Skip to content

Commit

Permalink
Merge tag 'afs-next-20190628' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/dhowells/linux-fs

Pull afs updates from David Howells:
 "A set of minor changes for AFS:

   - Remove an unnecessary check in afs_unlink()

   - Add a tracepoint for tracking callback management

   - Add a tracepoint for afs_server object usage

   - Use struct_size()

   - Add mappings for AFS UAE abort codes to Linux error codes, using
     symbolic names rather than hex numbers in the .c file"

* tag 'afs-next-20190628' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
  afs: Add support for the UAE error table
  fs/afs: use struct_size() in kzalloc()
  afs: Trace afs_server usage
  afs: Add some callback management tracepoints
  afs: afs_unlink() doesn't need to check dentry->d_inode
  • Loading branch information
torvalds committed Jul 11, 2019
2 parents 25cd6f3 + 1eda8ba commit 8dda995
Show file tree
Hide file tree
Showing 14 changed files with 369 additions and 82 deletions.
20 changes: 14 additions & 6 deletions fs/afs/callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static struct afs_cb_interest *afs_create_interest(struct afs_server *server,
refcount_set(&new->usage, 1);
new->sb = vnode->vfs_inode.i_sb;
new->vid = vnode->volume->vid;
new->server = afs_get_server(server);
new->server = afs_get_server(server, afs_server_trace_get_new_cbi);
INIT_HLIST_NODE(&new->cb_vlink);

write_lock(&server->cb_break_lock);
Expand Down Expand Up @@ -195,7 +195,7 @@ void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi)
write_unlock(&cbi->server->cb_break_lock);
if (vi)
kfree_rcu(vi, rcu);
afs_put_server(net, cbi->server);
afs_put_server(net, cbi->server, afs_server_trace_put_cbi);
}
kfree_rcu(cbi, rcu);
}
Expand All @@ -212,7 +212,7 @@ void afs_init_callback_state(struct afs_server *server)
/*
* actually break a callback
*/
void __afs_break_callback(struct afs_vnode *vnode)
void __afs_break_callback(struct afs_vnode *vnode, enum afs_cb_break_reason reason)
{
_enter("");

Expand All @@ -223,13 +223,17 @@ void __afs_break_callback(struct afs_vnode *vnode)

if (vnode->lock_state == AFS_VNODE_LOCK_WAITING_FOR_CB)
afs_lock_may_be_available(vnode);

trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, true);
} else {
trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, false);
}
}

void afs_break_callback(struct afs_vnode *vnode)
void afs_break_callback(struct afs_vnode *vnode, enum afs_cb_break_reason reason)
{
write_seqlock(&vnode->cb_lock);
__afs_break_callback(vnode);
__afs_break_callback(vnode, reason);
write_sequnlock(&vnode->cb_lock);
}

