diff options
author | Oleg Nesterov <oleg@redhat.com> | 2023-11-30 12:56:17 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2023-12-24 15:22:48 +0000 |
commit | df91b9dfdee23072641570b1efc049f19d839ae8 (patch) | |
tree | dcfa69ea62242d637ff7bf8b5fd32c00127a3af7 /fs/afs/inode.c | |
parent | 1702e0654ca9a7bcd7c7619c8a5004db58945b71 (diff) |
afs: use read_seqbegin() in afs_check_validity() and afs_getattr()
David Howells says:
(3) afs_check_validity().
(4) afs_getattr().
These are both pretty short, so your solution is probably good for them.
That said, afs_vnode_commit_status() can spend a long time under the
write lock - and pretty much every file RPC op returns a status update.
Change these functions to use read_seqbegin(). This simplifies the code
and doesn't change the current behaviour, the "seq" counter is always even
so read_seqbegin_or_lock() can never take the lock.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
Link: https://lore.kernel.org/r/20231130115617.GA21584@redhat.com/
Diffstat (limited to 'fs/afs/inode.c')
-rw-r--r-- | fs/afs/inode.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 78efc9719349..a6ae74d5b698 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -629,10 +629,10 @@ bool afs_check_validity(struct afs_vnode *vnode) enum afs_cb_break_reason need_clear = afs_cb_break_no_break; time64_t now = ktime_get_real_seconds(); unsigned int cb_break; - int seq = 0; + int seq; do { - read_seqbegin_or_lock(&vnode->cb_lock, &seq); + seq = read_seqbegin(&vnode->cb_lock); cb_break = vnode->cb_break; if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { @@ -650,9 +650,7 @@ bool afs_check_validity(struct afs_vnode *vnode) need_clear = afs_cb_break_no_promise; } - } while (need_seqretry(&vnode->cb_lock, seq)); - - done_seqretry(&vnode->cb_lock, seq); + } while (read_seqretry(&vnode->cb_lock, seq)); if (need_clear == afs_cb_break_no_break) return true; @@ -755,7 +753,7 @@ int afs_getattr(struct mnt_idmap *idmap, const struct path *path, struct inode *inode = d_inode(path->dentry); struct afs_vnode *vnode = AFS_FS_I(inode); struct key *key; - int ret, seq = 0; + int ret, seq; _enter("{ ino=%lu v=%u }", inode->i_ino, inode->i_generation); @@ -772,7 +770,7 @@ int afs_getattr(struct mnt_idmap *idmap, const struct path *path, } do { - read_seqbegin_or_lock(&vnode->cb_lock, &seq); + seq = read_seqbegin(&vnode->cb_lock); generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat); if (test_bit(AFS_VNODE_SILLY_DELETED, &vnode->flags) && stat->nlink > 0) @@ -784,9 +782,8 @@ int afs_getattr(struct mnt_idmap *idmap, const struct path *path, */ if (S_ISDIR(inode->i_mode)) stat->size = vnode->netfs.remote_i_size; - } while (need_seqretry(&vnode->cb_lock, seq)); + } while (read_seqretry(&vnode->cb_lock, seq)); - done_seqretry(&vnode->cb_lock, seq); return 0; } |