diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-06 02:26:36 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-06 02:26:36 +0300 |
commit | 9daa0a27a0bce6596be287fb1df372ff80bb1087 (patch) | |
tree | 0dae8f626d71339d79131a3f664abbe36547c5da /include | |
parent | 0b166a57e6222666292a481b742af92b50c3ba50 (diff) | |
parent | 8409f67b6437c4b327ee95a71081b9c7bfee0b00 (diff) | |
download | linux-9daa0a27a0bce6596be287fb1df372ff80bb1087.tar.xz |
Merge tag 'afs-next-20200604' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull AFS updates from David Howells:
"There's some core VFS changes which affect a couple of filesystems:
- Make the inode hash table RCU safe and providing some RCU-safe
accessor functions. The search can then be done without taking the
inode_hash_lock. Care must be taken because the object may be being
deleted and no wait is made.
- Allow iunique() to avoid taking the inode_hash_lock.
- Allow AFS's callback processing to avoid taking the inode_hash_lock
when using the inode table to find an inode to notify.
- Improve Ext4's time updating. Konstantin Khlebnikov said "For now,
I've plugged this issue with try-lock in ext4 lazy time update.
This solution is much better."
Then there's a set of changes to make a number of improvements to the
AFS driver:
- Improve callback (ie. third party change notification) processing
by:
(a) Relying more on the fact we're doing this under RCU and by
using fewer locks. This makes use of the RCU-based inode
searching outlined above.
(b) Moving to keeping volumes in a tree indexed by volume ID
rather than a flat list.
(c) Making the server and volume records logically part of the
cell. This means that a server record now points directly at
the cell and the tree of volumes is there. This removes an N:M
mapping table, simplifying things.
- Improve keeping NAT or firewall channels open for the server
callbacks to reach the client by actively polling the fileserver on
a timed basis, instead of only doing it when we have an operation
to process.
- Improving detection of delayed or lost callbacks by including the
parent directory in the list of file IDs to be queried when doing a
bulk status fetch from lookup. We can then check to see if our copy
of the directory has changed under us without us getting notified.
- Determine aliasing of cells (such as a cell that is pointed to be a
DNS alias). This allows us to avoid having ambiguity due to
apparently different cells using the same volume and file servers.
- Improve the fileserver rotation to do more probing when it detects
that all of the addresses to a server are listed as non-responsive.
It's possible that an address that previously stopped responding
has become responsive again.
Beyond that, lay some foundations for making some calls asynchronous:
- Turn the fileserver cursor struct into a general operation struct
and hang the parameters off of that rather than keeping them in
local variables and hang results off of that rather than the call
struct.
- Implement some general operation handling code and simplify the
callers of operations that affect a volume or a volume component
(such as a file). Most of the operation is now done by core code.
- Operations are supplied with a table of operations to issue
different variants of RPCs and to manage the completion, where all
the required data is held in the operation object, thereby allowing
these to be called from a workqueue.
- Put the standard "if (begin), while(select), call op, end" sequence
into a canned function that just emulates the current behaviour for
now.
There are also some fixes interspersed:
- Don't let the EACCES from ICMP6 mapping reach the user as such,
since it's confusing as to whether it's a filesystem error. Convert
it to EHOSTUNREACH.
- Don't use the epoch value acquired through probing a server. If we
have two servers with the same UUID but in different cells, it's
hard to draw conclusions from them having different epoch values.
- Don't interpret the argument to the CB.ProbeUuid RPC as a
fileserver UUID and look up a fileserver from it.
- Deal with servers in different cells having the same UUIDs. In the
event that a CB.InitCallBackState3 RPC is received, we have to
break the callback promises for every server record matching that
UUID.
- Don't let afs_statfs return values that go below 0.
- Don't use running fileserver probe state to make server selection
and address selection decisions on. Only make decisions on final
state as the running state is cleared at the start of probing"
Acked-by: Al Viro <viro@zeniv.linux.org.uk> (fs/inode.c part)
* tag 'afs-next-20200604' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: (27 commits)
afs: Adjust the fileserver rotation algorithm to reprobe/retry more quickly
afs: Show more a bit more server state in /proc/net/afs/servers
afs: Don't use probe running state to make decisions outside probe code
afs: Fix afs_statfs() to not let the values go below zero
afs: Fix the by-UUID server tree to allow servers with the same UUID
afs: Reorganise volume and server trees to be rooted on the cell
afs: Add a tracepoint to track the lifetime of the afs_volume struct
afs: Detect cell aliases 3 - YFS Cells with a canonical cell name op
afs: Detect cell aliases 2 - Cells with no root volumes
afs: Detect cell aliases 1 - Cells with root volumes
afs: Implement client support for the YFSVL.GetCellName RPC op
afs: Retain more of the VLDB record for alias detection
afs: Fix handling of CB.ProbeUuid cache manager op
afs: Don't get epoch from a server because it may be ambiguous
afs: Build an abstraction around an "operation" concept
afs: Rename struct afs_fs_cursor to afs_operation
afs: Remove the error argument from afs_protocol_error()
afs: Set error flag rather than return error from file status decode
afs: Make callback processing more efficient.
afs: Show more information in /proc/net/afs/servers
...
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/fs.h | 3 | ||||
-rw-r--r-- | include/trace/events/afs.h | 111 |
2 files changed, 91 insertions, 23 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index bb0acc7e86d8..01f5d296f9bb 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3081,6 +3081,9 @@ extern struct inode *find_inode_nowait(struct super_block *, int (*match)(struct inode *, unsigned long, void *), void *data); +extern struct inode *find_inode_rcu(struct super_block *, unsigned long, + int (*)(struct inode *, void *), void *); +extern struct inode *find_inode_by_ino_rcu(struct super_block *, unsigned long); extern int insert_inode_locked4(struct inode *, unsigned long, int (*test)(struct inode *, void *), void *); extern int insert_inode_locked(struct inode *); #ifdef CONFIG_DEBUG_LOCK_ALLOC diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h index c612cabbc378..5f0c1cf1ea13 100644 --- a/include/trace/events/afs.h +++ b/include/trace/events/afs.h @@ -33,20 +33,40 @@ enum afs_server_trace { afs_server_trace_destroy, afs_server_trace_free, afs_server_trace_gc, + afs_server_trace_get_by_addr, 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_get_probe, 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_probe, afs_server_trace_put_slist, afs_server_trace_put_slist_isort, afs_server_trace_put_uuid_rsq, afs_server_trace_update, }; +enum afs_volume_trace { + afs_volume_trace_alloc, + afs_volume_trace_free, + afs_volume_trace_get_alloc_sbi, + afs_volume_trace_get_cell_insert, + afs_volume_trace_get_new_op, + afs_volume_trace_get_query_alias, + afs_volume_trace_put_cell_dup, + afs_volume_trace_put_cell_root, + afs_volume_trace_put_destroy_sbi, + afs_volume_trace_put_free_fc, + afs_volume_trace_put_put_op, + afs_volume_trace_put_query_alias, + afs_volume_trace_put_validate_fc, + afs_volume_trace_remove, +}; + enum afs_fs_operation { afs_FS_FetchData = 130, /* AFS Fetch file data */ afs_FS_FetchACL = 131, /* AFS Fetch file ACL */ @@ -108,6 +128,7 @@ enum afs_vl_operation { afs_VL_GetEntryByNameU = 527, /* AFS Get Vol Entry By Name operation ID */ afs_VL_GetAddrsU = 533, /* AFS Get FS server addresses */ afs_YFSVL_GetEndpoints = 64002, /* YFS Get FS & Vol server addresses */ + afs_YFSVL_GetCellName = 64014, /* YFS Get actual cell name */ afs_VL_GetCapabilities = 65537, /* AFS Get VL server capabilities */ }; @@ -140,6 +161,7 @@ enum afs_eproto_cause { afs_eproto_bad_status, afs_eproto_cb_count, afs_eproto_cb_fid_count, + afs_eproto_cellname_len, afs_eproto_file_type, afs_eproto_ibulkst_cb_count, afs_eproto_ibulkst_count, @@ -241,19 +263,38 @@ enum afs_cb_break_reason { EM(afs_server_trace_destroy, "DESTROY ") \ EM(afs_server_trace_free, "FREE ") \ EM(afs_server_trace_gc, "GC ") \ + EM(afs_server_trace_get_by_addr, "GET addr ") \ 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_get_probe, "GET probe") \ 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_probe, "PUT probe") \ 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_volume_traces \ + EM(afs_volume_trace_alloc, "ALLOC ") \ + EM(afs_volume_trace_free, "FREE ") \ + EM(afs_volume_trace_get_alloc_sbi, "GET sbi-alloc ") \ + EM(afs_volume_trace_get_cell_insert, "GET cell-insrt") \ + EM(afs_volume_trace_get_new_op, "GET op-new ") \ + EM(afs_volume_trace_get_query_alias, "GET cell-alias") \ + EM(afs_volume_trace_put_cell_dup, "PUT cell-dup ") \ + EM(afs_volume_trace_put_cell_root, "PUT cell-root ") \ + EM(afs_volume_trace_put_destroy_sbi, "PUT sbi-destry") \ + EM(afs_volume_trace_put_free_fc, "PUT fc-free ") \ + EM(afs_volume_trace_put_put_op, "PUT op-put ") \ + EM(afs_volume_trace_put_query_alias, "PUT cell-alias") \ + EM(afs_volume_trace_put_validate_fc, "PUT fc-validat") \ + E_(afs_volume_trace_remove, "REMOVE ") + #define afs_fs_operations \ EM(afs_FS_FetchData, "FS.FetchData") \ EM(afs_FS_FetchStatus, "FS.FetchStatus") \ @@ -310,6 +351,7 @@ enum afs_cb_break_reason { EM(afs_VL_GetEntryByNameU, "VL.GetEntryByNameU") \ EM(afs_VL_GetAddrsU, "VL.GetAddrsU") \ EM(afs_YFSVL_GetEndpoints, "YFSVL.GetEndpoints") \ + EM(afs_YFSVL_GetCellName, "YFSVL.GetCellName") \ E_(afs_VL_GetCapabilities, "VL.GetCapabilities") #define afs_edit_dir_ops \ @@ -339,6 +381,7 @@ enum afs_cb_break_reason { EM(afs_eproto_bad_status, "BadStatus") \ EM(afs_eproto_cb_count, "CbCount") \ EM(afs_eproto_cb_fid_count, "CbFidCount") \ + EM(afs_eproto_cellname_len, "CellNameLen") \ EM(afs_eproto_file_type, "FileTYpe") \ EM(afs_eproto_ibulkst_cb_count, "IBS.CbCount") \ EM(afs_eproto_ibulkst_count, "IBS.FidCount") \ @@ -636,7 +679,7 @@ TRACE_EVENT(afs_make_fs_calli, TRACE_EVENT(afs_make_fs_call1, TP_PROTO(struct afs_call *call, const struct afs_fid *fid, - const char *name), + const struct qstr *name), TP_ARGS(call, fid, name), @@ -648,8 +691,7 @@ TRACE_EVENT(afs_make_fs_call1, ), TP_fast_assign( - int __len = strlen(name); - __len = min(__len, 23); + unsigned int __len = min_t(unsigned int, name->len, 23); __entry->call = call->debug_id; __entry->op = call->operation_ID; if (fid) { @@ -659,7 +701,7 @@ TRACE_EVENT(afs_make_fs_call1, __entry->fid.vnode = 0; __entry->fid.unique = 0; } - memcpy(__entry->name, name, __len); + memcpy(__entry->name, name->name, __len); __entry->name[__len] = 0; ), @@ -674,7 +716,7 @@ TRACE_EVENT(afs_make_fs_call1, TRACE_EVENT(afs_make_fs_call2, TP_PROTO(struct afs_call *call, const struct afs_fid *fid, - const char *name, const char *name2), + const struct qstr *name, const struct qstr *name2), TP_ARGS(call, fid, name, name2), @@ -687,10 +729,8 @@ TRACE_EVENT(afs_make_fs_call2, ), TP_fast_assign( - int __len = strlen(name); - int __len2 = strlen(name2); - __len = min(__len, 23); - __len2 = min(__len2, 23); + unsigned int __len = min_t(unsigned int, name->len, 23); + unsigned int __len2 = min_t(unsigned int, name2->len, 23); __entry->call = call->debug_id; __entry->op = call->operation_ID; if (fid) { @@ -700,9 +740,9 @@ TRACE_EVENT(afs_make_fs_call2, __entry->fid.vnode = 0; __entry->fid.unique = 0; } - memcpy(__entry->name, name, __len); + memcpy(__entry->name, name->name, __len); __entry->name[__len] = 0; - memcpy(__entry->name2, name2, __len2); + memcpy(__entry->name2, name2->name, __len2); __entry->name2[__len2] = 0; ), @@ -988,24 +1028,22 @@ TRACE_EVENT(afs_edit_dir, ); TRACE_EVENT(afs_protocol_error, - TP_PROTO(struct afs_call *call, int error, enum afs_eproto_cause cause), + TP_PROTO(struct afs_call *call, enum afs_eproto_cause cause), - TP_ARGS(call, error, cause), + TP_ARGS(call, cause), TP_STRUCT__entry( __field(unsigned int, call ) - __field(int, error ) __field(enum afs_eproto_cause, cause ) ), TP_fast_assign( __entry->call = call ? call->debug_id : 0; - __entry->error = error; __entry->cause = cause; ), - TP_printk("c=%08x r=%d %s", - __entry->call, __entry->error, + TP_printk("c=%08x %s", + __entry->call, __print_symbolic(__entry->cause, afs_eproto_causes)) ); @@ -1271,26 +1309,53 @@ TRACE_EVENT(afs_cb_miss, ); TRACE_EVENT(afs_server, - TP_PROTO(struct afs_server *server, int usage, enum afs_server_trace reason), + TP_PROTO(struct afs_server *server, int ref, int active, + enum afs_server_trace reason), - TP_ARGS(server, usage, reason), + TP_ARGS(server, ref, active, reason), TP_STRUCT__entry( __field(unsigned int, server ) - __field(int, usage ) + __field(int, ref ) + __field(int, active ) __field(int, reason ) ), TP_fast_assign( __entry->server = server->debug_id; - __entry->usage = usage; + __entry->ref = ref; + __entry->active = active; __entry->reason = reason; ), - TP_printk("s=%08x %s u=%d", + TP_printk("s=%08x %s u=%d a=%d", __entry->server, __print_symbolic(__entry->reason, afs_server_traces), - __entry->usage) + __entry->ref, + __entry->active) + ); + +TRACE_EVENT(afs_volume, + TP_PROTO(afs_volid_t vid, int ref, enum afs_volume_trace reason), + + TP_ARGS(vid, ref, reason), + + TP_STRUCT__entry( + __field(afs_volid_t, vid ) + __field(int, ref ) + __field(enum afs_volume_trace, reason ) + ), + + TP_fast_assign( + __entry->vid = vid; + __entry->ref = ref; + __entry->reason = reason; + ), + + TP_printk("V=%llx %s u=%d", + __entry->vid, + __print_symbolic(__entry->reason, afs_volume_traces), + __entry->ref) ); #endif /* _TRACE_AFS_H */ |