Expand Down Expand Up @@ -277,6 +281,8 @@ static void afs_break_one_callback(struct afs_server *server,

write_lock(&volume->cb_v_break_lock);
volume->cb_v_break++;
trace_afs_cb_break(fid, volume->cb_v_break,
afs_cb_break_for_volume_callback, false);
write_unlock(&volume->cb_v_break_lock);
} else {
data.volume = NULL;
Expand All @@ -285,8 +291,10 @@ static void afs_break_one_callback(struct afs_server *server,
afs_iget5_test, &data);
if (inode) {
vnode = AFS_FS_I(inode);
afs_break_callback(vnode);
afs_break_callback(vnode, afs_cb_break_for_callback);
iput(inode);
} else {
trace_afs_cb_miss(fid, afs_cb_break_for_callback);
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion fs/afs/cmservice.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,11 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
* server holds up change visibility till it receives our reply so as
* to maintain cache coherency.
*/
if (call->server)
if (call->server) {
trace_afs_server(call->server, atomic_read(&call->server->usage),
afs_server_trace_callback);
afs_break_callbacks(call->server, call->count, call->request);
}

afs_send_empty_reply(call);
afs_put_call(call);
Expand Down
21 changes: 9 additions & 12 deletions fs/afs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,7 @@ static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
if (nr_inline > (PAGE_SIZE - sizeof(*req)) / sizeof(struct page *))
nr_inline = 0;

req = kzalloc(sizeof(*req) + sizeof(struct page *) * nr_inline,
GFP_KERNEL);
req = kzalloc(struct_size(req, array, nr_inline), GFP_KERNEL);
if (!req)
return ERR_PTR(-ENOMEM);

Expand Down Expand Up @@ -1363,12 +1362,12 @@ static int afs_dir_remove_link(struct afs_vnode *dvnode, struct dentry *dentry,
drop_nlink(&vnode->vfs_inode);
if (vnode->vfs_inode.i_nlink == 0) {
set_bit(AFS_VNODE_DELETED, &vnode->flags);
__afs_break_callback(vnode);
__afs_break_callback(vnode, afs_cb_break_for_unlink);
}
write_sequnlock(&vnode->cb_lock);
ret = 0;
} else {
afs_break_callback(vnode);
afs_break_callback(vnode, afs_cb_break_for_unlink);

if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
kdebug("AFS_VNODE_DELETED");
Expand All @@ -1390,7 +1389,8 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
{
struct afs_fs_cursor fc;
struct afs_status_cb *scb;
struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL;
struct afs_vnode *dvnode = AFS_FS_I(dir);
struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
struct key *key;
bool need_rehash = false;
int ret;
Expand All @@ -1413,15 +1413,12 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
}

/* Try to make sure we have a callback promise on the victim. */
if (d_really_is_positive(dentry)) {
vnode = AFS_FS_I(d_inode(dentry));
ret = afs_validate(vnode, key);
if (ret < 0)
goto error_key;
}
ret = afs_validate(vnode, key);
if (ret < 0)
goto error_key;

spin_lock(&dentry->d_lock);
if (vnode && d_count(dentry) > 1) {
if (d_count(dentry) > 1) {
spin_unlock(&dentry->d_lock);
/* Start asynchronous writeout of the inode */
write_inode_now(d_inode(dentry), 0);
Expand Down
6 changes: 2 additions & 4 deletions fs/afs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,7 @@ int afs_page_filler(void *data, struct page *page)
/* fall through */
default:
go_on:
req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *),
GFP_KERNEL);
req = kzalloc(struct_size(req, array, 1), GFP_KERNEL);
if (!req)
goto enomem;

Expand Down Expand Up @@ -461,8 +460,7 @@ static int afs_readpages_one(struct file *file, struct address_space *mapping,
n++;
}

req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *) * n,
GFP_NOFS);
req = kzalloc(struct_size(req, array, n), GFP_NOFS);
if (!req)
return -ENOMEM;

Expand Down
2 changes: 1 addition & 1 deletion fs/afs/fsclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -1911,7 +1911,7 @@ struct afs_call *afs_fs_get_capabilities(struct afs_net *net,
return ERR_PTR(-ENOMEM);

call->key = key;
call->server = afs_get_server(server);
call->server = afs_get_server(server, afs_server_trace_get_caps);
call->server_index = server_index;
call->upgrade = true;
call->async = true;
Expand Down
17 changes: 10 additions & 7 deletions fs/afs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ void afs_vnode_commit_status(struct afs_fs_cursor *fc,
if (scb->status.abort_code == VNOVNODE) {
set_bit(AFS_VNODE_DELETED, &vnode->flags);
clear_nlink(&vnode->vfs_inode);
__afs_break_callback(vnode);
__afs_break_callback(vnode, afs_cb_break_for_deleted);
}
} else {
if (scb->have_status)
Expand Down Expand Up @@ -594,8 +594,9 @@ bool afs_check_validity(struct afs_vnode *vnode)
struct afs_cb_interest *cbi;
struct afs_server *server;
struct afs_volume *volume = vnode->volume;
enum afs_cb_break_reason need_clear = afs_cb_break_no_break;
time64_t now = ktime_get_real_seconds();
bool valid, need_clear = false;
bool valid;
unsigned int cb_break, cb_s_break, cb_v_break;
int seq = 0;

Expand All @@ -613,13 +614,13 @@ bool afs_check_validity(struct afs_vnode *vnode)
vnode->cb_v_break != cb_v_break) {
vnode->cb_s_break = cb_s_break;
vnode->cb_v_break = cb_v_break;
need_clear = true;
need_clear = afs_cb_break_for_vsbreak;
valid = false;
} else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
need_clear = true;
need_clear = afs_cb_break_for_zap;
valid = false;
} else if (vnode->cb_expires_at - 10 <= now) {
need_clear = true;
need_clear = afs_cb_break_for_lapsed;
valid = false;
} else {
valid = true;
Expand All @@ -635,10 +636,12 @@ bool afs_check_validity(struct afs_vnode *vnode)

done_seqretry(&vnode->cb_lock, seq);

if (need_clear) {
if (need_clear != afs_cb_break_no_break) {
write_seqlock(&vnode->cb_lock);
if (cb_break == vnode->cb_break)
__afs_break_callback(vnode);
__afs_break_callback(vnode, need_clear);
else
trace_afs_cb_miss(&vnode->fid, need_clear);
write_sequnlock(&vnode->cb_lock);
valid = false;
}
Expand Down
18 changes: 7 additions & 11 deletions fs/afs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ struct afs_server {
atomic_t usage;
u32 addr_version; /* Address list version */
u32 cm_epoch; /* Server RxRPC epoch */
unsigned int debug_id; /* Debugging ID for traces */

/* file service access */
rwlock_t fs_lock; /* access lock */
Expand Down Expand Up @@ -844,9 +845,9 @@ extern struct fscache_cookie_def afs_vnode_cache_index_def;
* callback.c
*/
extern void afs_init_callback_state(struct afs_server *);
extern void __afs_break_callback(struct afs_vnode *);
extern void afs_break_callback(struct afs_vnode *);
extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*);
extern void __afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason);
extern void afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason);
extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break *);

