AFS development
-----BEGIN PGP SIGNATURE----- iQIVAwUAXRyW8vu3V2unywtrAQIhsw//cVtxLx4ZCox5Z/93cdqych8RoCrwcUEG Cli0NAjlp/0HETvCsIqdkPKf+4OYCW1tHB2KTdbFdQLZptLgoEhykx89k70z9ggb ViieEa1GvAKhdamVqkPUC+3Q33uzyRaK7Gi5N3phJoaO+o328SlrPG0LerQgY0Np Rf3je56A1gIjEgWTmpStxiY262jlgaR3IuvpOqbu2G0TQVWV8CsBKw61fTdmEEQp dIkNO/xFXS+PvPdmQe5zCAjD/W2D+ggeBMbBwHF411qA60plGinubBYKZ98ikliZ OnQQPExI7mroIMzpYT+rzEQyxui2nz5t+Hj+d6t7iIvitNcX/Q53sVTq3RfQ0FjG QCd+j/l2p7fkXK4Sxgb/UBkj/pRr6W+FYSbQ/tmpD8UypEf5B3ln6GuA6yTMuNRF wVb744slKWq0c7KUuXmz806B2qJoyFG206jyFnoByvs6cPmB1+JqhBBYOKHcwjbo HIK+oUKkEfE6ofjQ3B9xOQ1anfbRnjjfJCmXvns9v57y/nRP2P78HUJNnEsOolk2 nc3Ep41OgeZdwkts9KnSjmwy6VF3UZ2NQEiWXsUIOxGMtcodw9ci1bpquJ71oyut 4sFMJvMU4eJD+XuCOlAgpbTaQ0Wuf11kFpl1Cof4fj0Z09C25Ahj6iKEKnumtO+4 edfNLlwO6oo= =wgib -----END PGP SIGNATURE----- Merge tag 'afs-next-20190628' of git://git.kernel.org/pub/scm/linux/kernel/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
This commit is contained in:
commit
8dda9957e3
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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("");
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
21
fs/afs/dir.c
21
fs/afs/dir.c
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -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;
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Universal AFS Error codes (UAE).
|
||||
*
|
||||
* Copyright (C) 2003, Daria Phoebe Brashear
|
||||
* Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
enum {
|
||||
UAEPERM = 0x2f6df00, /* Operation not permitted */
|
||||
UAENOENT = 0x2f6df01, /* No such file or directory */
|
||||
UAESRCH = 0x2f6df02, /* No such process */
|
||||
UAEINTR = 0x2f6df03, /* Interrupted system call */
|
||||
UAEIO = 0x2f6df04, /* I/O error */
|
||||
UAENXIO = 0x2f6df05, /* No such device or address */
|
||||
UAE2BIG = 0x2f6df06, /* Arg list too long */
|
||||
UAENOEXEC = 0x2f6df07, /* Exec format error */
|
||||
UAEBADF = 0x2f6df08, /* Bad file number */
|
||||
UAECHILD = 0x2f6df09, /* No child processes */
|
||||
UAEAGAIN = 0x2f6df0a, /* Try again */
|
||||
UAENOMEM = 0x2f6df0b, /* Out of memory */
|
||||
UAEACCES = 0x2f6df0c, /* Permission denied */
|
||||
UAEFAULT = 0x2f6df0d, /* Bad address */
|
||||
UAENOTBLK = 0x2f6df0e, /* Block device required */
|
||||
UAEBUSY = 0x2f6df0f, /* Device or resource busy */
|
||||
UAEEXIST = 0x2f6df10, /* File exists */
|
||||
UAEXDEV = 0x2f6df11, /* Cross-device link */
|
||||
UAENODEV = 0x2f6df12, /* No such device */
|
||||
UAENOTDIR = 0x2f6df13, /* Not a directory */
|
||||
UAEISDIR = 0x2f6df14, /* Is a directory */
|
||||
UAEINVAL = 0x2f6df15, /* Invalid argument */
|
||||
UAENFILE = 0x2f6df16, /* File table overflow */
|
||||
UAEMFILE = 0x2f6df17, /* Too many open files */
|
||||
UAENOTTY = 0x2f6df18, /* Not a typewriter */
|
||||
UAETXTBSY = 0x2f6df19, /* Text file busy */
|
||||
UAEFBIG = 0x2f6df1a, /* File too large */
|
||||
UAENOSPC = 0x2f6df1b, /* No space left on device */
|
||||
UAESPIPE = 0x2f6df1c, /* Illegal seek */
|
||||
UAEROFS = 0x2f6df1d, /* Read-only file system */
|
||||
UAEMLINK = 0x2f6df1e, /* Too many links */
|
||||
UAEPIPE = 0x2f6df1f, /* Broken pipe */
|
||||
UAEDOM = 0x2f6df20, /* Math argument out of domain of func */
|
||||
UAERANGE = 0x2f6df21, /* Math result not representable */
|
||||
UAEDEADLK = 0x2f6df22, /* Resource deadlock would occur */
|
||||
UAENAMETOOLONG = 0x2f6df23, /* File name too long */
|
||||
UAENOLCK = 0x2f6df24, /* No record locks available */
|
||||
UAENOSYS = 0x2f6df25, /* Function not implemented */
|
||||
UAENOTEMPTY = 0x2f6df26, /* Directory not empty */
|
||||
UAELOOP = 0x2f6df27, /* Too many symbolic links encountered */
|
||||
UAEWOULDBLOCK = 0x2f6df28, /* Operation would block */
|
||||
UAENOMSG = 0x2f6df29, /* No message of desired type */
|
||||
UAEIDRM = 0x2f6df2a, /* Identifier removed */
|
||||
UAECHRNG = 0x2f6df2b, /* Channel number out of range */
|
||||
UAEL2NSYNC = 0x2f6df2c, /* Level 2 not synchronized */
|
||||
UAEL3HLT = 0x2f6df2d, /* Level 3 halted */
|
||||
UAEL3RST = 0x2f6df2e, /* Level 3 reset */
|
||||
UAELNRNG = 0x2f6df2f, /* Link number out of range */
|
||||
UAEUNATCH = 0x2f6df30, /* Protocol driver not attached */
|
||||
UAENOCSI = 0x2f6df31, /* No CSI structure available */
|
||||
UAEL2HLT = 0x2f6df32, /* Level 2 halted */
|
||||
UAEBADE = 0x2f6df33, /* Invalid exchange */
|
||||
UAEBADR = 0x2f6df34, /* Invalid request descriptor */
|
||||
UAEXFULL = 0x2f6df35, /* Exchange full */
|
||||
UAENOANO = 0x2f6df36, /* No anode */
|
||||
UAEBADRQC = 0x2f6df37, /* Invalid request code */
|
||||
UAEBADSLT = 0x2f6df38, /* Invalid slot */
|
||||
UAEBFONT = 0x2f6df39, /* Bad font file format */
|
||||
UAENOSTR = 0x2f6df3a, /* Device not a stream */
|
||||
UAENODATA = 0x2f6df3b, /* No data available */
|
||||
UAETIME = 0x2f6df3c, /* Timer expired */
|
||||
UAENOSR = 0x2f6df3d, /* Out of streams resources */
|
||||
UAENONET = 0x2f6df3e, /* Machine is not on the network */
|
||||
UAENOPKG = 0x2f6df3f, /* Package not installed */
|
||||
UAEREMOTE = 0x2f6df40, /* Object is remote */
|
||||
UAENOLINK = 0x2f6df41, /* Link has been severed */
|
||||
UAEADV = 0x2f6df42, /* Advertise error */
|
||||
UAESRMNT = 0x2f6df43, /* Srmount error */
|
||||
UAECOMM = 0x2f6df44, /* Communication error on send */
|
||||
UAEPROTO = 0x2f6df45, /* Protocol error */
|
||||
UAEMULTIHOP = 0x2f6df46, /* Multihop attempted */
|
||||
UAEDOTDOT = 0x2f6df47, /* RFS specific error */
|
||||
UAEBADMSG = 0x2f6df48, /* Not a data message */
|
||||
UAEOVERFLOW = 0x2f6df49, /* Value too large for defined data type */
|
||||
UAENOTUNIQ = 0x2f6df4a, /* Name not unique on network */
|
||||
UAEBADFD = 0x2f6df4b, /* File descriptor in bad state */
|
||||
UAEREMCHG = 0x2f6df4c, /* Remote address changed */
|
||||
UAELIBACC = 0x2f6df4d, /* Can not access a needed shared library */
|
||||
UAELIBBAD = 0x2f6df4e, /* Accessing a corrupted shared library */
|
||||
UAELIBSCN = 0x2f6df4f, /* .lib section in a.out corrupted */
|
||||
UAELIBMAX = 0x2f6df50, /* Attempting to link in too many shared libraries */
|
||||
UAELIBEXEC = 0x2f6df51, /* Cannot exec a shared library directly */
|
||||
UAEILSEQ = 0x2f6df52, /* Illegal byte sequence */
|
||||
UAERESTART = 0x2f6df53, /* Interrupted system call should be restarted */
|
||||
UAESTRPIPE = 0x2f6df54, /* Streams pipe error */
|
||||
UAEUSERS = 0x2f6df55, /* Too many users */
|
||||
UAENOTSOCK = 0x2f6df56, /* Socket operation on non-socket */
|
||||
UAEDESTADDRREQ = 0x2f6df57, /* Destination address required */
|
||||
UAEMSGSIZE = 0x2f6df58, /* Message too long */
|
||||
UAEPROTOTYPE = 0x2f6df59, /* Protocol wrong type for socket */
|
||||
UAENOPROTOOPT = 0x2f6df5a, /* Protocol not available */
|
||||
UAEPROTONOSUPPORT = 0x2f6df5b, /* Protocol not supported */
|
||||
UAESOCKTNOSUPPORT = 0x2f6df5c, /* Socket type not supported */
|
||||
UAEOPNOTSUPP = 0x2f6df5d, /* Operation not supported on transport endpoint */
|
||||
UAEPFNOSUPPORT = 0x2f6df5e, /* Protocol family not supported */
|
||||
UAEAFNOSUPPORT = 0x2f6df5f, /* Address family not supported by protocol */
|
||||
UAEADDRINUSE = 0x2f6df60, /* Address already in use */
|
||||
UAEADDRNOTAVAIL = 0x2f6df61, /* Cannot assign requested address */
|
||||
UAENETDOWN = 0x2f6df62, /* Network is down */
|
||||
UAENETUNREACH = 0x2f6df63, /* Network is unreachable */
|
||||
UAENETRESET = 0x2f6df64, /* Network dropped connection because of reset */
|
||||
UAECONNABORTED = 0x2f6df65, /* Software caused connection abort */
|
||||
UAECONNRESET = 0x2f6df66, /* Connection reset by peer */
|
||||
UAENOBUFS = 0x2f6df67, /* No buffer space available */
|
||||
UAEISCONN = 0x2f6df68, /* Transport endpoint is already connected */
|
||||
UAENOTCONN = 0x2f6df69, /* Transport endpoint is not connected */
|
||||
UAESHUTDOWN = 0x2f6df6a, /* Cannot send after transport endpoint shutdown */
|
||||
UAETOOMANYREFS = 0x2f6df6b, /* Too many references: cannot splice */
|
||||
UAETIMEDOUT = 0x2f6df6c, /* Connection timed out */
|
||||
UAECONNREFUSED = 0x2f6df6d, /* Connection refused */
|
||||
UAEHOSTDOWN = 0x2f6df6e, /* Host is down */
|
||||
UAEHOSTUNREACH = 0x2f6df6f, /* No route to host */
|
||||
UAEALREADY = 0x2f6df70, /* Operation already in progress */
|
||||
UAEINPROGRESS = 0x2f6df71, /* Operation now in progress */
|
||||
UAESTALE = 0x2f6df72, /* Stale NFS file handle */
|
||||
UAEUCLEAN = 0x2f6df73, /* Structure needs cleaning */
|
||||
UAENOTNAM = 0x2f6df74, /* Not a XENIX named type file */
|
||||
UAENAVAIL = 0x2f6df75, /* No XENIX semaphores available */
|
||||
UAEISNAM = 0x2f6df76, /* Is a named type file */
|
||||
UAEREMOTEIO = 0x2f6df77, /* Remote I/O error */
|
||||
UAEDQUOT = 0x2f6df78, /* Quota exceeded */
|
||||
UAENOMEDIUM = 0x2f6df79, /* No medium found */
|
||||
UAEMEDIUMTYPE = 0x2f6df7a, /* Wrong medium type */
|
||||
};
|
|
@ -184,7 +184,7 @@ void afs_put_call(struct afs_call *call)
|
|||
if (call->type->destructor)
|
||||
call->type->destructor(call);
|
||||
|
||||
afs_put_server(call->net, call->server);
|
||||
afs_put_server(call->net, call->server, afs_server_trace_put_call);
|
||||
afs_put_cb_interest(call->net, call->cbi);
|
||||
afs_put_addrlist(call->alist);
|
||||
kfree(call->request);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
static unsigned afs_server_gc_delay = 10; /* Server record timeout in seconds */
|
||||
static unsigned afs_server_update_delay = 30; /* Time till VLDB recheck in secs */
|
||||
static atomic_t afs_server_debug_id;
|
||||
|
||||
static void afs_inc_servers_outstanding(struct afs_net *net)
|
||||
{
|
||||
|
@ -47,7 +48,7 @@ struct afs_server *afs_find_server(struct afs_net *net,
|
|||
|
||||
do {
|
||||
if (server)
|
||||
afs_put_server(net, server);
|
||||
afs_put_server(net, server, afs_server_trace_put_find_rsq);
|
||||
server = NULL;
|
||||
read_seqbegin_or_lock(&net->fs_addr_lock, &seq);
|
||||
|
||||
|
@ -112,7 +113,7 @@ struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uu
|
|||
* changes.
|
||||
*/
|
||||
if (server)
|
||||
afs_put_server(net, server);
|
||||
afs_put_server(net, server, afs_server_trace_put_uuid_rsq);
|
||||
server = NULL;
|
||||
|
||||
read_seqbegin_or_lock(&net->fs_lock, &seq);
|
||||
|
@ -127,7 +128,7 @@ struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uu
|
|||
} else if (diff > 0) {
|
||||
p = p->rb_right;
|
||||
} else {
|
||||
afs_get_server(server);
|
||||
afs_get_server(server, afs_server_trace_get_by_uuid);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -198,7 +199,7 @@ static struct afs_server *afs_install_server(struct afs_net *net,
|
|||
ret = 0;
|
||||
|
||||
exists:
|
||||
afs_get_server(server);
|
||||
afs_get_server(server, afs_server_trace_get_install);
|
||||
write_sequnlock(&net->fs_lock);
|
||||
return server;
|
||||
}
|
||||
|
@ -219,6 +220,7 @@ static struct afs_server *afs_alloc_server(struct afs_net *net,
|
|||
goto enomem;
|
||||
|
||||
atomic_set(&server->usage, 1);
|
||||
server->debug_id = atomic_inc_return(&afs_server_debug_id);
|
||||
RCU_INIT_POINTER(server->addresses, alist);
|
||||
server->addr_version = alist->version;
|
||||
server->uuid = *uuid;
|
||||
|
@ -230,6 +232,7 @@ static struct afs_server *afs_alloc_server(struct afs_net *net,
|
|||
spin_lock_init(&server->probe_lock);
|
||||
|
||||
afs_inc_servers_outstanding(net);
|
||||
trace_afs_server(server, 1, afs_server_trace_alloc);
|
||||
_leave(" = %p", server);
|
||||
return server;
|
||||
|
||||
|
@ -324,10 +327,23 @@ void afs_servers_timer(struct timer_list *timer)
|
|||
afs_dec_servers_outstanding(net);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a reference on a server object.
|
||||
*/
|
||||
struct afs_server *afs_get_server(struct afs_server *server,
|
||||
enum afs_server_trace reason)
|
||||
{
|
||||
unsigned int u = atomic_inc_return(&server->usage);
|
||||
|
||||
trace_afs_server(server, u, reason);
|
||||
return server;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release a reference on a server record.
|
||||
*/
|
||||
void afs_put_server(struct afs_net *net, struct afs_server *server)
|
||||
void afs_put_server(struct afs_net *net, struct afs_server *server,
|
||||
enum afs_server_trace reason)
|
||||
{
|
||||
unsigned int usage;
|
||||
|
||||
|
@ -338,7 +354,7 @@ void afs_put_server(struct afs_net *net, struct afs_server *server)
|
|||
|
||||
usage = atomic_dec_return(&server->usage);
|
||||
|
||||
_enter("{%u}", usage);
|
||||
trace_afs_server(server, usage, reason);
|
||||
|
||||
if (likely(usage > 0))
|
||||
return;
|
||||
|
@ -350,6 +366,8 @@ static void afs_server_rcu(struct rcu_head *rcu)
|
|||
{
|
||||
struct afs_server *server = container_of(rcu, struct afs_server, rcu);
|
||||
|
||||
trace_afs_server(server, atomic_read(&server->usage),
|
||||
afs_server_trace_free);
|
||||
afs_put_addrlist(rcu_access_pointer(server->addresses));
|
||||
kfree(server);
|
||||
}
|
||||
|
@ -365,7 +383,9 @@ static void afs_destroy_server(struct afs_net *net, struct afs_server *server)
|
|||
.index = alist->preferred,
|
||||
.error = 0,
|
||||
};
|
||||
_enter("%p", server);
|
||||
|
||||
trace_afs_server(server, atomic_read(&server->usage),
|
||||
afs_server_trace_give_up_cb);
|
||||
|
||||
if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags))
|
||||
afs_fs_give_up_all_callbacks(net, server, &ac, NULL);
|
||||
|
@ -373,6 +393,8 @@ static void afs_destroy_server(struct afs_net *net, struct afs_server *server)
|
|||
wait_var_event(&server->probe_outstanding,
|
||||
atomic_read(&server->probe_outstanding) == 0);
|
||||
|
||||
trace_afs_server(server, atomic_read(&server->usage),
|
||||
afs_server_trace_destroy);
|
||||
call_rcu(&server->rcu, afs_server_rcu);
|
||||
afs_dec_servers_outstanding(net);
|
||||
}
|
||||
|
@ -392,6 +414,7 @@ static void afs_gc_servers(struct afs_net *net, struct afs_server *gc_list)
|
|||
write_seqlock(&net->fs_lock);
|
||||
usage = 1;
|
||||
deleted = atomic_try_cmpxchg(&server->usage, &usage, 0);
|
||||
trace_afs_server(server, usage, afs_server_trace_gc);
|
||||
if (deleted) {
|
||||
rb_erase(&server->uuid_rb, &net->fs_servers);
|
||||
hlist_del_rcu(&server->proc_link);
|
||||
|
@ -514,6 +537,8 @@ static noinline bool afs_update_server_record(struct afs_fs_cursor *fc, struct a
|
|||
|
||||
_enter("");
|
||||
|
||||
trace_afs_server(server, atomic_read(&server->usage), afs_server_trace_update);
|
||||
|
||||
alist = afs_vl_lookup_addrs(fc->vnode->volume->cell, fc->key,
|
||||
&server->uuid);
|
||||
if (IS_ERR(alist)) {
|
||||
|
|
|
@ -16,7 +16,8 @@ void afs_put_serverlist(struct afs_net *net, struct afs_server_list *slist)
|
|||
if (slist && refcount_dec_and_test(&slist->usage)) {
|
||||
for (i = 0; i < slist->nr_servers; i++) {
|
||||
afs_put_cb_interest(net, slist->servers[i].cb_interest);
|
||||
afs_put_server(net, slist->servers[i].server);
|
||||
afs_put_server(net, slist->servers[i].server,
|
||||
afs_server_trace_put_slist);
|
||||
}
|
||||
kfree(slist);
|
||||
}
|
||||
|
@ -67,7 +68,8 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell,
|
|||
break;
|
||||
if (j < slist->nr_servers) {
|
||||
if (slist->servers[j].server == server) {
|
||||
afs_put_server(cell->net, server);
|
||||
afs_put_server(cell->net, server,
|
||||
afs_server_trace_put_slist_isort);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,8 +44,7 @@ static int afs_fill_page(struct afs_vnode *vnode, struct key *key,
|
|||
return 0;
|
||||
}
|
||||
|
||||
req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *),
|
||||
GFP_KERNEL);
|
||||
req = kzalloc(struct_size(req, array, 1), GFP_KERNEL);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -27,6 +27,26 @@ enum afs_call_trace {
|
|||
afs_call_trace_work,
|
||||
};
|
||||
|
||||
enum afs_server_trace {
|
||||
afs_server_trace_alloc,
|
||||
afs_server_trace_callback,
|
||||
afs_server_trace_destroy,
|
||||
afs_server_trace_free,
|
||||
afs_server_trace_gc,
|
||||
afs_server_trace_get_by_uuid,
|
||||
afs_server_trace_get_caps,
|
||||
afs_server_trace_get_install,
|
||||
afs_server_trace_get_new_cbi,
|
||||
afs_server_trace_give_up_cb,
|
||||
afs_server_trace_put_call,
|
||||
afs_server_trace_put_cbi,
|
||||
afs_server_trace_put_find_rsq,
|
||||
afs_server_trace_put_slist,
|
||||
afs_server_trace_put_slist_isort,
|
||||
afs_server_trace_put_uuid_rsq,
|
||||
afs_server_trace_update,
|
||||
};
|
||||
|
||||
enum afs_fs_operation {
|
||||
afs_FS_FetchData = 130, /* AFS Fetch file data */
|
||||
afs_FS_FetchACL = 131, /* AFS Fetch file ACL */
|
||||
|
@ -191,6 +211,17 @@ enum afs_flock_operation {
|
|||
afs_flock_op_wake,
|
||||
};
|
||||
|
||||
enum afs_cb_break_reason {
|
||||
afs_cb_break_no_break,
|
||||
afs_cb_break_for_callback,
|
||||
afs_cb_break_for_deleted,
|
||||
afs_cb_break_for_lapsed,
|
||||
afs_cb_break_for_unlink,
|
||||
afs_cb_break_for_vsbreak,
|
||||
afs_cb_break_for_volume_callback,
|
||||
afs_cb_break_for_zap,
|
||||
};
|
||||
|
||||
#endif /* end __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY */
|
||||
|
||||
/*
|
||||
|
@ -204,6 +235,25 @@ enum afs_flock_operation {
|
|||
EM(afs_call_trace_wake, "WAKE ") \
|
||||
E_(afs_call_trace_work, "WORK ")
|
||||
|
||||
#define afs_server_traces \
|
||||
EM(afs_server_trace_alloc, "ALLOC ") \
|
||||
EM(afs_server_trace_callback, "CALLBACK ") \
|
||||
EM(afs_server_trace_destroy, "DESTROY ") \
|
||||
EM(afs_server_trace_free, "FREE ") \
|
||||
EM(afs_server_trace_gc, "GC ") \
|
||||
EM(afs_server_trace_get_by_uuid, "GET uuid ") \
|
||||
EM(afs_server_trace_get_caps, "GET caps ") \
|
||||
EM(afs_server_trace_get_install, "GET inst ") \
|
||||
EM(afs_server_trace_get_new_cbi, "GET cbi ") \
|
||||
EM(afs_server_trace_give_up_cb, "giveup-cb") \
|
||||
EM(afs_server_trace_put_call, "PUT call ") \
|
||||
EM(afs_server_trace_put_cbi, "PUT cbi ") \
|
||||
EM(afs_server_trace_put_find_rsq, "PUT f-rsq") \
|
||||
EM(afs_server_trace_put_slist, "PUT slist") \
|
||||
EM(afs_server_trace_put_slist_isort, "PUT isort") \
|
||||
EM(afs_server_trace_put_uuid_rsq, "PUT u-req") \
|
||||
E_(afs_server_trace_update, "UPDATE")
|
||||
|
||||
#define afs_fs_operations \
|
||||
EM(afs_FS_FetchData, "FS.FetchData") \
|
||||
EM(afs_FS_FetchStatus, "FS.FetchStatus") \
|
||||
|
@ -370,6 +420,16 @@ enum afs_flock_operation {
|
|||
EM(afs_flock_op_unlock, "UNLOCK ") \
|
||||
E_(afs_flock_op_wake, "WAKE ")
|
||||
|
||||
#define afs_cb_break_reasons \
|
||||
EM(afs_cb_break_no_break, "no-break") \
|
||||
EM(afs_cb_break_for_callback, "break-cb") \
|
||||
EM(afs_cb_break_for_deleted, "break-del") \
|
||||
EM(afs_cb_break_for_lapsed, "break-lapsed") \
|
||||
EM(afs_cb_break_for_unlink, "break-unlink") \
|
||||
EM(afs_cb_break_for_vsbreak, "break-vs") \
|
||||
EM(afs_cb_break_for_volume_callback, "break-v-cb") \
|
||||
E_(afs_cb_break_for_zap, "break-zap")
|
||||
|
||||
/*
|
||||
* Export enum symbols via userspace.
|
||||
*/
|
||||
|
@ -379,6 +439,7 @@ enum afs_flock_operation {
|
|||
#define E_(a, b) TRACE_DEFINE_ENUM(a);
|
||||
|
||||
afs_call_traces;
|
||||
afs_server_traces;
|
||||
afs_fs_operations;
|
||||
afs_vl_operations;
|
||||
afs_edit_dir_ops;
|
||||
|
@ -388,6 +449,7 @@ afs_io_errors;
|
|||
afs_file_errors;
|
||||
afs_flock_types;
|
||||
afs_flock_operations;
|
||||
afs_cb_break_reasons;
|
||||
|
||||
/*
|
||||
* Now redefine the EM() and E_() macros to map the enums to the strings that
|
||||
|
@ -1167,6 +1229,76 @@ TRACE_EVENT(afs_get_tree,
|
|||
__entry->cell, __entry->volume, __entry->vid)
|
||||
);
|
||||
|
||||
TRACE_EVENT(afs_cb_break,
|
||||
TP_PROTO(struct afs_fid *fid, unsigned int cb_break,
|
||||
enum afs_cb_break_reason reason, bool skipped),
|
||||
|
||||
TP_ARGS(fid, cb_break, reason, skipped),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field_struct(struct afs_fid, fid )
|
||||
__field(unsigned int, cb_break )
|
||||
__field(enum afs_cb_break_reason, reason )
|
||||
__field(bool, skipped )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->fid = *fid;
|
||||
__entry->cb_break = cb_break;
|
||||
__entry->reason = reason;
|
||||
__entry->skipped = skipped;
|
||||
),
|
||||
|
||||
TP_printk("%llx:%llx:%x b=%x s=%u %s",
|
||||
__entry->fid.vid, __entry->fid.vnode, __entry->fid.unique,
|
||||
__entry->cb_break,
|
||||
__entry->skipped,
|
||||
__print_symbolic(__entry->reason, afs_cb_break_reasons))
|
||||
);
|
||||
|
||||
TRACE_EVENT(afs_cb_miss,
|
||||
TP_PROTO(struct afs_fid *fid, enum afs_cb_break_reason reason),
|
||||
|
||||
TP_ARGS(fid, reason),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field_struct(struct afs_fid, fid )
|
||||
__field(enum afs_cb_break_reason, reason )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->fid = *fid;
|
||||
__entry->reason = reason;
|
||||
),
|
||||
|
||||
TP_printk(" %llx:%llx:%x %s",
|
||||
__entry->fid.vid, __entry->fid.vnode, __entry->fid.unique,
|
||||
__print_symbolic(__entry->reason, afs_cb_break_reasons))
|
||||
);
|
||||
|
||||
TRACE_EVENT(afs_server,
|
||||
TP_PROTO(struct afs_server *server, int usage, enum afs_server_trace reason),
|
||||
|
||||
TP_ARGS(server, usage, reason),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, server )
|
||||
__field(int, usage )
|
||||
__field(int, reason )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->server = server->debug_id;
|
||||
__entry->usage = usage;
|
||||
__entry->reason = reason;
|
||||
),
|
||||
|
||||
TP_printk("s=%08x %s u=%d",
|
||||
__entry->server,
|
||||
__print_symbolic(__entry->reason, afs_server_traces),
|
||||
__entry->usage)
|
||||
);
|
||||
|
||||
#endif /* _TRACE_AFS_H */
|
||||
|
||||
/* This part must be outside protection */
|
||||
|
|
Loading…
Reference in New Issue