diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-10 23:55:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-10 23:55:33 -0400 |
commit | 8dda9957e3a1c871dfbabf84c4760f9b26032442 (patch) | |
tree | f627992d3b0638ab7541d25d60611b2ab3e18f18 | |
parent | 25cd6f355dab9d11b7c8a4005867d5a30b8b14ee (diff) | |
parent | 1eda8bab70ca7d353b4e865140eaec06fedbf871 (diff) |
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
-rw-r--r-- | fs/afs/callback.c | 20 | ||||
-rw-r--r-- | fs/afs/cmservice.c | 5 | ||||
-rw-r--r-- | fs/afs/dir.c | 21 | ||||
-rw-r--r-- | fs/afs/file.c | 6 | ||||
-rw-r--r-- | fs/afs/fsclient.c | 2 | ||||
-rw-r--r-- | fs/afs/inode.c | 17 | ||||
-rw-r--r-- | fs/afs/internal.h | 18 | ||||
-rw-r--r-- | fs/afs/misc.c | 48 | ||||
-rw-r--r-- | fs/afs/protocol_uae.h | 132 | ||||
-rw-r--r-- | fs/afs/rxrpc.c | 2 | ||||
-rw-r--r-- | fs/afs/server.c | 39 | ||||
-rw-r--r-- | fs/afs/server_list.c | 6 | ||||
-rw-r--r-- | fs/afs/write.c | 3 | ||||
-rw-r--r-- | include/trace/events/afs.h | 132 |
14 files changed, 369 insertions, 82 deletions
diff --git a/fs/afs/callback.c b/fs/afs/callback.c index 915010464572..6cdd7047c809 100644 --- a/fs/afs/callback.c +++ b/fs/afs/callback.c | |||
@@ -48,7 +48,7 @@ static struct afs_cb_interest *afs_create_interest(struct afs_server *server, | |||
48 | refcount_set(&new->usage, 1); | 48 | refcount_set(&new->usage, 1); |
49 | new->sb = vnode->vfs_inode.i_sb; | 49 | new->sb = vnode->vfs_inode.i_sb; |
50 | new->vid = vnode->volume->vid; | 50 | new->vid = vnode->volume->vid; |
51 | new->server = afs_get_server(server); | 51 | new->server = afs_get_server(server, afs_server_trace_get_new_cbi); |
52 | INIT_HLIST_NODE(&new->cb_vlink); | 52 | INIT_HLIST_NODE(&new->cb_vlink); |
53 | 53 | ||
54 | write_lock(&server->cb_break_lock); | 54 | write_lock(&server->cb_break_lock); |
@@ -195,7 +195,7 @@ void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi) | |||
195 | write_unlock(&cbi->server->cb_break_lock); | 195 | write_unlock(&cbi->server->cb_break_lock); |
196 | if (vi) | 196 | if (vi) |
197 | kfree_rcu(vi, rcu); | 197 | kfree_rcu(vi, rcu); |
198 | afs_put_server(net, cbi->server); | 198 | afs_put_server(net, cbi->server, afs_server_trace_put_cbi); |
199 | } | 199 | } |
200 | kfree_rcu(cbi, rcu); | 200 | kfree_rcu(cbi, rcu); |
201 | } | 201 | } |
@@ -212,7 +212,7 @@ void afs_init_callback_state(struct afs_server *server) | |||
212 | /* | 212 | /* |
213 | * actually break a callback | 213 | * actually break a callback |
214 | */ | 214 | */ |
215 | void __afs_break_callback(struct afs_vnode *vnode) | 215 | void __afs_break_callback(struct afs_vnode *vnode, enum afs_cb_break_reason reason) |
216 | { | 216 | { |
217 | _enter(""); | 217 | _enter(""); |
218 | 218 | ||
@@ -223,13 +223,17 @@ void __afs_break_callback(struct afs_vnode *vnode) | |||
223 | 223 | ||
224 | if (vnode->lock_state == AFS_VNODE_LOCK_WAITING_FOR_CB) | 224 | if (vnode->lock_state == AFS_VNODE_LOCK_WAITING_FOR_CB) |
225 | afs_lock_may_be_available(vnode); | 225 | afs_lock_may_be_available(vnode); |
226 | |||
227 | trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, true); | ||
228 | } else { | ||
229 | trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, false); | ||
226 | } | 230 | } |
227 | } | 231 | } |
228 | 232 | ||
229 | void afs_break_callback(struct afs_vnode *vnode) | 233 | void afs_break_callback(struct afs_vnode *vnode, enum afs_cb_break_reason reason) |
230 | { | 234 | { |
231 | write_seqlock(&vnode->cb_lock); | 235 | write_seqlock(&vnode->cb_lock); |
232 | __afs_break_callback(vnode); | 236 | __afs_break_callback(vnode, reason); |
233 | write_sequnlock(&vnode->cb_lock); | 237 | write_sequnlock(&vnode->cb_lock); |
234 | } | 238 | } |
235 | 239 | ||
@@ -277,6 +281,8 @@ static void afs_break_one_callback(struct afs_server *server, | |||
277 | 281 | ||
278 | write_lock(&volume->cb_v_break_lock); | 282 | write_lock(&volume->cb_v_break_lock); |
279 | volume->cb_v_break++; | 283 | volume->cb_v_break++; |
284 | trace_afs_cb_break(fid, volume->cb_v_break, | ||
285 | afs_cb_break_for_volume_callback, false); | ||
280 | write_unlock(&volume->cb_v_break_lock); | 286 | write_unlock(&volume->cb_v_break_lock); |
281 | } else { | 287 | } else { |
282 | data.volume = NULL; | 288 | data.volume = NULL; |
@@ -285,8 +291,10 @@ static void afs_break_one_callback(struct afs_server *server, | |||
285 | afs_iget5_test, &data); | 291 | afs_iget5_test, &data); |
286 | if (inode) { | 292 | if (inode) { |
287 | vnode = AFS_FS_I(inode); | 293 | vnode = AFS_FS_I(inode); |
288 | afs_break_callback(vnode); | 294 | afs_break_callback(vnode, afs_cb_break_for_callback); |
289 | iput(inode); | 295 | iput(inode); |
296 | } else { | ||
297 | trace_afs_cb_miss(fid, afs_cb_break_for_callback); | ||
290 | } | 298 | } |
291 | } | 299 | } |
292 | } | 300 | } |
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index 3451be03667f..602d75bf9bb2 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c | |||
@@ -256,8 +256,11 @@ static void SRXAFSCB_CallBack(struct work_struct *work) | |||
256 | * server holds up change visibility till it receives our reply so as | 256 | * server holds up change visibility till it receives our reply so as |
257 | * to maintain cache coherency. | 257 | * to maintain cache coherency. |
258 | */ | 258 | */ |
259 | if (call->server) | 259 | if (call->server) { |
260 | trace_afs_server(call->server, atomic_read(&call->server->usage), | ||
261 | afs_server_trace_callback); | ||
260 | afs_break_callbacks(call->server, call->count, call->request); | 262 | afs_break_callbacks(call->server, call->count, call->request); |
263 | } | ||
261 | 264 | ||
262 | afs_send_empty_reply(call); | 265 | afs_send_empty_reply(call); |
263 | afs_put_call(call); | 266 | afs_put_call(call); |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index da9563d62b32..e640d67274be 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -238,8 +238,7 @@ retry: | |||
238 | if (nr_inline > (PAGE_SIZE - sizeof(*req)) / sizeof(struct page *)) | 238 | if (nr_inline > (PAGE_SIZE - sizeof(*req)) / sizeof(struct page *)) |
239 | nr_inline = 0; | 239 | nr_inline = 0; |
240 | 240 | ||
241 | req = kzalloc(sizeof(*req) + sizeof(struct page *) * nr_inline, | 241 | req = kzalloc(struct_size(req, array, nr_inline), GFP_KERNEL); |
242 | GFP_KERNEL); | ||
243 | if (!req) | 242 | if (!req) |
244 | return ERR_PTR(-ENOMEM); | 243 | return ERR_PTR(-ENOMEM); |
245 | 244 | ||
@@ -1363,12 +1362,12 @@ static int afs_dir_remove_link(struct afs_vnode *dvnode, struct dentry *dentry, | |||
1363 | drop_nlink(&vnode->vfs_inode); | 1362 | drop_nlink(&vnode->vfs_inode); |
1364 | if (vnode->vfs_inode.i_nlink == 0) { | 1363 | if (vnode->vfs_inode.i_nlink == 0) { |
1365 | set_bit(AFS_VNODE_DELETED, &vnode->flags); | 1364 | set_bit(AFS_VNODE_DELETED, &vnode->flags); |
1366 | __afs_break_callback(vnode); | 1365 | __afs_break_callback(vnode, afs_cb_break_for_unlink); |
1367 | } | 1366 | } |
1368 | write_sequnlock(&vnode->cb_lock); | 1367 | write_sequnlock(&vnode->cb_lock); |
1369 | ret = 0; | 1368 | ret = 0; |
1370 | } else { | 1369 | } else { |
1371 | afs_break_callback(vnode); | 1370 | afs_break_callback(vnode, afs_cb_break_for_unlink); |
1372 | 1371 | ||
1373 | if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) | 1372 | if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) |
1374 | kdebug("AFS_VNODE_DELETED"); | 1373 | kdebug("AFS_VNODE_DELETED"); |
@@ -1390,7 +1389,8 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry) | |||
1390 | { | 1389 | { |
1391 | struct afs_fs_cursor fc; | 1390 | struct afs_fs_cursor fc; |
1392 | struct afs_status_cb *scb; | 1391 | struct afs_status_cb *scb; |
1393 | struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL; | 1392 | struct afs_vnode *dvnode = AFS_FS_I(dir); |
1393 | struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry)); | ||
1394 | struct key *key; | 1394 | struct key *key; |
1395 | bool need_rehash = false; | 1395 | bool need_rehash = false; |
1396 | int ret; | 1396 | int ret; |
@@ -1413,15 +1413,12 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry) | |||
1413 | } | 1413 | } |
1414 | 1414 | ||
1415 | /* Try to make sure we have a callback promise on the victim. */ | 1415 | /* Try to make sure we have a callback promise on the victim. */ |
1416 | if (d_really_is_positive(dentry)) { | 1416 | ret = afs_validate(vnode, key); |
1417 | vnode = AFS_FS_I(d_inode(dentry)); | 1417 | if (ret < 0) |
1418 | ret = afs_validate(vnode, key); | 1418 | goto error_key; |
1419 | if (ret < 0) | ||
1420 | goto error_key; | ||
1421 | } | ||
1422 | 1419 | ||
1423 | spin_lock(&dentry->d_lock); | 1420 | spin_lock(&dentry->d_lock); |
1424 | if (vnode && d_count(dentry) > 1) { | 1421 | if (d_count(dentry) > 1) { |
1425 | spin_unlock(&dentry->d_lock); | 1422 | spin_unlock(&dentry->d_lock); |
1426 | /* Start asynchronous writeout of the inode */ | 1423 | /* Start asynchronous writeout of the inode */ |
1427 | write_inode_now(d_inode(dentry), 0); | 1424 | write_inode_now(d_inode(dentry), 0); |
diff --git a/fs/afs/file.c b/fs/afs/file.c index 8fd7d3b9a1b1..56b69576274d 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c | |||
@@ -310,8 +310,7 @@ int afs_page_filler(void *data, struct page *page) | |||
310 | /* fall through */ | 310 | /* fall through */ |
311 | default: | 311 | default: |
312 | go_on: | 312 | go_on: |
313 | req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *), | 313 | req = kzalloc(struct_size(req, array, 1), GFP_KERNEL); |
314 | GFP_KERNEL); | ||
315 | if (!req) | 314 | if (!req) |
316 | goto enomem; | 315 | goto enomem; |
317 | 316 | ||
@@ -461,8 +460,7 @@ static int afs_readpages_one(struct file *file, struct address_space *mapping, | |||
461 | n++; | 460 | n++; |
462 | } | 461 | } |
463 | 462 | ||
464 | req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *) * n, | 463 | req = kzalloc(struct_size(req, array, n), GFP_NOFS); |
465 | GFP_NOFS); | ||
466 | if (!req) | 464 | if (!req) |
467 | return -ENOMEM; | 465 | return -ENOMEM; |
468 | 466 | ||
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index a1ef0266422a..1ce73e014139 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c | |||
@@ -1911,7 +1911,7 @@ struct afs_call *afs_fs_get_capabilities(struct afs_net *net, | |||
1911 | return ERR_PTR(-ENOMEM); | 1911 | return ERR_PTR(-ENOMEM); |
1912 | 1912 | ||
1913 | call->key = key; | 1913 | call->key = key; |
1914 | call->server = afs_get_server(server); | 1914 | call->server = afs_get_server(server, afs_server_trace_get_caps); |
1915 | call->server_index = server_index; | 1915 | call->server_index = server_index; |
1916 | call->upgrade = true; | 1916 | call->upgrade = true; |
1917 | call->async = true; | 1917 | call->async = true; |
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 18a50d4febcf..7b1c18c32f48 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -283,7 +283,7 @@ void afs_vnode_commit_status(struct afs_fs_cursor *fc, | |||
283 | if (scb->status.abort_code == VNOVNODE) { | 283 | if (scb->status.abort_code == VNOVNODE) { |
284 | set_bit(AFS_VNODE_DELETED, &vnode->flags); | 284 | set_bit(AFS_VNODE_DELETED, &vnode->flags); |
285 | clear_nlink(&vnode->vfs_inode); | 285 | clear_nlink(&vnode->vfs_inode); |
286 | __afs_break_callback(vnode); | 286 | __afs_break_callback(vnode, afs_cb_break_for_deleted); |
287 | } | 287 | } |
288 | } else { | 288 | } else { |
289 | if (scb->have_status) | 289 | if (scb->have_status) |
@@ -594,8 +594,9 @@ bool afs_check_validity(struct afs_vnode *vnode) | |||
594 | struct afs_cb_interest *cbi; | 594 | struct afs_cb_interest *cbi; |
595 | struct afs_server *server; | 595 | struct afs_server *server; |
596 | struct afs_volume *volume = vnode->volume; | 596 | struct afs_volume *volume = vnode->volume; |
597 | enum afs_cb_break_reason need_clear = afs_cb_break_no_break; | ||
597 | time64_t now = ktime_get_real_seconds(); | 598 | time64_t now = ktime_get_real_seconds(); |
598 | bool valid, need_clear = false; | 599 | bool valid; |
599 | unsigned int cb_break, cb_s_break, cb_v_break; | 600 | unsigned int cb_break, cb_s_break, cb_v_break; |
600 | int seq = 0; | 601 | int seq = 0; |
601 | 602 | ||
@@ -613,13 +614,13 @@ bool afs_check_validity(struct afs_vnode *vnode) | |||
613 | vnode->cb_v_break != cb_v_break) { | 614 | vnode->cb_v_break != cb_v_break) { |
614 | vnode->cb_s_break = cb_s_break; | 615 | vnode->cb_s_break = cb_s_break; |
615 | vnode->cb_v_break = cb_v_break; | 616 | vnode->cb_v_break = cb_v_break; |
616 | need_clear = true; | 617 | need_clear = afs_cb_break_for_vsbreak; |
617 | valid = false; | 618 | valid = false; |
618 | } else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) { | 619 | } else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) { |
619 | need_clear = true; | 620 | need_clear = afs_cb_break_for_zap; |
620 | valid = false; | 621 | valid = false; |
621 | } else if (vnode->cb_expires_at - 10 <= now) { | 622 | } else if (vnode->cb_expires_at - 10 <= now) { |
622 | need_clear = true; | 623 | need_clear = afs_cb_break_for_lapsed; |
623 | valid = false; | 624 | valid = false; |
624 | } else { | 625 | } else { |
625 | valid = true; | 626 | valid = true; |
@@ -635,10 +636,12 @@ bool afs_check_validity(struct afs_vnode *vnode) | |||
635 | 636 | ||
636 | done_seqretry(&vnode->cb_lock, seq); | 637 | done_seqretry(&vnode->cb_lock, seq); |
637 | 638 | ||
638 | if (need_clear) { | 639 | if (need_clear != afs_cb_break_no_break) { |
639 | write_seqlock(&vnode->cb_lock); | 640 | write_seqlock(&vnode->cb_lock); |
640 | if (cb_break == vnode->cb_break) | 641 | if (cb_break == vnode->cb_break) |
641 | __afs_break_callback(vnode); | 642 | __afs_break_callback(vnode, need_clear); |
643 | else | ||
644 | trace_afs_cb_miss(&vnode->fid, need_clear); | ||
642 | write_sequnlock(&vnode->cb_lock); | 645 | write_sequnlock(&vnode->cb_lock); |
643 | valid = false; | 646 | valid = false; |
644 | } | 647 | } |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 7ee63526c6a2..be37fafbaeb5 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -514,6 +514,7 @@ struct afs_server { | |||
514 | atomic_t usage; | 514 | atomic_t usage; |
515 | u32 addr_version; /* Address list version */ | 515 | u32 addr_version; /* Address list version */ |
516 | u32 cm_epoch; /* Server RxRPC epoch */ | 516 | u32 cm_epoch; /* Server RxRPC epoch */ |
517 | unsigned int debug_id; /* Debugging ID for traces */ | ||
517 | 518 | ||
518 | /* file service access */ | 519 | /* file service access */ |
519 | rwlock_t fs_lock; /* access lock */ | 520 | rwlock_t fs_lock; /* access lock */ |
@@ -844,9 +845,9 @@ extern struct fscache_cookie_def afs_vnode_cache_index_def; | |||
844 | * callback.c | 845 | * callback.c |
845 | */ | 846 | */ |
846 | extern void afs_init_callback_state(struct afs_server *); | 847 | extern void afs_init_callback_state(struct afs_server *); |
847 | extern void __afs_break_callback(struct afs_vnode *); | 848 | extern void __afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason); |
848 | extern void afs_break_callback(struct afs_vnode *); | 849 | extern void afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason); |
849 | extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*); | 850 | extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break *); |
850 | 851 | ||
851 | extern int afs_register_server_cb_interest(struct afs_vnode *, | 852 | extern int afs_register_server_cb_interest(struct afs_vnode *, |
852 | struct afs_server_list *, unsigned int); | 853 | struct afs_server_list *, unsigned int); |
@@ -1240,17 +1241,12 @@ extern void __exit afs_clean_up_permit_cache(void); | |||
1240 | */ | 1241 | */ |
1241 | extern spinlock_t afs_server_peer_lock; | 1242 | extern spinlock_t afs_server_peer_lock; |
1242 | 1243 | ||
1243 | static inline struct afs_server *afs_get_server(struct afs_server *server) | ||
1244 | { | ||
1245 | atomic_inc(&server->usage); | ||
1246 | return server; | ||
1247 | } | ||
1248 | |||
1249 | extern struct afs_server *afs_find_server(struct afs_net *, | 1244 | extern struct afs_server *afs_find_server(struct afs_net *, |
1250 | const struct sockaddr_rxrpc *); | 1245 | const struct sockaddr_rxrpc *); |
1251 | extern struct afs_server *afs_find_server_by_uuid(struct afs_net *, const uuid_t *); | 1246 | extern struct afs_server *afs_find_server_by_uuid(struct afs_net *, const uuid_t *); |
1252 | extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *); | 1247 | extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *); |
1253 | extern void afs_put_server(struct afs_net *, struct afs_server *); | 1248 | extern struct afs_server *afs_get_server(struct afs_server *, enum afs_server_trace); |
1249 | extern void afs_put_server(struct afs_net *, struct afs_server *, enum afs_server_trace); | ||
1254 | extern void afs_manage_servers(struct work_struct *); | 1250 | extern void afs_manage_servers(struct work_struct *); |
1255 | extern void afs_servers_timer(struct timer_list *); | 1251 | extern void afs_servers_timer(struct timer_list *); |
1256 | extern void __net_exit afs_purge_servers(struct afs_net *); | 1252 | 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, | |||
1434 | { | 1430 | { |
1435 | if (fc->ac.error == -ENOENT) { | 1431 | if (fc->ac.error == -ENOENT) { |
1436 | set_bit(AFS_VNODE_DELETED, &vnode->flags); | 1432 | set_bit(AFS_VNODE_DELETED, &vnode->flags); |
1437 | afs_break_callback(vnode); | 1433 | afs_break_callback(vnode, afs_cb_break_for_deleted); |
1438 | } | 1434 | } |
1439 | } | 1435 | } |
1440 | 1436 | ||
diff --git a/fs/afs/misc.c b/fs/afs/misc.c index 5497ab38f585..52b19e9c1535 100644 --- a/fs/afs/misc.c +++ b/fs/afs/misc.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include "internal.h" | 11 | #include "internal.h" |
12 | #include "afs_fs.h" | 12 | #include "afs_fs.h" |
13 | #include "protocol_uae.h" | ||
13 | 14 | ||
14 | /* | 15 | /* |
15 | * convert an AFS abort code to a Linux error number | 16 | * convert an AFS abort code to a Linux error number |
@@ -65,34 +66,25 @@ int afs_abort_to_error(u32 abort_code) | |||
65 | case AFSVL_PERM: return -EACCES; | 66 | case AFSVL_PERM: return -EACCES; |
66 | case AFSVL_NOMEM: return -EREMOTEIO; | 67 | case AFSVL_NOMEM: return -EREMOTEIO; |
67 | 68 | ||
68 | /* Unified AFS error table; ET "uae" == 0x2f6df00 */ | 69 | /* Unified AFS error table */ |
69 | case 0x2f6df00: return -EPERM; | 70 | case UAEPERM: return -EPERM; |
70 | case 0x2f6df01: return -ENOENT; | 71 | case UAENOENT: return -ENOENT; |
71 | case 0x2f6df04: return -EIO; | 72 | case UAEACCES: return -EACCES; |
72 | case 0x2f6df0a: return -EAGAIN; | 73 | case UAEBUSY: return -EBUSY; |
73 | case 0x2f6df0b: return -ENOMEM; | 74 | case UAEEXIST: return -EEXIST; |
74 | case 0x2f6df0c: return -EACCES; | 75 | case UAENOTDIR: return -ENOTDIR; |
75 | case 0x2f6df0f: return -EBUSY; | 76 | case UAEISDIR: return -EISDIR; |
76 | case 0x2f6df10: return -EEXIST; | 77 | case UAEFBIG: return -EFBIG; |
77 | case 0x2f6df11: return -EXDEV; | 78 | case UAENOSPC: return -ENOSPC; |
78 | case 0x2f6df12: return -ENODEV; | 79 | case UAEROFS: return -EROFS; |
79 | case 0x2f6df13: return -ENOTDIR; | 80 | case UAEMLINK: return -EMLINK; |
80 | case 0x2f6df14: return -EISDIR; | 81 | case UAEDEADLK: return -EDEADLK; |
81 | case 0x2f6df15: return -EINVAL; | 82 | case UAENAMETOOLONG: return -ENAMETOOLONG; |
82 | case 0x2f6df1a: return -EFBIG; | 83 | case UAENOLCK: return -ENOLCK; |
83 | case 0x2f6df1b: return -ENOSPC; | 84 | case UAENOTEMPTY: return -ENOTEMPTY; |
84 | case 0x2f6df1d: return -EROFS; | 85 | case UAELOOP: return -ELOOP; |
85 | case 0x2f6df1e: return -EMLINK; | 86 | case UAENOMEDIUM: return -ENOMEDIUM; |
86 | case 0x2f6df20: return -EDOM; | 87 | case UAEDQUOT: return -EDQUOT; |
87 | case 0x2f6df21: return -ERANGE; | ||
88 | case 0x2f6df22: return -EDEADLK; | ||
89 | case 0x2f6df23: return -ENAMETOOLONG; | ||
90 | case 0x2f6df24: return -ENOLCK; | ||
91 | case 0x2f6df26: return -ENOTEMPTY; | ||
92 | case 0x2f6df28: return -EWOULDBLOCK; | ||
93 | case 0x2f6df69: return -ENOTCONN; | ||
94 | case 0x2f6df6c: return -ETIMEDOUT; | ||
95 | case 0x2f6df78: return -EDQUOT; | ||
96 | 88 | ||
97 | /* RXKAD abort codes; from include/rxrpc/packet.h. ET "RXK" == 0x1260B00 */ | 89 | /* RXKAD abort codes; from include/rxrpc/packet.h. ET "RXK" == 0x1260B00 */ |
98 | case RXKADINCONSISTENCY: return -EPROTO; | 90 | case RXKADINCONSISTENCY: return -EPROTO; |
diff --git a/fs/afs/protocol_uae.h b/fs/afs/protocol_uae.h new file mode 100644 index 000000000000..1b3d1060bd34 --- /dev/null +++ b/fs/afs/protocol_uae.h | |||
@@ -0,0 +1,132 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* Universal AFS Error codes (UAE). | ||
3 | * | ||
4 | * Copyright (C) 2003, Daria Phoebe Brashear | ||
5 | * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. | ||
6 | */ | ||
7 | |||
8 | enum { | ||
9 | UAEPERM = 0x2f6df00, /* Operation not permitted */ | ||
10 | UAENOENT = 0x2f6df01, /* No such file or directory */ | ||
11 | UAESRCH = 0x2f6df02, /* No such process */ | ||
12 | UAEINTR = 0x2f6df03, /* Interrupted system call */ | ||
13 | UAEIO = 0x2f6df04, /* I/O error */ | ||
14 | UAENXIO = 0x2f6df05, /* No such device or address */ | ||
15 | UAE2BIG = 0x2f6df06, /* Arg list too long */ | ||
16 | UAENOEXEC = 0x2f6df07, /* Exec format error */ | ||
17 | UAEBADF = 0x2f6df08, /* Bad file number */ | ||
18 | UAECHILD = 0x2f6df09, /* No child processes */ | ||
19 | UAEAGAIN = 0x2f6df0a, /* Try again */ | ||
20 | UAENOMEM = 0x2f6df0b, /* Out of memory */ | ||
21 | UAEACCES = 0x2f6df0c, /* Permission denied */ | ||
22 | UAEFAULT = 0x2f6df0d, /* Bad address */ | ||
23 | UAENOTBLK = 0x2f6df0e, /* Block device required */ | ||
24 | UAEBUSY = 0x2f6df0f, /* Device or resource busy */ | ||
25 | UAEEXIST = 0x2f6df10, /* File exists */ | ||
26 | UAEXDEV = 0x2f6df11, /* Cross-device link */ | ||
27 | UAENODEV = 0x2f6df12, /* No such device */ | ||
28 | UAENOTDIR = 0x2f6df13, /* Not a directory */ | ||
29 | UAEISDIR = 0x2f6df14, /* Is a directory */ | ||
30 | UAEINVAL = 0x2f6df15, /* Invalid argument */ | ||
31 | UAENFILE = 0x2f6df16, /* File table overflow */ | ||
32 | UAEMFILE = 0x2f6df17, /* Too many open files */ | ||
33 | UAENOTTY = 0x2f6df18, /* Not a typewriter */ | ||
34 | UAETXTBSY = 0x2f6df19, /* Text file busy */ | ||
35 | UAEFBIG = 0x2f6df1a, /* File too large */ | ||
36 | UAENOSPC = 0x2f6df1b, /* No space left on device */ | ||
37 | UAESPIPE = 0x2f6df1c, /* Illegal seek */ | ||
38 | UAEROFS = 0x2f6df1d, /* Read-only file system */ | ||
39 | UAEMLINK = 0x2f6df1e, /* Too many links */ | ||
40 | UAEPIPE = 0x2f6df1f, /* Broken pipe */ | ||
41 | UAEDOM = 0x2f6df20, /* Math argument out of domain of func */ | ||
42 | UAERANGE = 0x2f6df21, /* Math result not representable */ | ||
43 | UAEDEADLK = 0x2f6df22, /* Resource deadlock would occur */ | ||
44 | UAENAMETOOLONG = 0x2f6df23, /* File name too long */ | ||
45 | UAENOLCK = 0x2f6df24, /* No record locks available */ | ||
46 | UAENOSYS = 0x2f6df25, /* Function not implemented */ | ||
47 | UAENOTEMPTY = 0x2f6df26, /* Directory not empty */ | ||
48 | UAELOOP = 0x2f6df27, /* Too many symbolic links encountered */ | ||
49 | UAEWOULDBLOCK = 0x2f6df28, /* Operation would block */ | ||
50 | UAENOMSG = 0x2f6df29, /* No message of desired type */ | ||
51 | UAEIDRM = 0x2f6df2a, /* Identifier removed */ | ||
52 | UAECHRNG = 0x2f6df2b, /* Channel number out of range */ | ||
53 | UAEL2NSYNC = 0x2f6df2c, /* Level 2 not synchronized */ | ||
54 | UAEL3HLT = 0x2f6df2d, /* Level 3 halted */ | ||
55 | UAEL3RST = 0x2f6df2e, /* Level 3 reset */ | ||
56 | UAELNRNG = 0x2f6df2f, /* Link number out of range */ | ||
57 | UAEUNATCH = 0x2f6df30, /* Protocol driver not attached */ | ||
58 | UAENOCSI = 0x2f6df31, /* No CSI structure available */ | ||
59 | UAEL2HLT = 0x2f6df32, /* Level 2 halted */ | ||
60 | UAEBADE = 0x2f6df33, /* Invalid exchange */ | ||
61 | UAEBADR = 0x2f6df34, /* Invalid request descriptor */ | ||
62 | UAEXFULL = 0x2f6df35, /* Exchange full */ | ||
63 | UAENOANO = 0x2f6df36, /* No anode */ | ||
64 | UAEBADRQC = 0x2f6df37, /* Invalid request code */ | ||
65 | UAEBADSLT = 0x2f6df38, /* Invalid slot */ | ||
66 | UAEBFONT = 0x2f6df39, /* Bad font file format */ | ||
67 | UAENOSTR = 0x2f6df3a, /* Device not a stream */ | ||
68 | UAENODATA = 0x2f6df3b, /* No data available */ | ||
69 | UAETIME = 0x2f6df3c, /* Timer expired */ | ||
70 | UAENOSR = 0x2f6df3d, /* Out of streams resources */ | ||
71 | UAENONET = 0x2f6df3e, /* Machine is not on the network */ | ||
72 | UAENOPKG = 0x2f6df3f, /* Package not installed */ | ||
73 | UAEREMOTE = 0x2f6df40, /* Object is remote */ | ||
74 | UAENOLINK = 0x2f6df41, /* Link has been severed */ | ||
75 | UAEADV = 0x2f6df42, /* Advertise error */ | ||
76 | UAESRMNT = 0x2f6df43, /* Srmount error */ | ||
77 | UAECOMM = 0x2f6df44, /* Communication error on send */ | ||
78 | UAEPROTO = 0x2f6df45, /* Protocol error */ | ||
79 | UAEMULTIHOP = 0x2f6df46, /* Multihop attempted */ | ||
80 | UAEDOTDOT = 0x2f6df47, /* RFS specific error */ | ||
81 | UAEBADMSG = 0x2f6df48, /* Not a data message */ | ||
82 | UAEOVERFLOW = 0x2f6df49, /* Value too large for defined data type */ | ||
83 | UAENOTUNIQ = 0x2f6df4a, /* Name not unique on network */ | ||
84 | UAEBADFD = 0x2f6df4b, /* File descriptor in bad state */ | ||
85 | UAEREMCHG = 0x2f6df4c, /* Remote address changed */ | ||
86 | UAELIBACC = 0x2f6df4d, /* Can not access a needed shared library */ | ||
87 | UAELIBBAD = 0x2f6df4e, /* Accessing a corrupted shared library */ | ||
88 | UAELIBSCN = 0x2f6df4f, /* .lib section in a.out corrupted */ | ||
89 | UAELIBMAX = 0x2f6df50, /* Attempting to link in too many shared libraries */ | ||
90 | UAELIBEXEC = 0x2f6df51, /* Cannot exec a shared library directly */ | ||
91 | UAEILSEQ = 0x2f6df52, /* Illegal byte sequence */ | ||
92 | UAERESTART = 0x2f6df53, /* Interrupted system call should be restarted */ | ||
93 | UAESTRPIPE = 0x2f6df54, /* Streams pipe error */ | ||
94 | UAEUSERS = 0x2f6df55, /* Too many users */ | ||
95 | UAENOTSOCK = 0x2f6df56, /* Socket operation on non-socket */ | ||
96 | UAEDESTADDRREQ = 0x2f6df57, /* Destination address required */ | ||
97 | UAEMSGSIZE = 0x2f6df58, /* Message too long */ | ||
98 | UAEPROTOTYPE = 0x2f6df59, /* Protocol wrong type for socket */ | ||
99 | UAENOPROTOOPT = 0x2f6df5a, /* Protocol not available */ | ||
100 | UAEPROTONOSUPPORT = 0x2f6df5b, /* Protocol not supported */ | ||
101 | UAESOCKTNOSUPPORT = 0x2f6df5c, /* Socket type not supported */ | ||
102 | UAEOPNOTSUPP = 0x2f6df5d, /* Operation not supported on transport endpoint */ | ||
103 | UAEPFNOSUPPORT = 0x2f6df5e, /* Protocol family not supported */ | ||
104 | UAEAFNOSUPPORT = 0x2f6df5f, /* Address family not supported by protocol */ | ||
105 | UAEADDRINUSE = 0x2f6df60, /* Address already in use */ | ||
106 | UAEADDRNOTAVAIL = 0x2f6df61, /* Cannot assign requested address */ | ||
107 | UAENETDOWN = 0x2f6df62, /* Network is down */ | ||
108 | UAENETUNREACH = 0x2f6df63, /* Network is unreachable */ | ||
109 | UAENETRESET = 0x2f6df64, /* Network dropped connection because of reset */ | ||
110 | UAECONNABORTED = 0x2f6df65, /* Software caused connection abort */ | ||
111 | UAECONNRESET = 0x2f6df66, /* Connection reset by peer */ | ||
112 | UAENOBUFS = 0x2f6df67, /* No buffer space available */ | ||
113 | UAEISCONN = 0x2f6df68, /* Transport endpoint is already connected */ | ||
114 | UAENOTCONN = 0x2f6df69, /* Transport endpoint is not connected */ | ||
115 | UAESHUTDOWN = 0x2f6df6a, /* Cannot send after transport endpoint shutdown */ | ||
116 | UAETOOMANYREFS = 0x2f6df6b, /* Too many references: cannot splice */ | ||
117 | UAETIMEDOUT = 0x2f6df6c, /* Connection timed out */ | ||
118 | UAECONNREFUSED = 0x2f6df6d, /* Connection refused */ | ||
119 | UAEHOSTDOWN = 0x2f6df6e, /* Host is down */ | ||
120 | UAEHOSTUNREACH = 0x2f6df6f, /* No route to host */ | ||
121 | UAEALREADY = 0x2f6df70, /* Operation already in progress */ | ||
122 | UAEINPROGRESS = 0x2f6df71, /* Operation now in progress */ | ||
123 | UAESTALE = 0x2f6df72, /* Stale NFS file handle */ | ||
124 | UAEUCLEAN = 0x2f6df73, /* Structure needs cleaning */ | ||
125 | UAENOTNAM = 0x2f6df74, /* Not a XENIX named type file */ | ||
126 | UAENAVAIL = 0x2f6df75, /* No XENIX semaphores available */ | ||
127 | UAEISNAM = 0x2f6df76, /* Is a named type file */ | ||
128 | UAEREMOTEIO = 0x2f6df77, /* Remote I/O error */ | ||
129 | UAEDQUOT = 0x2f6df78, /* Quota exceeded */ | ||
130 | UAENOMEDIUM = 0x2f6df79, /* No medium found */ | ||
131 | UAEMEDIUMTYPE = 0x2f6df7a, /* Wrong medium type */ | ||
132 | }; | ||
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index d1dde2834b6d..0e5269374ac1 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
@@ -184,7 +184,7 @@ void afs_put_call(struct afs_call *call) | |||
184 | if (call->type->destructor) | 184 | if (call->type->destructor) |
185 | call->type->destructor(call); | 185 | call->type->destructor(call); |
186 | 186 | ||
187 | afs_put_server(call->net, call->server); | 187 | afs_put_server(call->net, call->server, afs_server_trace_put_call); |
188 | afs_put_cb_interest(call->net, call->cbi); | 188 | afs_put_cb_interest(call->net, call->cbi); |
189 | afs_put_addrlist(call->alist); | 189 | afs_put_addrlist(call->alist); |
190 | kfree(call->request); | 190 | kfree(call->request); |
diff --git a/fs/afs/server.c b/fs/afs/server.c index e900cd74361b..64d440aaabc0 100644 --- a/fs/afs/server.c +++ b/fs/afs/server.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | static unsigned afs_server_gc_delay = 10; /* Server record timeout in seconds */ | 14 | static unsigned afs_server_gc_delay = 10; /* Server record timeout in seconds */ |
15 | static unsigned afs_server_update_delay = 30; /* Time till VLDB recheck in secs */ | 15 | static unsigned afs_server_update_delay = 30; /* Time till VLDB recheck in secs */ |
16 | static atomic_t afs_server_debug_id; | ||
16 | 17 | ||
17 | static void afs_inc_servers_outstanding(struct afs_net *net) | 18 | static void afs_inc_servers_outstanding(struct afs_net *net) |
18 | { | 19 | { |
@@ -47,7 +48,7 @@ struct afs_server *afs_find_server(struct afs_net *net, | |||
47 | 48 | ||
48 | do { | 49 | do { |
49 | if (server) | 50 | if (server) |
50 | afs_put_server(net, server); | 51 | afs_put_server(net, server, afs_server_trace_put_find_rsq); |
51 | server = NULL; | 52 | server = NULL; |
52 | read_seqbegin_or_lock(&net->fs_addr_lock, &seq); | 53 | read_seqbegin_or_lock(&net->fs_addr_lock, &seq); |
53 | 54 | ||
@@ -112,7 +113,7 @@ struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uu | |||
112 | * changes. | 113 | * changes. |
113 | */ | 114 | */ |
114 | if (server) | 115 | if (server) |
115 | afs_put_server(net, server); | 116 | afs_put_server(net, server, afs_server_trace_put_uuid_rsq); |
116 | server = NULL; | 117 | server = NULL; |
117 | 118 | ||
118 | read_seqbegin_or_lock(&net->fs_lock, &seq); | 119 | 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 | |||
127 | } else if (diff > 0) { | 128 | } else if (diff > 0) { |
128 | p = p->rb_right; | 129 | p = p->rb_right; |
129 | } else { | 130 | } else { |
130 | afs_get_server(server); | 131 | afs_get_server(server, afs_server_trace_get_by_uuid); |
131 | break; | 132 | break; |
132 | } | 133 | } |
133 | 134 | ||
@@ -198,7 +199,7 @@ static struct afs_server *afs_install_server(struct afs_net *net, | |||
198 | ret = 0; | 199 | ret = 0; |
199 | 200 | ||
200 | exists: | 201 | exists: |
201 | afs_get_server(server); | 202 | afs_get_server(server, afs_server_trace_get_install); |
202 | write_sequnlock(&net->fs_lock); | 203 | write_sequnlock(&net->fs_lock); |
203 | return server; | 204 | return server; |
204 | } | 205 | } |
@@ -219,6 +220,7 @@ static struct afs_server *afs_alloc_server(struct afs_net *net, | |||
219 | goto enomem; | 220 | goto enomem; |
220 | 221 | ||
221 | atomic_set(&server->usage, 1); | 222 | atomic_set(&server->usage, 1); |
223 | server->debug_id = atomic_inc_return(&afs_server_debug_id); | ||
222 | RCU_INIT_POINTER(server->addresses, alist); | 224 | RCU_INIT_POINTER(server->addresses, alist); |
223 | server->addr_version = alist->version; | 225 | server->addr_version = alist->version; |
224 | server->uuid = *uuid; | 226 | server->uuid = *uuid; |
@@ -230,6 +232,7 @@ static struct afs_server *afs_alloc_server(struct afs_net *net, | |||
230 | spin_lock_init(&server->probe_lock); | 232 | spin_lock_init(&server->probe_lock); |
231 | 233 | ||
232 | afs_inc_servers_outstanding(net); | 234 | afs_inc_servers_outstanding(net); |
235 | trace_afs_server(server, 1, afs_server_trace_alloc); | ||
233 | _leave(" = %p", server); | 236 | _leave(" = %p", server); |
234 | return server; | 237 | return server; |
235 | 238 | ||
@@ -325,9 +328,22 @@ void afs_servers_timer(struct timer_list *timer) | |||
325 | } | 328 | } |
326 | 329 | ||
327 | /* | 330 | /* |
331 | * Get a reference on a server object. | ||
332 | */ | ||
333 | struct afs_server *afs_get_server(struct afs_server *server, | ||
334 | enum afs_server_trace reason) | ||
335 | { | ||
336 | unsigned int u = atomic_inc_return(&server->usage); | ||
337 | |||
338 | trace_afs_server(server, u, reason); | ||
339 | return server; | ||
340 | } | ||
341 | |||
342 | /* | ||
328 | * Release a reference on a server record. | 343 | * Release a reference on a server record. |
329 | */ | 344 | */ |
330 | void afs_put_server(struct afs_net *net, struct afs_server *server) | 345 | void afs_put_server(struct afs_net *net, struct afs_server *server, |
346 | enum afs_server_trace reason) | ||
331 | { | 347 | { |
332 | unsigned int usage; | 348 | unsigned int usage; |
333 | 349 | ||
@@ -338,7 +354,7 @@ void afs_put_server(struct afs_net *net, struct afs_server *server) | |||
338 | 354 | ||
339 | usage = atomic_dec_return(&server->usage); | 355 | usage = atomic_dec_return(&server->usage); |
340 | 356 | ||
341 | _enter("{%u}", usage); | 357 | trace_afs_server(server, usage, reason); |
342 | 358 | ||
343 | if (likely(usage > 0)) | 359 | if (likely(usage > 0)) |
344 | return; | 360 | return; |
@@ -350,6 +366,8 @@ static void afs_server_rcu(struct rcu_head *rcu) | |||
350 | { | 366 | { |
351 | struct afs_server *server = container_of(rcu, struct afs_server, rcu); | 367 | struct afs_server *server = container_of(rcu, struct afs_server, rcu); |
352 | 368 | ||
369 | trace_afs_server(server, atomic_read(&server->usage), | ||
370 | afs_server_trace_free); | ||
353 | afs_put_addrlist(rcu_access_pointer(server->addresses)); | 371 | afs_put_addrlist(rcu_access_pointer(server->addresses)); |
354 | kfree(server); | 372 | kfree(server); |
355 | } | 373 | } |
@@ -365,7 +383,9 @@ static void afs_destroy_server(struct afs_net *net, struct afs_server *server) | |||
365 | .index = alist->preferred, | 383 | .index = alist->preferred, |
366 | .error = 0, | 384 | .error = 0, |
367 | }; | 385 | }; |
368 | _enter("%p", server); | 386 | |
387 | trace_afs_server(server, atomic_read(&server->usage), | ||
388 | afs_server_trace_give_up_cb); | ||
369 | 389 | ||
370 | if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags)) | 390 | if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags)) |
371 | afs_fs_give_up_all_callbacks(net, server, &ac, NULL); | 391 | 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) | |||
373 | wait_var_event(&server->probe_outstanding, | 393 | wait_var_event(&server->probe_outstanding, |
374 | atomic_read(&server->probe_outstanding) == 0); | 394 | atomic_read(&server->probe_outstanding) == 0); |
375 | 395 | ||
396 | trace_afs_server(server, atomic_read(&server->usage), | ||
397 | afs_server_trace_destroy); | ||
376 | call_rcu(&server->rcu, afs_server_rcu); | 398 | call_rcu(&server->rcu, afs_server_rcu); |
377 | afs_dec_servers_outstanding(net); | 399 | afs_dec_servers_outstanding(net); |
378 | } | 400 | } |
@@ -392,6 +414,7 @@ static void afs_gc_servers(struct afs_net *net, struct afs_server *gc_list) | |||
392 | write_seqlock(&net->fs_lock); | 414 | write_seqlock(&net->fs_lock); |
393 | usage = 1; | 415 | usage = 1; |
394 | deleted = atomic_try_cmpxchg(&server->usage, &usage, 0); | 416 | deleted = atomic_try_cmpxchg(&server->usage, &usage, 0); |
417 | trace_afs_server(server, usage, afs_server_trace_gc); | ||
395 | if (deleted) { | 418 | if (deleted) { |
396 | rb_erase(&server->uuid_rb, &net->fs_servers); | 419 | rb_erase(&server->uuid_rb, &net->fs_servers); |
397 | hlist_del_rcu(&server->proc_link); | 420 | hlist_del_rcu(&server->proc_link); |
@@ -514,6 +537,8 @@ static noinline bool afs_update_server_record(struct afs_fs_cursor *fc, struct a | |||
514 | 537 | ||
515 | _enter(""); | 538 | _enter(""); |
516 | 539 | ||
540 | trace_afs_server(server, atomic_read(&server->usage), afs_server_trace_update); | ||
541 | |||
517 | alist = afs_vl_lookup_addrs(fc->vnode->volume->cell, fc->key, | 542 | alist = afs_vl_lookup_addrs(fc->vnode->volume->cell, fc->key, |
518 | &server->uuid); | 543 | &server->uuid); |
519 | if (IS_ERR(alist)) { | 544 | if (IS_ERR(alist)) { |
diff --git a/fs/afs/server_list.c b/fs/afs/server_list.c index b4988bc8e6f2..888d91d195d9 100644 --- a/fs/afs/server_list.c +++ b/fs/afs/server_list.c | |||
@@ -16,7 +16,8 @@ void afs_put_serverlist(struct afs_net *net, struct afs_server_list *slist) | |||
16 | if (slist && refcount_dec_and_test(&slist->usage)) { | 16 | if (slist && refcount_dec_and_test(&slist->usage)) { |
17 | for (i = 0; i < slist->nr_servers; i++) { | 17 | for (i = 0; i < slist->nr_servers; i++) { |
18 | afs_put_cb_interest(net, slist->servers[i].cb_interest); | 18 | afs_put_cb_interest(net, slist->servers[i].cb_interest); |
19 | afs_put_server(net, slist->servers[i].server); | 19 | afs_put_server(net, slist->servers[i].server, |
20 | afs_server_trace_put_slist); | ||
20 | } | 21 | } |
21 | kfree(slist); | 22 | kfree(slist); |
22 | } | 23 | } |
@@ -67,7 +68,8 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, | |||
67 | break; | 68 | break; |
68 | if (j < slist->nr_servers) { | 69 | if (j < slist->nr_servers) { |
69 | if (slist->servers[j].server == server) { | 70 | if (slist->servers[j].server == server) { |
70 | afs_put_server(cell->net, server); | 71 | afs_put_server(cell->net, server, |
72 | afs_server_trace_put_slist_isort); | ||
71 | continue; | 73 | continue; |
72 | } | 74 | } |
73 | 75 | ||
diff --git a/fs/afs/write.c b/fs/afs/write.c index 98eb7adbce91..cb76566763db 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c | |||
@@ -44,8 +44,7 @@ static int afs_fill_page(struct afs_vnode *vnode, struct key *key, | |||
44 | return 0; | 44 | return 0; |
45 | } | 45 | } |
46 | 46 | ||
47 | req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *), | 47 | req = kzalloc(struct_size(req, array, 1), GFP_KERNEL); |
48 | GFP_KERNEL); | ||
49 | if (!req) | 48 | if (!req) |
50 | return -ENOMEM; | 49 | return -ENOMEM; |
51 | 50 | ||
diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h index 51b1e0da2efc..d5ec4fac82ae 100644 --- a/include/trace/events/afs.h +++ b/include/trace/events/afs.h | |||
@@ -27,6 +27,26 @@ enum afs_call_trace { | |||
27 | afs_call_trace_work, | 27 | afs_call_trace_work, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | enum afs_server_trace { | ||
31 | afs_server_trace_alloc, | ||
32 | afs_server_trace_callback, | ||
33 | afs_server_trace_destroy, | ||
34 | afs_server_trace_free, | ||
35 | afs_server_trace_gc, | ||
36 | afs_server_trace_get_by_uuid, | ||
37 | afs_server_trace_get_caps, | ||
38 | afs_server_trace_get_install, | ||
39 | afs_server_trace_get_new_cbi, | ||
40 | afs_server_trace_give_up_cb, | ||
41 | afs_server_trace_put_call, | ||
42 | afs_server_trace_put_cbi, | ||
43 | afs_server_trace_put_find_rsq, | ||
44 | afs_server_trace_put_slist, | ||
45 | afs_server_trace_put_slist_isort, | ||
46 | afs_server_trace_put_uuid_rsq, | ||
47 | afs_server_trace_update, | ||
48 | }; | ||
49 | |||
30 | enum afs_fs_operation { | 50 | enum afs_fs_operation { |
31 | afs_FS_FetchData = 130, /* AFS Fetch file data */ | 51 | afs_FS_FetchData = 130, /* AFS Fetch file data */ |
32 | afs_FS_FetchACL = 131, /* AFS Fetch file ACL */ | 52 | afs_FS_FetchACL = 131, /* AFS Fetch file ACL */ |
@@ -191,6 +211,17 @@ enum afs_flock_operation { | |||
191 | afs_flock_op_wake, | 211 | afs_flock_op_wake, |
192 | }; | 212 | }; |
193 | 213 | ||
214 | enum afs_cb_break_reason { | ||
215 | afs_cb_break_no_break, | ||
216 | afs_cb_break_for_callback, | ||
217 | afs_cb_break_for_deleted, | ||
218 | afs_cb_break_for_lapsed, | ||
219 | afs_cb_break_for_unlink, | ||
220 | afs_cb_break_for_vsbreak, | ||
221 | afs_cb_break_for_volume_callback, | ||
222 | afs_cb_break_for_zap, | ||
223 | }; | ||
224 | |||
194 | #endif /* end __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY */ | 225 | #endif /* end __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY */ |
195 | 226 | ||
196 | /* | 227 | /* |
@@ -204,6 +235,25 @@ enum afs_flock_operation { | |||
204 | EM(afs_call_trace_wake, "WAKE ") \ | 235 | EM(afs_call_trace_wake, "WAKE ") \ |
205 | E_(afs_call_trace_work, "WORK ") | 236 | E_(afs_call_trace_work, "WORK ") |
206 | 237 | ||
238 | #define afs_server_traces \ | ||
239 | EM(afs_server_trace_alloc, "ALLOC ") \ | ||
240 | EM(afs_server_trace_callback, "CALLBACK ") \ | ||
241 | EM(afs_server_trace_destroy, "DESTROY ") \ | ||
242 | EM(afs_server_trace_free, "FREE ") \ | ||
243 | EM(afs_server_trace_gc, "GC ") \ | ||
244 | EM(afs_server_trace_get_by_uuid, "GET uuid ") \ | ||
245 | EM(afs_server_trace_get_caps, "GET caps ") \ | ||
246 | EM(afs_server_trace_get_install, "GET inst ") \ | ||
247 | EM(afs_server_trace_get_new_cbi, "GET cbi ") \ | ||
248 | EM(afs_server_trace_give_up_cb, "giveup-cb") \ | ||
249 | EM(afs_server_trace_put_call, "PUT call ") \ | ||
250 | EM(afs_server_trace_put_cbi, "PUT cbi ") \ | ||
251 | EM(afs_server_trace_put_find_rsq, "PUT f-rsq") \ | ||
252 | EM(afs_server_trace_put_slist, "PUT slist") \ | ||
253 | EM(afs_server_trace_put_slist_isort, "PUT isort") \ | ||
254 | EM(afs_server_trace_put_uuid_rsq, "PUT u-req") \ | ||
255 | E_(afs_server_trace_update, "UPDATE") | ||
256 | |||
207 | #define afs_fs_operations \ | 257 | #define afs_fs_operations \ |
208 | EM(afs_FS_FetchData, "FS.FetchData") \ | 258 | EM(afs_FS_FetchData, "FS.FetchData") \ |
209 | EM(afs_FS_FetchStatus, "FS.FetchStatus") \ | 259 | EM(afs_FS_FetchStatus, "FS.FetchStatus") \ |
@@ -370,6 +420,16 @@ enum afs_flock_operation { | |||
370 | EM(afs_flock_op_unlock, "UNLOCK ") \ | 420 | EM(afs_flock_op_unlock, "UNLOCK ") \ |
371 | E_(afs_flock_op_wake, "WAKE ") | 421 | E_(afs_flock_op_wake, "WAKE ") |
372 | 422 | ||
423 | #define afs_cb_break_reasons \ | ||
424 | EM(afs_cb_break_no_break, "no-break") \ | ||
425 | EM(afs_cb_break_for_callback, "break-cb") \ | ||
426 | EM(afs_cb_break_for_deleted, "break-del") \ | ||
427 | EM(afs_cb_break_for_lapsed, "break-lapsed") \ | ||
428 | EM(afs_cb_break_for_unlink, "break-unlink") \ | ||
429 | EM(afs_cb_break_for_vsbreak, "break-vs") \ | ||
430 | EM(afs_cb_break_for_volume_callback, "break-v-cb") \ | ||
431 | E_(afs_cb_break_for_zap, "break-zap") | ||
432 | |||
373 | /* | 433 | /* |
374 | * Export enum symbols via userspace. | 434 | * Export enum symbols via userspace. |
375 | */ | 435 | */ |
@@ -379,6 +439,7 @@ enum afs_flock_operation { | |||
379 | #define E_(a, b) TRACE_DEFINE_ENUM(a); | 439 | #define E_(a, b) TRACE_DEFINE_ENUM(a); |
380 | 440 | ||
381 | afs_call_traces; | 441 | afs_call_traces; |
442 | afs_server_traces; | ||
382 | afs_fs_operations; | 443 | afs_fs_operations; |
383 | afs_vl_operations; | 444 | afs_vl_operations; |
384 | afs_edit_dir_ops; | 445 | afs_edit_dir_ops; |
@@ -388,6 +449,7 @@ afs_io_errors; | |||
388 | afs_file_errors; | 449 | afs_file_errors; |
389 | afs_flock_types; | 450 | afs_flock_types; |
390 | afs_flock_operations; | 451 | afs_flock_operations; |
452 | afs_cb_break_reasons; | ||
391 | 453 | ||
392 | /* | 454 | /* |
393 | * Now redefine the EM() and E_() macros to map the enums to the strings that | 455 | * Now redefine the EM() and E_() macros to map the enums to the strings that |
@@ -1167,6 +1229,76 @@ TRACE_EVENT(afs_get_tree, | |||
1167 | __entry->cell, __entry->volume, __entry->vid) | 1229 | __entry->cell, __entry->volume, __entry->vid) |
1168 | ); | 1230 | ); |
1169 | 1231 | ||
1232 | TRACE_EVENT(afs_cb_break, | ||
1233 | TP_PROTO(struct afs_fid *fid, unsigned int cb_break, | ||
1234 | enum afs_cb_break_reason reason, bool skipped), | ||
1235 | |||
1236 | TP_ARGS(fid, cb_break, reason, skipped), | ||
1237 | |||
1238 | TP_STRUCT__entry( | ||
1239 | __field_struct(struct afs_fid, fid ) | ||
1240 | __field(unsigned int, cb_break ) | ||
1241 | __field(enum afs_cb_break_reason, reason ) | ||
1242 | __field(bool, skipped ) | ||
1243 | ), | ||
1244 | |||
1245 | TP_fast_assign( | ||
1246 | __entry->fid = *fid; | ||
1247 | __entry->cb_break = cb_break; | ||
1248 | __entry->reason = reason; | ||
1249 | __entry->skipped = skipped; | ||
1250 | ), | ||
1251 | |||
1252 | TP_printk("%llx:%llx:%x b=%x s=%u %s", | ||
1253 | __entry->fid.vid, __entry->fid.vnode, __entry->fid.unique, | ||
1254 | __entry->cb_break, | ||
1255 | __entry->skipped, | ||
1256 | __print_symbolic(__entry->reason, afs_cb_break_reasons)) | ||
1257 | ); | ||
1258 | |||
1259 | TRACE_EVENT(afs_cb_miss, | ||
1260 | TP_PROTO(struct afs_fid *fid, enum afs_cb_break_reason reason), | ||
1261 | |||
1262 | TP_ARGS(fid, reason), | ||
1263 | |||
1264 | TP_STRUCT__entry( | ||
1265 | __field_struct(struct afs_fid, fid ) | ||
1266 | __field(enum afs_cb_break_reason, reason ) | ||
1267 | ), | ||
1268 | |||
1269 | TP_fast_assign( | ||
1270 | __entry->fid = *fid; | ||
1271 | __entry->reason = reason; | ||
1272 | ), | ||
1273 | |||
1274 | TP_printk(" %llx:%llx:%x %s", | ||
1275 | __entry->fid.vid, __entry->fid.vnode, __entry->fid.unique, | ||
1276 | __print_symbolic(__entry->reason, afs_cb_break_reasons)) | ||
1277 | ); | ||
1278 | |||
1279 | TRACE_EVENT(afs_server, | ||
1280 | TP_PROTO(struct afs_server *server, int usage, enum afs_server_trace reason), | ||
1281 | |||
1282 | TP_ARGS(server, usage, reason), | ||
1283 | |||
1284 | TP_STRUCT__entry( | ||
1285 | __field(unsigned int, server ) | ||
1286 | __field(int, usage ) | ||
1287 | __field(int, reason ) | ||
1288 | ), | ||
1289 | |||
1290 | TP_fast_assign( | ||
1291 | __entry->server = server->debug_id; | ||
1292 | __entry->usage = usage; | ||
1293 | __entry->reason = reason; | ||
1294 | ), | ||
1295 | |||
1296 | TP_printk("s=%08x %s u=%d", | ||
1297 | __entry->server, | ||
1298 | __print_symbolic(__entry->reason, afs_server_traces), | ||
1299 | __entry->usage) | ||
1300 | ); | ||
1301 | |||
1170 | #endif /* _TRACE_AFS_H */ | 1302 | #endif /* _TRACE_AFS_H */ |
1171 | 1303 | ||
1172 | /* This part must be outside protection */ | 1304 | /* This part must be outside protection */ |