extern int afs_register_server_cb_interest(struct afs_vnode *,
struct afs_server_list *, unsigned int);
Expand Down Expand Up @@ -1240,17 +1241,12 @@ extern void __exit afs_clean_up_permit_cache(void);
*/
extern spinlock_t afs_server_peer_lock;

static inline struct afs_server *afs_get_server(struct afs_server *server)
{
atomic_inc(&server->usage);
return server;
}

extern struct afs_server *afs_find_server(struct afs_net *,
const struct sockaddr_rxrpc *);
extern struct afs_server *afs_find_server_by_uuid(struct afs_net *, const uuid_t *);
extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *);
extern void afs_put_server(struct afs_net *, struct afs_server *);
extern struct afs_server *afs_get_server(struct afs_server *, enum afs_server_trace);
extern void afs_put_server(struct afs_net *, struct afs_server *, enum afs_server_trace);
extern void afs_manage_servers(struct work_struct *);
extern void afs_servers_timer(struct timer_list *);
extern void __net_exit afs_purge_servers(struct afs_net *);
Expand Down Expand Up @@ -1434,7 +1430,7 @@ static inline void afs_check_for_remote_deletion(struct afs_fs_cursor *fc,
{
if (fc->ac.error == -ENOENT) {
set_bit(AFS_VNODE_DELETED, &vnode->flags);
afs_break_callback(vnode);
afs_break_callback(vnode, afs_cb_break_for_deleted);
}
}

Expand Down
48 changes: 20 additions & 28 deletions fs/afs/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/errno.h>
#include "internal.h"
#include "afs_fs.h"
#include "protocol_uae.h"

/*
* convert an AFS abort code to a Linux error number
Expand Down Expand Up @@ -65,34 +66,25 @@ int afs_abort_to_error(u32 abort_code)
case AFSVL_PERM: return -EACCES;
case AFSVL_NOMEM: return -EREMOTEIO;

/* Unified AFS error table; ET "uae" == 0x2f6df00 */
case 0x2f6df00: return -EPERM;
case 0x2f6df01: return -ENOENT;
case 0x2f6df04: return -EIO;
case 0x2f6df0a: return -EAGAIN;
case 0x2f6df0b: return -ENOMEM;
case 0x2f6df0c: return -EACCES;
case 0x2f6df0f: return -EBUSY;
case 0x2f6df10: return -EEXIST;
case 0x2f6df11: return -EXDEV;
case 0x2f6df12: return -ENODEV;
case 0x2f6df13: return -ENOTDIR;
case 0x2f6df14: return -EISDIR;
case 0x2f6df15: return -EINVAL;
case 0x2f6df1a: return -EFBIG;
case 0x2f6df1b: return -ENOSPC;
case 0x2f6df1d: return -EROFS;
case 0x2f6df1e: return -EMLINK;
case 0x2f6df20: return -EDOM;
case 0x2f6df21: return -ERANGE;
case 0x2f6df22: return -EDEADLK;
case 0x2f6df23: return -ENAMETOOLONG;
case 0x2f6df24: return -ENOLCK;
case 0x2f6df26: return -ENOTEMPTY;
case 0x2f6df28: return -EWOULDBLOCK;
case 0x2f6df69: return -ENOTCONN;
case 0x2f6df6c: return -ETIMEDOUT;
case 0x2f6df78: return -EDQUOT;
/* Unified AFS error table */
case UAEPERM: return -EPERM;
case UAENOENT: return -ENOENT;
case UAEACCES: return -EACCES;
case UAEBUSY: return -EBUSY;
case UAEEXIST: return -EEXIST;
case UAENOTDIR: return -ENOTDIR;
case UAEISDIR: return -EISDIR;
case UAEFBIG: return -EFBIG;
case UAENOSPC: return -ENOSPC;
case UAEROFS: return -EROFS;
case UAEMLINK: return -EMLINK;
case UAEDEADLK: return -EDEADLK;
case UAENAMETOOLONG: return -ENAMETOOLONG;
case UAENOLCK: return -ENOLCK;
case UAENOTEMPTY: return -ENOTEMPTY;
case UAELOOP: return -ELOOP;
case UAENOMEDIUM: return -ENOMEDIUM;
case UAEDQUOT: return -EDQUOT;

/* RXKAD abort codes; from include/rxrpc/packet.h. ET "RXK" == 0x1260B00 */
case RXKADINCONSISTENCY: return -EPROTO;
Expand Down
Loading

0 comments on commit 8dda995

Please sign in to comment.