From 358585a8c185b7c9579a89e8501d05043863b5be Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 4 Mar 2024 12:34:00 +0100 Subject: [PATCH] 6.1-stable patches added patches: exportfs-use-pr_debug-for-unreachable-debug-statements.patch filelock-add-a-new-locks_inode_context-accessor-function.patch lockd-ensure-we-use-the-correct-file-descriptor-when-unlocking.patch lockd-fix-file-selection-in-nlmsvc_cancel_blocked.patch lockd-set-missing-fl_flags-field-when-retrieving-args.patch lockd-use-locks_inode_context-helper.patch nfsd-add-a-nfsd4_file_hash_remove-helper.patch nfsd-add-cb_recall_any-tracepoints.patch nfsd-add-delegation-reaper-to-react-to-low-memory-condition.patch nfsd-add-support-for-sending-cb_recall_any.patch nfsd-allow-disabling-nfsv2-at-compile-time.patch nfsd-avoid-clashing-function-prototypes.patch nfsd-clean-up-find_or_add_file.patch nfsd-clean-up-nfs4_preprocess_stateid_op-call-sites.patch nfsd-clean-up-nfsd4_init_file.patch nfsd-don-t-destroy-global-nfs4_file-table-in-per-net-shutdown.patch nfsd-fix-licensing-header-in-filecache.c.patch nfsd-fix-up-the-filecache-laundrette-scheduling.patch nfsd-flesh-out-a-documenting-comment-for-filecache.c.patch nfsd-ignore-requests-to-disable-unsupported-versions.patch nfsd-move-nfserrno-to-vfs.c.patch nfsd-refactor-find_file.patch nfsd-refactoring-courtesy_client_reaper-to-a-generic-low-memory-shrinker.patch nfsd-register-unregister-of-nfsd-client-shrinker-at-nfsd-startup-shutdown-time.patch nfsd-remove-redundant-assignment-to-variable-host_err.patch nfsd-replace-delayed_work-with-work_struct-for-nfsd_client_shrinker.patch nfsd-simplify-read_plus.patch nfsd-trace-delegation-revocations.patch nfsd-trace-stateids-returned-via-delegreturn.patch nfsd-update-file_hashtbl-helpers.patch nfsd-use-const-pointers-as-parameters-to-fh_-helpers.patch nfsd-use-locks_inode_context-helper.patch nfsd-use-only-rq_dropme-to-signal-the-need-to-drop-a-reply.patch nfsd-use-rhashtable-for-managing-nfs4_file-objects.patch nfsd-use-set_bit-rq_dropme.patch nfsd-use-struct_size-helper-in-alloc_session.patch trace-relocate-event-helper-files.patch --- ...bug-for-unreachable-debug-statements.patch | 55 + ...ocks_inode_context-accessor-function.patch | 168 ++ ...rrect-file-descriptor-when-unlocking.patch | 40 + ...e-selection-in-nlmsvc_cancel_blocked.patch | 38 + ...-fl_flags-field-when-retrieving-args.patch | 37 + ...lockd-use-locks_inode_context-helper.patch | 44 + ...-add-a-nfsd4_file_hash_remove-helper.patch | 61 + .../nfsd-add-cb_recall_any-tracepoints.patch | 136 ++ ...per-to-react-to-low-memory-condition.patch | 204 +++ ...dd-support-for-sending-cb_recall_any.patch | 165 ++ ...llow-disabling-nfsv2-at-compile-time.patch | 143 ++ ...d-avoid-clashing-function-prototypes.patch | 1529 ++++++++++++++++ .../nfsd-clean-up-find_or_add_file.patch | 123 ++ ...fs4_preprocess_stateid_op-call-sites.patch | 106 ++ queue-6.1/nfsd-clean-up-nfsd4_init_file.patch | 61 + ...-nfs4_file-table-in-per-net-shutdown.patch | 42 + ...-fix-licensing-header-in-filecache.c.patch | 29 + ...-the-filecache-laundrette-scheduling.patch | 53 + ...-documenting-comment-for-filecache.c.patch | 54 + ...ests-to-disable-unsupported-versions.patch | 35 + queue-6.1/nfsd-move-nfserrno-to-vfs.c.patch | 231 +++ queue-6.1/nfsd-refactor-find_file.patch | 80 + ...per-to-a-generic-low-memory-shrinker.patch | 88 + ...rinker-at-nfsd-startup-shutdown-time.patch | 136 ++ ...dant-assignment-to-variable-host_err.patch | 34 + ...work_struct-for-nfsd_client_shrinker.patch | 74 + queue-6.1/nfsd-simplify-read_plus.patch | 205 +++ .../nfsd-trace-delegation-revocations.patch | 103 ++ ...ce-stateids-returned-via-delegreturn.patch | 42 + .../nfsd-update-file_hashtbl-helpers.patch | 40 + ...ointers-as-parameters-to-fh_-helpers.patch | 61 + .../nfsd-use-locks_inode_context-helper.patch | 51 + ...e-to-signal-the-need-to-drop-a-reply.patch | 53 + ...table-for-managing-nfs4_file-objects.patch | 244 +++ queue-6.1/nfsd-use-set_bit-rq_dropme.patch | 41 + ...-struct_size-helper-in-alloc_session.patch | 39 + queue-6.1/series | 37 + .../trace-relocate-event-helper-files.patch | 1559 +++++++++++++++++ 38 files changed, 6241 insertions(+) create mode 100644 queue-6.1/exportfs-use-pr_debug-for-unreachable-debug-statements.patch create mode 100644 queue-6.1/filelock-add-a-new-locks_inode_context-accessor-function.patch create mode 100644 queue-6.1/lockd-ensure-we-use-the-correct-file-descriptor-when-unlocking.patch create mode 100644 queue-6.1/lockd-fix-file-selection-in-nlmsvc_cancel_blocked.patch create mode 100644 queue-6.1/lockd-set-missing-fl_flags-field-when-retrieving-args.patch create mode 100644 queue-6.1/lockd-use-locks_inode_context-helper.patch create mode 100644 queue-6.1/nfsd-add-a-nfsd4_file_hash_remove-helper.patch create mode 100644 queue-6.1/nfsd-add-cb_recall_any-tracepoints.patch create mode 100644 queue-6.1/nfsd-add-delegation-reaper-to-react-to-low-memory-condition.patch create mode 100644 queue-6.1/nfsd-add-support-for-sending-cb_recall_any.patch create mode 100644 queue-6.1/nfsd-allow-disabling-nfsv2-at-compile-time.patch create mode 100644 queue-6.1/nfsd-avoid-clashing-function-prototypes.patch create mode 100644 queue-6.1/nfsd-clean-up-find_or_add_file.patch create mode 100644 queue-6.1/nfsd-clean-up-nfs4_preprocess_stateid_op-call-sites.patch create mode 100644 queue-6.1/nfsd-clean-up-nfsd4_init_file.patch create mode 100644 queue-6.1/nfsd-don-t-destroy-global-nfs4_file-table-in-per-net-shutdown.patch create mode 100644 queue-6.1/nfsd-fix-licensing-header-in-filecache.c.patch create mode 100644 queue-6.1/nfsd-fix-up-the-filecache-laundrette-scheduling.patch create mode 100644 queue-6.1/nfsd-flesh-out-a-documenting-comment-for-filecache.c.patch create mode 100644 queue-6.1/nfsd-ignore-requests-to-disable-unsupported-versions.patch create mode 100644 queue-6.1/nfsd-move-nfserrno-to-vfs.c.patch create mode 100644 queue-6.1/nfsd-refactor-find_file.patch create mode 100644 queue-6.1/nfsd-refactoring-courtesy_client_reaper-to-a-generic-low-memory-shrinker.patch create mode 100644 queue-6.1/nfsd-register-unregister-of-nfsd-client-shrinker-at-nfsd-startup-shutdown-time.patch create mode 100644 queue-6.1/nfsd-remove-redundant-assignment-to-variable-host_err.patch create mode 100644 queue-6.1/nfsd-replace-delayed_work-with-work_struct-for-nfsd_client_shrinker.patch create mode 100644 queue-6.1/nfsd-simplify-read_plus.patch create mode 100644 queue-6.1/nfsd-trace-delegation-revocations.patch create mode 100644 queue-6.1/nfsd-trace-stateids-returned-via-delegreturn.patch create mode 100644 queue-6.1/nfsd-update-file_hashtbl-helpers.patch create mode 100644 queue-6.1/nfsd-use-const-pointers-as-parameters-to-fh_-helpers.patch create mode 100644 queue-6.1/nfsd-use-locks_inode_context-helper.patch create mode 100644 queue-6.1/nfsd-use-only-rq_dropme-to-signal-the-need-to-drop-a-reply.patch create mode 100644 queue-6.1/nfsd-use-rhashtable-for-managing-nfs4_file-objects.patch create mode 100644 queue-6.1/nfsd-use-set_bit-rq_dropme.patch create mode 100644 queue-6.1/nfsd-use-struct_size-helper-in-alloc_session.patch create mode 100644 queue-6.1/trace-relocate-event-helper-files.patch diff --git a/queue-6.1/exportfs-use-pr_debug-for-unreachable-debug-statements.patch b/queue-6.1/exportfs-use-pr_debug-for-unreachable-debug-statements.patch new file mode 100644 index 00000000000..0cc7381935a --- /dev/null +++ b/queue-6.1/exportfs-use-pr_debug-for-unreachable-debug-statements.patch @@ -0,0 +1,55 @@ +From db11de653c2fdd198722c6647c23d8ecbf2dc80a Mon Sep 17 00:00:00 2001 +From: David Disseldorp +Date: Fri, 21 Oct 2022 14:24:14 +0200 +Subject: exportfs: use pr_debug for unreachable debug statements + +From: David Disseldorp + +[ Upstream commit 427505ffeaa464f683faba945a88d3e3248f6979 ] + +expfs.c has a bunch of dprintk statements which are unusable due to: + #define dprintk(fmt, args...) do{}while(0) +Use pr_debug so that they can be enabled dynamically. +Also make some minor changes to the debug statements to fix some +incorrect types, and remove __func__ which can be handled by dynamic +debug separately. + +Signed-off-by: David Disseldorp +Reviewed-by: NeilBrown +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/exportfs/expfs.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/exportfs/expfs.c ++++ b/fs/exportfs/expfs.c +@@ -18,7 +18,7 @@ + #include + #include + +-#define dprintk(fmt, args...) do{}while(0) ++#define dprintk(fmt, args...) pr_debug(fmt, ##args) + + + static int get_name(const struct path *path, char *name, struct dentry *child); +@@ -132,8 +132,8 @@ static struct dentry *reconnect_one(stru + inode_unlock(dentry->d_inode); + + if (IS_ERR(parent)) { +- dprintk("%s: get_parent of %ld failed, err %d\n", +- __func__, dentry->d_inode->i_ino, PTR_ERR(parent)); ++ dprintk("get_parent of %lu failed, err %ld\n", ++ dentry->d_inode->i_ino, PTR_ERR(parent)); + return parent; + } + +@@ -147,7 +147,7 @@ static struct dentry *reconnect_one(stru + dprintk("%s: found name: %s\n", __func__, nbuf); + tmp = lookup_one_unlocked(mnt_user_ns(mnt), nbuf, parent, strlen(nbuf)); + if (IS_ERR(tmp)) { +- dprintk("%s: lookup failed: %d\n", __func__, PTR_ERR(tmp)); ++ dprintk("lookup failed: %ld\n", PTR_ERR(tmp)); + err = PTR_ERR(tmp); + goto out_err; + } diff --git a/queue-6.1/filelock-add-a-new-locks_inode_context-accessor-function.patch b/queue-6.1/filelock-add-a-new-locks_inode_context-accessor-function.patch new file mode 100644 index 00000000000..48e2b93dbbe --- /dev/null +++ b/queue-6.1/filelock-add-a-new-locks_inode_context-accessor-function.patch @@ -0,0 +1,168 @@ +From 5c8dcb0ee71e3d832d3f7b67bcf369fc206fed1a Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Wed, 16 Nov 2022 09:02:30 -0500 +Subject: filelock: add a new locks_inode_context accessor function + +From: Jeff Layton + +[ Upstream commit 401a8b8fd5acd51582b15238d72a8d0edd580e9f ] + +There are a number of places in the kernel that are accessing the +inode->i_flctx field without smp_load_acquire. This is required to +ensure that the caller doesn't see a partially-initialized structure. + +Add a new accessor function for it to make this clear and convert all of +the relevant accesses in locks.c to use it. Also, convert +locks_free_lock_context to use the helper as well instead of just doing +a "bare" assignment. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Jeff Layton +Stable-dep-of: 77c67530e1f9 ("nfsd: use locks_inode_context helper") +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/locks.c | 24 ++++++++++++------------ + include/linux/fs.h | 14 ++++++++++++++ + 2 files changed, 26 insertions(+), 12 deletions(-) + +--- a/fs/locks.c ++++ b/fs/locks.c +@@ -175,7 +175,7 @@ locks_get_lock_context(struct inode *ino + struct file_lock_context *ctx; + + /* paired with cmpxchg() below */ +- ctx = smp_load_acquire(&inode->i_flctx); ++ ctx = locks_inode_context(inode); + if (likely(ctx) || type == F_UNLCK) + goto out; + +@@ -194,7 +194,7 @@ locks_get_lock_context(struct inode *ino + */ + if (cmpxchg(&inode->i_flctx, NULL, ctx)) { + kmem_cache_free(flctx_cache, ctx); +- ctx = smp_load_acquire(&inode->i_flctx); ++ ctx = locks_inode_context(inode); + } + out: + trace_locks_get_lock_context(inode, type, ctx); +@@ -247,7 +247,7 @@ locks_check_ctx_file_list(struct file *f + void + locks_free_lock_context(struct inode *inode) + { +- struct file_lock_context *ctx = inode->i_flctx; ++ struct file_lock_context *ctx = locks_inode_context(inode); + + if (unlikely(ctx)) { + locks_check_ctx_lists(inode); +@@ -891,7 +891,7 @@ posix_test_lock(struct file *filp, struc + void *owner; + void (*func)(void); + +- ctx = smp_load_acquire(&inode->i_flctx); ++ ctx = locks_inode_context(inode); + if (!ctx || list_empty_careful(&ctx->flc_posix)) { + fl->fl_type = F_UNLCK; + return; +@@ -1483,7 +1483,7 @@ int __break_lease(struct inode *inode, u + new_fl->fl_flags = type; + + /* typically we will check that ctx is non-NULL before calling */ +- ctx = smp_load_acquire(&inode->i_flctx); ++ ctx = locks_inode_context(inode); + if (!ctx) { + WARN_ON_ONCE(1); + goto free_lock; +@@ -1588,7 +1588,7 @@ void lease_get_mtime(struct inode *inode + struct file_lock_context *ctx; + struct file_lock *fl; + +- ctx = smp_load_acquire(&inode->i_flctx); ++ ctx = locks_inode_context(inode); + if (ctx && !list_empty_careful(&ctx->flc_lease)) { + spin_lock(&ctx->flc_lock); + fl = list_first_entry_or_null(&ctx->flc_lease, +@@ -1634,7 +1634,7 @@ int fcntl_getlease(struct file *filp) + int type = F_UNLCK; + LIST_HEAD(dispose); + +- ctx = smp_load_acquire(&inode->i_flctx); ++ ctx = locks_inode_context(inode); + if (ctx && !list_empty_careful(&ctx->flc_lease)) { + percpu_down_read(&file_rwsem); + spin_lock(&ctx->flc_lock); +@@ -1823,7 +1823,7 @@ static int generic_delete_lease(struct f + struct file_lock_context *ctx; + LIST_HEAD(dispose); + +- ctx = smp_load_acquire(&inode->i_flctx); ++ ctx = locks_inode_context(inode); + if (!ctx) { + trace_generic_delete_lease(inode, NULL); + return error; +@@ -2562,7 +2562,7 @@ void locks_remove_posix(struct file *fil + * posix_lock_file(). Another process could be setting a lock on this + * file at the same time, but we wouldn't remove that lock anyway. + */ +- ctx = smp_load_acquire(&inode->i_flctx); ++ ctx = locks_inode_context(inode); + if (!ctx || list_empty(&ctx->flc_posix)) + return; + +@@ -2635,7 +2635,7 @@ void locks_remove_file(struct file *filp + { + struct file_lock_context *ctx; + +- ctx = smp_load_acquire(&locks_inode(filp)->i_flctx); ++ ctx = locks_inode_context(locks_inode(filp)); + if (!ctx) + return; + +@@ -2682,7 +2682,7 @@ bool vfs_inode_has_locks(struct inode *i + struct file_lock_context *ctx; + bool ret; + +- ctx = smp_load_acquire(&inode->i_flctx); ++ ctx = locks_inode_context(inode); + if (!ctx) + return false; + +@@ -2863,7 +2863,7 @@ void show_fd_locks(struct seq_file *f, + struct file_lock_context *ctx; + int id = 0; + +- ctx = smp_load_acquire(&inode->i_flctx); ++ ctx = locks_inode_context(inode); + if (!ctx) + return; + +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1189,6 +1189,13 @@ extern void show_fd_locks(struct seq_fil + struct file *filp, struct files_struct *files); + extern bool locks_owner_has_blockers(struct file_lock_context *flctx, + fl_owner_t owner); ++ ++static inline struct file_lock_context * ++locks_inode_context(const struct inode *inode) ++{ ++ return smp_load_acquire(&inode->i_flctx); ++} ++ + #else /* !CONFIG_FILE_LOCKING */ + static inline int fcntl_getlk(struct file *file, unsigned int cmd, + struct flock __user *user) +@@ -1334,6 +1341,13 @@ static inline bool locks_owner_has_block + { + return false; + } ++ ++static inline struct file_lock_context * ++locks_inode_context(const struct inode *inode) ++{ ++ return NULL; ++} ++ + #endif /* !CONFIG_FILE_LOCKING */ + + static inline struct inode *file_inode(const struct file *f) diff --git a/queue-6.1/lockd-ensure-we-use-the-correct-file-descriptor-when-unlocking.patch b/queue-6.1/lockd-ensure-we-use-the-correct-file-descriptor-when-unlocking.patch new file mode 100644 index 00000000000..b3aff36ae56 --- /dev/null +++ b/queue-6.1/lockd-ensure-we-use-the-correct-file-descriptor-when-unlocking.patch @@ -0,0 +1,40 @@ +From f9d843598ec499abdb2f040a1c6665cfc7ab1b87 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Fri, 11 Nov 2022 14:36:37 -0500 +Subject: lockd: ensure we use the correct file descriptor when unlocking + +From: Jeff Layton + +[ Upstream commit 69efce009f7df888e1fede3cb2913690eb829f52 ] + +Shared locks are set on O_RDONLY descriptors and exclusive locks are set +on O_WRONLY ones. nlmsvc_unlock however calls vfs_lock_file twice, once +for each descriptor, but it doesn't reset fl_file. Ensure that it does. + +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/lockd/svclock.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/fs/lockd/svclock.c ++++ b/fs/lockd/svclock.c +@@ -659,11 +659,13 @@ nlmsvc_unlock(struct net *net, struct nl + nlmsvc_cancel_blocked(net, file, lock); + + lock->fl.fl_type = F_UNLCK; +- if (file->f_file[O_RDONLY]) +- error = vfs_lock_file(file->f_file[O_RDONLY], F_SETLK, ++ lock->fl.fl_file = file->f_file[O_RDONLY]; ++ if (lock->fl.fl_file) ++ error = vfs_lock_file(lock->fl.fl_file, F_SETLK, + &lock->fl, NULL); +- if (file->f_file[O_WRONLY]) +- error = vfs_lock_file(file->f_file[O_WRONLY], F_SETLK, ++ lock->fl.fl_file = file->f_file[O_WRONLY]; ++ if (lock->fl.fl_file) ++ error |= vfs_lock_file(lock->fl.fl_file, F_SETLK, + &lock->fl, NULL); + + return (error < 0)? nlm_lck_denied_nolocks : nlm_granted; diff --git a/queue-6.1/lockd-fix-file-selection-in-nlmsvc_cancel_blocked.patch b/queue-6.1/lockd-fix-file-selection-in-nlmsvc_cancel_blocked.patch new file mode 100644 index 00000000000..3ea46ad2b52 --- /dev/null +++ b/queue-6.1/lockd-fix-file-selection-in-nlmsvc_cancel_blocked.patch @@ -0,0 +1,38 @@ +From fdf4fd6f05ae4659354de48f42dcee40eb4405dd Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Fri, 11 Nov 2022 14:36:38 -0500 +Subject: lockd: fix file selection in nlmsvc_cancel_blocked + +From: Jeff Layton + +[ Upstream commit 9f27783b4dd235ef3c8dbf69fc6322777450323c ] + +We currently do a lock_to_openmode call based on the arguments from the +NLM_UNLOCK call, but that will always set the fl_type of the lock to +F_UNLCK, and the O_RDONLY descriptor is always chosen. + +Fix it to use the file_lock from the block instead. + +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/lockd/svclock.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/fs/lockd/svclock.c ++++ b/fs/lockd/svclock.c +@@ -699,9 +699,10 @@ nlmsvc_cancel_blocked(struct net *net, s + block = nlmsvc_lookup_block(file, lock); + mutex_unlock(&file->f_mutex); + if (block != NULL) { +- mode = lock_to_openmode(&lock->fl); +- vfs_cancel_lock(block->b_file->f_file[mode], +- &block->b_call->a_args.lock.fl); ++ struct file_lock *fl = &block->b_call->a_args.lock.fl; ++ ++ mode = lock_to_openmode(fl); ++ vfs_cancel_lock(block->b_file->f_file[mode], fl); + status = nlmsvc_unlink_block(block); + nlmsvc_release_block(block); + } diff --git a/queue-6.1/lockd-set-missing-fl_flags-field-when-retrieving-args.patch b/queue-6.1/lockd-set-missing-fl_flags-field-when-retrieving-args.patch new file mode 100644 index 00000000000..ac56a5faf13 --- /dev/null +++ b/queue-6.1/lockd-set-missing-fl_flags-field-when-retrieving-args.patch @@ -0,0 +1,37 @@ +From c9bb9f1f9a8a13d5c4d8d0dc61826710edfa5ee4 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Fri, 11 Nov 2022 14:36:36 -0500 +Subject: lockd: set missing fl_flags field when retrieving args + +From: Jeff Layton + +[ Upstream commit 75c7940d2a86d3f1b60a0a265478cb8fc887b970 ] + +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/lockd/svc4proc.c | 1 + + fs/lockd/svcproc.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/fs/lockd/svc4proc.c ++++ b/fs/lockd/svc4proc.c +@@ -52,6 +52,7 @@ nlm4svc_retrieve_args(struct svc_rqst *r + *filp = file; + + /* Set up the missing parts of the file_lock structure */ ++ lock->fl.fl_flags = FL_POSIX; + lock->fl.fl_file = file->f_file[mode]; + lock->fl.fl_pid = current->tgid; + lock->fl.fl_start = (loff_t)lock->lock_start; +--- a/fs/lockd/svcproc.c ++++ b/fs/lockd/svcproc.c +@@ -77,6 +77,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rq + + /* Set up the missing parts of the file_lock structure */ + mode = lock_to_openmode(&lock->fl); ++ lock->fl.fl_flags = FL_POSIX; + lock->fl.fl_file = file->f_file[mode]; + lock->fl.fl_pid = current->tgid; + lock->fl.fl_lmops = &nlmsvc_lock_operations; diff --git a/queue-6.1/lockd-use-locks_inode_context-helper.patch b/queue-6.1/lockd-use-locks_inode_context-helper.patch new file mode 100644 index 00000000000..5c347433046 --- /dev/null +++ b/queue-6.1/lockd-use-locks_inode_context-helper.patch @@ -0,0 +1,44 @@ +From 444f52797c77c16ddea5319f53c0d650d775606c Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Wed, 16 Nov 2022 09:19:43 -0500 +Subject: lockd: use locks_inode_context helper + +From: Jeff Layton + +[ Upstream commit 98b41ffe0afdfeaa1439a5d6bd2db4a94277e31b ] + +lockd currently doesn't access i_flctx safely. This requires a +smp_load_acquire, as the pointer is set via cmpxchg (a release +operation). + +Cc: Trond Myklebust +Cc: Anna Schumaker +Cc: Chuck Lever +Reviewed-by: Christoph Hellwig +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/lockd/svcsubs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/lockd/svcsubs.c ++++ b/fs/lockd/svcsubs.c +@@ -210,7 +210,7 @@ nlm_traverse_locks(struct nlm_host *host + { + struct inode *inode = nlmsvc_file_inode(file); + struct file_lock *fl; +- struct file_lock_context *flctx = inode->i_flctx; ++ struct file_lock_context *flctx = locks_inode_context(inode); + struct nlm_host *lockhost; + + if (!flctx || list_empty_careful(&flctx->flc_posix)) +@@ -265,7 +265,7 @@ nlm_file_inuse(struct nlm_file *file) + { + struct inode *inode = nlmsvc_file_inode(file); + struct file_lock *fl; +- struct file_lock_context *flctx = inode->i_flctx; ++ struct file_lock_context *flctx = locks_inode_context(inode); + + if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares) + return 1; diff --git a/queue-6.1/nfsd-add-a-nfsd4_file_hash_remove-helper.patch b/queue-6.1/nfsd-add-a-nfsd4_file_hash_remove-helper.patch new file mode 100644 index 00000000000..52500cfc61b --- /dev/null +++ b/queue-6.1/nfsd-add-a-nfsd4_file_hash_remove-helper.patch @@ -0,0 +1,61 @@ +From 29ddbb46d0563b2f0dc15886308b67aa5916965a Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Fri, 28 Oct 2022 10:47:34 -0400 +Subject: NFSD: Add a nfsd4_file_hash_remove() helper + +From: Chuck Lever + +[ Upstream commit 3341678f2fd6106055cead09e513fad6950a0d19 ] + +Refactor to relocate hash deletion operation to a helper function +that is close to most other nfs4_file data structure operations. + +The "noinline" annotation will become useful in a moment when the +hlist_del_rcu() is replaced with a more complex rhash remove +operation. It also guarantees that hash remove operations can be +traced with "-p function -l remove_nfs4_file_locked". + +This also simplifies the organization of forward declarations: the +to-be-added rhashtable and its param structure will be defined +/after/ put_nfs4_file(). + +Signed-off-by: Chuck Lever +Reviewed-by: NeilBrown +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -84,6 +84,7 @@ static bool check_for_locks(struct nfs4_ + static void nfs4_free_ol_stateid(struct nfs4_stid *stid); + void nfsd4_end_grace(struct nfsd_net *nn); + static void _free_cpntf_state_locked(struct nfsd_net *nn, struct nfs4_cpntf_state *cps); ++static void nfsd4_file_hash_remove(struct nfs4_file *fi); + + /* Locking: */ + +@@ -591,7 +592,7 @@ put_nfs4_file(struct nfs4_file *fi) + might_lock(&state_lock); + + if (refcount_dec_and_lock(&fi->fi_ref, &state_lock)) { +- hlist_del_rcu(&fi->fi_hash); ++ nfsd4_file_hash_remove(fi); + spin_unlock(&state_lock); + WARN_ON_ONCE(!list_empty(&fi->fi_clnt_odstate)); + WARN_ON_ONCE(!list_empty(&fi->fi_delegations)); +@@ -4750,6 +4751,11 @@ find_or_add_file(struct nfs4_file *new, + return insert_file(new, fh, hashval); + } + ++static noinline_for_stack void nfsd4_file_hash_remove(struct nfs4_file *fi) ++{ ++ hlist_del_rcu(&fi->fi_hash); ++} ++ + /* + * Called to check deny when READ with all zero stateid or + * WRITE with all zero or all one stateid diff --git a/queue-6.1/nfsd-add-cb_recall_any-tracepoints.patch b/queue-6.1/nfsd-add-cb_recall_any-tracepoints.patch new file mode 100644 index 00000000000..93eabeedb31 --- /dev/null +++ b/queue-6.1/nfsd-add-cb_recall_any-tracepoints.patch @@ -0,0 +1,136 @@ +From f8705e063165c4cd87f1bbdec9211992c5d434e4 Mon Sep 17 00:00:00 2001 +From: Dai Ngo +Date: Wed, 16 Nov 2022 19:44:48 -0800 +Subject: NFSD: add CB_RECALL_ANY tracepoints + +From: Dai Ngo + +[ Upstream commit 638593be55c0b37a1930038460a9918215d5c24b ] + +Add tracepoints to trace start and end of CB_RECALL_ANY operation. + +Signed-off-by: Dai Ngo +[ cel: added show_rca_mask() macro ] +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 2 + + fs/nfsd/trace.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++ + include/trace/misc/nfs.h | 12 +++++++++++ + 3 files changed, 64 insertions(+) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -2877,6 +2877,7 @@ static int + nfsd4_cb_recall_any_done(struct nfsd4_callback *cb, + struct rpc_task *task) + { ++ trace_nfsd_cb_recall_any_done(cb, task); + switch (task->tk_status) { + case -NFS4ERR_DELAY: + rpc_delay(task, 2 * HZ); +@@ -6254,6 +6255,7 @@ deleg_reaper(struct nfsd_net *nn) + list_del_init(&clp->cl_ra_cblist); + clp->cl_ra->ra_keep = 0; + clp->cl_ra->ra_bmval[0] = BIT(RCA4_TYPE_MASK_RDATA_DLG); ++ trace_nfsd_cb_recall_any(clp->cl_ra); + nfsd4_run_cb(&clp->cl_ra->ra_cb); + } + } +--- a/fs/nfsd/trace.h ++++ b/fs/nfsd/trace.h +@@ -9,9 +9,12 @@ + #define _NFSD_TRACE_H + + #include ++#include ++#include + + #include "export.h" + #include "nfsfh.h" ++#include "xdr4.h" + + #define NFSD_TRACE_PROC_RES_FIELDS \ + __field(unsigned int, netns_ino) \ +@@ -1492,6 +1495,32 @@ TRACE_EVENT(nfsd_cb_offload, + __entry->fh_hash, __entry->count, __entry->status) + ); + ++TRACE_EVENT(nfsd_cb_recall_any, ++ TP_PROTO( ++ const struct nfsd4_cb_recall_any *ra ++ ), ++ TP_ARGS(ra), ++ TP_STRUCT__entry( ++ __field(u32, cl_boot) ++ __field(u32, cl_id) ++ __field(u32, keep) ++ __field(unsigned long, bmval0) ++ __sockaddr(addr, ra->ra_cb.cb_clp->cl_cb_conn.cb_addrlen) ++ ), ++ TP_fast_assign( ++ __entry->cl_boot = ra->ra_cb.cb_clp->cl_clientid.cl_boot; ++ __entry->cl_id = ra->ra_cb.cb_clp->cl_clientid.cl_id; ++ __entry->keep = ra->ra_keep; ++ __entry->bmval0 = ra->ra_bmval[0]; ++ __assign_sockaddr(addr, &ra->ra_cb.cb_clp->cl_addr, ++ ra->ra_cb.cb_clp->cl_cb_conn.cb_addrlen); ++ ), ++ TP_printk("addr=%pISpc client %08x:%08x keep=%u bmval0=%s", ++ __get_sockaddr(addr), __entry->cl_boot, __entry->cl_id, ++ __entry->keep, show_rca_mask(__entry->bmval0) ++ ) ++); ++ + DECLARE_EVENT_CLASS(nfsd_cb_done_class, + TP_PROTO( + const stateid_t *stp, +@@ -1531,6 +1560,27 @@ DEFINE_NFSD_CB_DONE_EVENT(nfsd_cb_notify + DEFINE_NFSD_CB_DONE_EVENT(nfsd_cb_layout_done); + DEFINE_NFSD_CB_DONE_EVENT(nfsd_cb_offload_done); + ++TRACE_EVENT(nfsd_cb_recall_any_done, ++ TP_PROTO( ++ const struct nfsd4_callback *cb, ++ const struct rpc_task *task ++ ), ++ TP_ARGS(cb, task), ++ TP_STRUCT__entry( ++ __field(u32, cl_boot) ++ __field(u32, cl_id) ++ __field(int, status) ++ ), ++ TP_fast_assign( ++ __entry->status = task->tk_status; ++ __entry->cl_boot = cb->cb_clp->cl_clientid.cl_boot; ++ __entry->cl_id = cb->cb_clp->cl_clientid.cl_id; ++ ), ++ TP_printk("client %08x:%08x status=%d", ++ __entry->cl_boot, __entry->cl_id, __entry->status ++ ) ++); ++ + #endif /* _NFSD_TRACE_H */ + + #undef TRACE_INCLUDE_PATH +--- a/include/trace/misc/nfs.h ++++ b/include/trace/misc/nfs.h +@@ -360,6 +360,18 @@ TRACE_DEFINE_ENUM(IOMODE_ANY); + { IOMODE_RW, "RW" }, \ + { IOMODE_ANY, "ANY" }) + ++#define show_rca_mask(x) \ ++ __print_flags(x, "|", \ ++ { BIT(RCA4_TYPE_MASK_RDATA_DLG), "RDATA_DLG" }, \ ++ { BIT(RCA4_TYPE_MASK_WDATA_DLG), "WDATA_DLG" }, \ ++ { BIT(RCA4_TYPE_MASK_DIR_DLG), "DIR_DLG" }, \ ++ { BIT(RCA4_TYPE_MASK_FILE_LAYOUT), "FILE_LAYOUT" }, \ ++ { BIT(RCA4_TYPE_MASK_BLK_LAYOUT), "BLK_LAYOUT" }, \ ++ { BIT(RCA4_TYPE_MASK_OBJ_LAYOUT_MIN), "OBJ_LAYOUT_MIN" }, \ ++ { BIT(RCA4_TYPE_MASK_OBJ_LAYOUT_MAX), "OBJ_LAYOUT_MAX" }, \ ++ { BIT(RCA4_TYPE_MASK_OTHER_LAYOUT_MIN), "OTHER_LAYOUT_MIN" }, \ ++ { BIT(RCA4_TYPE_MASK_OTHER_LAYOUT_MAX), "OTHER_LAYOUT_MAX" }) ++ + #define show_nfs4_seq4_status(x) \ + __print_flags(x, "|", \ + { SEQ4_STATUS_CB_PATH_DOWN, "CB_PATH_DOWN" }, \ diff --git a/queue-6.1/nfsd-add-delegation-reaper-to-react-to-low-memory-condition.patch b/queue-6.1/nfsd-add-delegation-reaper-to-react-to-low-memory-condition.patch new file mode 100644 index 00000000000..115391f429f --- /dev/null +++ b/queue-6.1/nfsd-add-delegation-reaper-to-react-to-low-memory-condition.patch @@ -0,0 +1,204 @@ +From ae75430dec3ea9b1eeaeefdfc28470352dd00dc5 Mon Sep 17 00:00:00 2001 +From: Dai Ngo +Date: Wed, 16 Nov 2022 19:44:47 -0800 +Subject: NFSD: add delegation reaper to react to low memory condition + +From: Dai Ngo + +[ Upstream commit 44df6f439a1790a5f602e3842879efa88f346672 ] + +The delegation reaper is called by nfsd memory shrinker's on +the 'count' callback. It scans the client list and sends the +courtesy CB_RECALL_ANY to the clients that hold delegations. + +To avoid flooding the clients with CB_RECALL_ANY requests, the +delegation reaper sends only one CB_RECALL_ANY request to each +client per 5 seconds. + +Signed-off-by: Dai Ngo +[ cel: moved definition of RCA4_TYPE_MASK_RDATA_DLG ] +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++--- + fs/nfsd/state.h | 5 ++ + include/linux/nfs4.h | 13 +++++++ + 3 files changed, 102 insertions(+), 4 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -2145,6 +2145,7 @@ static void __free_client(struct kref *k + kfree(clp->cl_nii_domain.data); + kfree(clp->cl_nii_name.data); + idr_destroy(&clp->cl_stateids); ++ kfree(clp->cl_ra); + kmem_cache_free(client_slab, clp); + } + +@@ -2872,6 +2873,36 @@ static const struct tree_descr client_fi + [3] = {""}, + }; + ++static int ++nfsd4_cb_recall_any_done(struct nfsd4_callback *cb, ++ struct rpc_task *task) ++{ ++ switch (task->tk_status) { ++ case -NFS4ERR_DELAY: ++ rpc_delay(task, 2 * HZ); ++ return 0; ++ default: ++ return 1; ++ } ++} ++ ++static void ++nfsd4_cb_recall_any_release(struct nfsd4_callback *cb) ++{ ++ struct nfs4_client *clp = cb->cb_clp; ++ struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); ++ ++ spin_lock(&nn->client_lock); ++ clear_bit(NFSD4_CLIENT_CB_RECALL_ANY, &clp->cl_flags); ++ put_client_renew_locked(clp); ++ spin_unlock(&nn->client_lock); ++} ++ ++static const struct nfsd4_callback_ops nfsd4_cb_recall_any_ops = { ++ .done = nfsd4_cb_recall_any_done, ++ .release = nfsd4_cb_recall_any_release, ++}; ++ + static struct nfs4_client *create_client(struct xdr_netobj name, + struct svc_rqst *rqstp, nfs4_verifier *verf) + { +@@ -2909,6 +2940,14 @@ static struct nfs4_client *create_client + free_client(clp); + return NULL; + } ++ clp->cl_ra = kzalloc(sizeof(*clp->cl_ra), GFP_KERNEL); ++ if (!clp->cl_ra) { ++ free_client(clp); ++ return NULL; ++ } ++ clp->cl_ra_time = 0; ++ nfsd4_init_cb(&clp->cl_ra->ra_cb, clp, &nfsd4_cb_recall_any_ops, ++ NFSPROC4_CLNT_CB_RECALL_ANY); + return clp; + } + +@@ -4364,14 +4403,16 @@ out: + static unsigned long + nfsd4_state_shrinker_count(struct shrinker *shrink, struct shrink_control *sc) + { +- int cnt; ++ int count; + struct nfsd_net *nn = container_of(shrink, + struct nfsd_net, nfsd_client_shrinker); + +- cnt = atomic_read(&nn->nfsd_courtesy_clients); +- if (cnt > 0) ++ count = atomic_read(&nn->nfsd_courtesy_clients); ++ if (!count) ++ count = atomic_long_read(&num_delegations); ++ if (count) + mod_delayed_work(laundry_wq, &nn->nfsd_shrinker_work, 0); +- return (unsigned long)cnt; ++ return (unsigned long)count; + } + + static unsigned long +@@ -6180,6 +6221,44 @@ courtesy_client_reaper(struct nfsd_net * + } + + static void ++deleg_reaper(struct nfsd_net *nn) ++{ ++ struct list_head *pos, *next; ++ struct nfs4_client *clp; ++ struct list_head cblist; ++ ++ INIT_LIST_HEAD(&cblist); ++ spin_lock(&nn->client_lock); ++ list_for_each_safe(pos, next, &nn->client_lru) { ++ clp = list_entry(pos, struct nfs4_client, cl_lru); ++ if (clp->cl_state != NFSD4_ACTIVE || ++ list_empty(&clp->cl_delegations) || ++ atomic_read(&clp->cl_delegs_in_recall) || ++ test_bit(NFSD4_CLIENT_CB_RECALL_ANY, &clp->cl_flags) || ++ (ktime_get_boottime_seconds() - ++ clp->cl_ra_time < 5)) { ++ continue; ++ } ++ list_add(&clp->cl_ra_cblist, &cblist); ++ ++ /* release in nfsd4_cb_recall_any_release */ ++ atomic_inc(&clp->cl_rpc_users); ++ set_bit(NFSD4_CLIENT_CB_RECALL_ANY, &clp->cl_flags); ++ clp->cl_ra_time = ktime_get_boottime_seconds(); ++ } ++ spin_unlock(&nn->client_lock); ++ ++ while (!list_empty(&cblist)) { ++ clp = list_first_entry(&cblist, struct nfs4_client, ++ cl_ra_cblist); ++ list_del_init(&clp->cl_ra_cblist); ++ clp->cl_ra->ra_keep = 0; ++ clp->cl_ra->ra_bmval[0] = BIT(RCA4_TYPE_MASK_RDATA_DLG); ++ nfsd4_run_cb(&clp->cl_ra->ra_cb); ++ } ++} ++ ++static void + nfsd4_state_shrinker_worker(struct work_struct *work) + { + struct delayed_work *dwork = to_delayed_work(work); +@@ -6187,6 +6266,7 @@ nfsd4_state_shrinker_worker(struct work_ + nfsd_shrinker_work); + + courtesy_client_reaper(nn); ++ deleg_reaper(nn); + } + + static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stid *stp) +--- a/fs/nfsd/state.h ++++ b/fs/nfsd/state.h +@@ -368,6 +368,7 @@ struct nfs4_client { + #define NFSD4_CLIENT_UPCALL_LOCK (5) /* upcall serialization */ + #define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \ + 1 << NFSD4_CLIENT_CB_KILL) ++#define NFSD4_CLIENT_CB_RECALL_ANY (6) + unsigned long cl_flags; + const struct cred *cl_cb_cred; + struct rpc_clnt *cl_cb_client; +@@ -411,6 +412,10 @@ struct nfs4_client { + + unsigned int cl_state; + atomic_t cl_delegs_in_recall; ++ ++ struct nfsd4_cb_recall_any *cl_ra; ++ time64_t cl_ra_time; ++ struct list_head cl_ra_cblist; + }; + + /* struct nfs4_client_reset +--- a/include/linux/nfs4.h ++++ b/include/linux/nfs4.h +@@ -732,4 +732,17 @@ enum nfs4_setxattr_options { + SETXATTR4_CREATE = 1, + SETXATTR4_REPLACE = 2, + }; ++ ++enum { ++ RCA4_TYPE_MASK_RDATA_DLG = 0, ++ RCA4_TYPE_MASK_WDATA_DLG = 1, ++ RCA4_TYPE_MASK_DIR_DLG = 2, ++ RCA4_TYPE_MASK_FILE_LAYOUT = 3, ++ RCA4_TYPE_MASK_BLK_LAYOUT = 4, ++ RCA4_TYPE_MASK_OBJ_LAYOUT_MIN = 8, ++ RCA4_TYPE_MASK_OBJ_LAYOUT_MAX = 9, ++ RCA4_TYPE_MASK_OTHER_LAYOUT_MIN = 12, ++ RCA4_TYPE_MASK_OTHER_LAYOUT_MAX = 15, ++}; ++ + #endif diff --git a/queue-6.1/nfsd-add-support-for-sending-cb_recall_any.patch b/queue-6.1/nfsd-add-support-for-sending-cb_recall_any.patch new file mode 100644 index 00000000000..25510d55134 --- /dev/null +++ b/queue-6.1/nfsd-add-support-for-sending-cb_recall_any.patch @@ -0,0 +1,165 @@ +From 08607743476ffa171431efaec0d6e7c29bbbed4e Mon Sep 17 00:00:00 2001 +From: Dai Ngo +Date: Wed, 16 Nov 2022 19:44:46 -0800 +Subject: NFSD: add support for sending CB_RECALL_ANY + +From: Dai Ngo + +[ Upstream commit 3959066b697b5dfbb7141124ae9665337d4bc638 ] + +Add XDR encode and decode function for CB_RECALL_ANY. + +Signed-off-by: Dai Ngo +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4callback.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ + fs/nfsd/state.h | 1 + fs/nfsd/xdr4.h | 5 +++ + fs/nfsd/xdr4cb.h | 6 ++++ + 4 files changed, 84 insertions(+) + +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -76,6 +76,17 @@ static __be32 *xdr_encode_empty_array(__ + * 1 Protocol" + */ + ++static void encode_uint32(struct xdr_stream *xdr, u32 n) ++{ ++ WARN_ON_ONCE(xdr_stream_encode_u32(xdr, n) < 0); ++} ++ ++static void encode_bitmap4(struct xdr_stream *xdr, const __u32 *bitmap, ++ size_t len) ++{ ++ WARN_ON_ONCE(xdr_stream_encode_uint32_array(xdr, bitmap, len) < 0); ++} ++ + /* + * nfs_cb_opnum4 + * +@@ -329,6 +340,24 @@ static void encode_cb_recall4args(struct + } + + /* ++ * CB_RECALLANY4args ++ * ++ * struct CB_RECALLANY4args { ++ * uint32_t craa_objects_to_keep; ++ * bitmap4 craa_type_mask; ++ * }; ++ */ ++static void ++encode_cb_recallany4args(struct xdr_stream *xdr, ++ struct nfs4_cb_compound_hdr *hdr, struct nfsd4_cb_recall_any *ra) ++{ ++ encode_nfs_cb_opnum4(xdr, OP_CB_RECALL_ANY); ++ encode_uint32(xdr, ra->ra_keep); ++ encode_bitmap4(xdr, ra->ra_bmval, ARRAY_SIZE(ra->ra_bmval)); ++ hdr->nops++; ++} ++ ++/* + * CB_SEQUENCE4args + * + * struct CB_SEQUENCE4args { +@@ -482,6 +511,26 @@ static void nfs4_xdr_enc_cb_recall(struc + encode_cb_nops(&hdr); + } + ++/* ++ * 20.6. Operation 8: CB_RECALL_ANY - Keep Any N Recallable Objects ++ */ ++static void ++nfs4_xdr_enc_cb_recall_any(struct rpc_rqst *req, ++ struct xdr_stream *xdr, const void *data) ++{ ++ const struct nfsd4_callback *cb = data; ++ struct nfsd4_cb_recall_any *ra; ++ struct nfs4_cb_compound_hdr hdr = { ++ .ident = cb->cb_clp->cl_cb_ident, ++ .minorversion = cb->cb_clp->cl_minorversion, ++ }; ++ ++ ra = container_of(cb, struct nfsd4_cb_recall_any, ra_cb); ++ encode_cb_compound4args(xdr, &hdr); ++ encode_cb_sequence4args(xdr, cb, &hdr); ++ encode_cb_recallany4args(xdr, &hdr, ra); ++ encode_cb_nops(&hdr); ++} + + /* + * NFSv4.0 and NFSv4.1 XDR decode functions +@@ -520,6 +569,28 @@ static int nfs4_xdr_dec_cb_recall(struct + return decode_cb_op_status(xdr, OP_CB_RECALL, &cb->cb_status); + } + ++/* ++ * 20.6. Operation 8: CB_RECALL_ANY - Keep Any N Recallable Objects ++ */ ++static int ++nfs4_xdr_dec_cb_recall_any(struct rpc_rqst *rqstp, ++ struct xdr_stream *xdr, ++ void *data) ++{ ++ struct nfsd4_callback *cb = data; ++ struct nfs4_cb_compound_hdr hdr; ++ int status; ++ ++ status = decode_cb_compound4res(xdr, &hdr); ++ if (unlikely(status)) ++ return status; ++ status = decode_cb_sequence4res(xdr, cb); ++ if (unlikely(status || cb->cb_seq_status)) ++ return status; ++ status = decode_cb_op_status(xdr, OP_CB_RECALL_ANY, &cb->cb_status); ++ return status; ++} ++ + #ifdef CONFIG_NFSD_PNFS + /* + * CB_LAYOUTRECALL4args +@@ -783,6 +854,7 @@ static const struct rpc_procinfo nfs4_cb + #endif + PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock), + PROC(CB_OFFLOAD, COMPOUND, cb_offload, cb_offload), ++ PROC(CB_RECALL_ANY, COMPOUND, cb_recall_any, cb_recall_any), + }; + + static unsigned int nfs4_cb_counts[ARRAY_SIZE(nfs4_cb_procedures)]; +--- a/fs/nfsd/state.h ++++ b/fs/nfsd/state.h +@@ -636,6 +636,7 @@ enum nfsd4_cb_op { + NFSPROC4_CLNT_CB_OFFLOAD, + NFSPROC4_CLNT_CB_SEQUENCE, + NFSPROC4_CLNT_CB_NOTIFY_LOCK, ++ NFSPROC4_CLNT_CB_RECALL_ANY, + }; + + /* Returns true iff a is later than b: */ +--- a/fs/nfsd/xdr4.h ++++ b/fs/nfsd/xdr4.h +@@ -896,5 +896,10 @@ struct nfsd4_operation { + union nfsd4_op_u *); + }; + ++struct nfsd4_cb_recall_any { ++ struct nfsd4_callback ra_cb; ++ u32 ra_keep; ++ u32 ra_bmval[1]; ++}; + + #endif +--- a/fs/nfsd/xdr4cb.h ++++ b/fs/nfsd/xdr4cb.h +@@ -48,3 +48,9 @@ + #define NFS4_dec_cb_offload_sz (cb_compound_dec_hdr_sz + \ + cb_sequence_dec_sz + \ + op_dec_sz) ++#define NFS4_enc_cb_recall_any_sz (cb_compound_enc_hdr_sz + \ ++ cb_sequence_enc_sz + \ ++ 1 + 1 + 1) ++#define NFS4_dec_cb_recall_any_sz (cb_compound_dec_hdr_sz + \ ++ cb_sequence_dec_sz + \ ++ op_dec_sz) diff --git a/queue-6.1/nfsd-allow-disabling-nfsv2-at-compile-time.patch b/queue-6.1/nfsd-allow-disabling-nfsv2-at-compile-time.patch new file mode 100644 index 00000000000..937c6150ce1 --- /dev/null +++ b/queue-6.1/nfsd-allow-disabling-nfsv2-at-compile-time.patch @@ -0,0 +1,143 @@ +From ca0bebbcc3bee825aa4f8768aca93a41aa076bbb Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Tue, 18 Oct 2022 07:47:56 -0400 +Subject: nfsd: allow disabling NFSv2 at compile time + +From: Jeff Layton + +[ Upstream commit 2f3a4b2ac2f28b9be78ad21f401f31e263845214 ] + +rpc.nfsd stopped supporting NFSv2 a year ago. Take the next logical +step toward deprecating it and allow NFSv2 support to be compiled out. + +Add a new CONFIG_NFSD_V2 option that can be turned off and rework the +CONFIG_NFSD_V?_ACL option dependencies. Add a description that +discourages enabling it. + +Also, change the description of CONFIG_NFSD to state that the always-on +version is now 3 instead of 2. + +Finally, add an #ifdef around "case 2:" in __write_versions. When NFSv2 +is disabled at compile time, this should make the kernel ignore attempts +to disable it at runtime, but still error out when trying to enable it. + +Signed-off-by: Jeff Layton +Reviewed-by: Tom Talpey +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/Kconfig | 19 +++++++++++++++---- + fs/nfsd/Makefile | 5 +++-- + fs/nfsd/nfsctl.c | 2 ++ + fs/nfsd/nfsd.h | 3 +-- + fs/nfsd/nfssvc.c | 6 ++++++ + 5 files changed, 27 insertions(+), 8 deletions(-) + +--- a/fs/nfsd/Kconfig ++++ b/fs/nfsd/Kconfig +@@ -8,6 +8,7 @@ config NFSD + select SUNRPC + select EXPORTFS + select NFS_ACL_SUPPORT if NFSD_V2_ACL ++ select NFS_ACL_SUPPORT if NFSD_V3_ACL + depends on MULTIUSER + help + Choose Y here if you want to allow other computers to access +@@ -26,19 +27,29 @@ config NFSD + + Below you can choose which versions of the NFS protocol are + available to clients mounting the NFS server on this system. +- Support for NFS version 2 (RFC 1094) is always available when ++ Support for NFS version 3 (RFC 1813) is always available when + CONFIG_NFSD is selected. + + If unsure, say N. + +-config NFSD_V2_ACL +- bool ++config NFSD_V2 ++ bool "NFS server support for NFS version 2 (DEPRECATED)" + depends on NFSD ++ default n ++ help ++ NFSv2 (RFC 1094) was the first publicly-released version of NFS. ++ Unless you are hosting ancient (1990's era) NFS clients, you don't ++ need this. ++ ++ If unsure, say N. ++ ++config NFSD_V2_ACL ++ bool "NFS server support for the NFSv2 ACL protocol extension" ++ depends on NFSD_V2 + + config NFSD_V3_ACL + bool "NFS server support for the NFSv3 ACL protocol extension" + depends on NFSD +- select NFSD_V2_ACL + help + Solaris NFS servers support an auxiliary NFSv3 ACL protocol that + never became an official part of the NFS version 3 protocol. +--- a/fs/nfsd/Makefile ++++ b/fs/nfsd/Makefile +@@ -10,9 +10,10 @@ obj-$(CONFIG_NFSD) += nfsd.o + # this one should be compiled first, as the tracing macros can easily blow up + nfsd-y += trace.o + +-nfsd-y += nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \ +- export.o auth.o lockd.o nfscache.o nfsxdr.o \ ++nfsd-y += nfssvc.o nfsctl.o nfsfh.o vfs.o \ ++ export.o auth.o lockd.o nfscache.o \ + stats.o filecache.o nfs3proc.o nfs3xdr.o ++nfsd-$(CONFIG_NFSD_V2) += nfsproc.o nfsxdr.o + nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o + nfsd-$(CONFIG_NFSD_V3_ACL) += nfs3acl.o + nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \ +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -581,7 +581,9 @@ static ssize_t __write_versions(struct f + + cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET; + switch(num) { ++#ifdef CONFIG_NFSD_V2 + case 2: ++#endif + case 3: + nfsd_vers(nn, num, cmd); + break; +--- a/fs/nfsd/nfsd.h ++++ b/fs/nfsd/nfsd.h +@@ -64,8 +64,7 @@ struct readdir_cd { + + + extern struct svc_program nfsd_program; +-extern const struct svc_version nfsd_version2, nfsd_version3, +- nfsd_version4; ++extern const struct svc_version nfsd_version2, nfsd_version3, nfsd_version4; + extern struct mutex nfsd_mutex; + extern spinlock_t nfsd_drc_lock; + extern unsigned long nfsd_drc_max_mem; +--- a/fs/nfsd/nfssvc.c ++++ b/fs/nfsd/nfssvc.c +@@ -91,8 +91,12 @@ unsigned long nfsd_drc_mem_used; + #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) + static struct svc_stat nfsd_acl_svcstats; + static const struct svc_version *nfsd_acl_version[] = { ++# if defined(CONFIG_NFSD_V2_ACL) + [2] = &nfsd_acl_version2, ++# endif ++# if defined(CONFIG_NFSD_V3_ACL) + [3] = &nfsd_acl_version3, ++# endif + }; + + #define NFSD_ACL_MINVERS 2 +@@ -116,7 +120,9 @@ static struct svc_stat nfsd_acl_svcstats + #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ + + static const struct svc_version *nfsd_version[] = { ++#if defined(CONFIG_NFSD_V2) + [2] = &nfsd_version2, ++#endif + [3] = &nfsd_version3, + #if defined(CONFIG_NFSD_V4) + [4] = &nfsd_version4, diff --git a/queue-6.1/nfsd-avoid-clashing-function-prototypes.patch b/queue-6.1/nfsd-avoid-clashing-function-prototypes.patch new file mode 100644 index 00000000000..b259b1a5e44 --- /dev/null +++ b/queue-6.1/nfsd-avoid-clashing-function-prototypes.patch @@ -0,0 +1,1529 @@ +From deb43baeb013c36694511a8751b59a4c68170a29 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Fri, 2 Dec 2022 12:48:59 -0800 +Subject: NFSD: Avoid clashing function prototypes + +From: Kees Cook + +[ Upstream commit e78e274eb22d966258a3845acc71d3c5b8ee2ea8 ] + +When built with Control Flow Integrity, function prototypes between +caller and function declaration must match. These mismatches are visible +at compile time with the new -Wcast-function-type-strict in Clang[1]. + +There were 97 warnings produced by NFS. For example: + +fs/nfsd/nfs4xdr.c:2228:17: warning: cast from '__be32 (*)(struct nfsd4_compoundargs *, struct nfsd4_access *)' (aka 'unsigned int (*)(struct nfsd4_compoundargs *, struct nfsd4_access *)') to 'nfsd4_dec' (aka 'unsigned int (*)(struct nfsd4_compoundargs *, void *)') converts to incompatible function type [-Wcast-function-type-strict] + [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The enc/dec callbacks were defined as passing "void *" as the second +argument, but were being implicitly cast to a new type. Replace the +argument with union nfsd4_op_u, and perform explicit member selection +in the function body. There are no resulting binary differences. + +Changes were made mechanically using the following Coccinelle script, +with minor by-hand fixes for members that didn't already match their +existing argument name: + +@find@ +identifier func; +type T, opsT; +identifier ops, N; +@@ + + opsT ops[] = { + [N] = (T) func, + }; + +@already_void@ +identifier find.func; +identifier name; +@@ + + func(..., +-void ++union nfsd4_op_u + *name) + { + ... + } + +@proto depends on !already_void@ +identifier find.func; +type T; +identifier name; +position p; +@@ + + func@p(..., + T name + ) { + ... + } + +@script:python get_member@ +type_name << proto.T; +member; +@@ + +coccinelle.member = cocci.make_ident(type_name.split("_", 1)[1].split(' ',1)[0]) + +@convert@ +identifier find.func; +type proto.T; +identifier proto.name; +position proto.p; +identifier get_member.member; +@@ + + func@p(..., +- T name ++ union nfsd4_op_u *u + ) { ++ T name = &u->member; + ... + } + +@cast@ +identifier find.func; +type T, opsT; +identifier ops, N; +@@ + + opsT ops[] = { + [N] = +- (T) + func, + }; + +Cc: Chuck Lever +Cc: Jeff Layton +Cc: Gustavo A. R. Silva +Cc: linux-nfs@vger.kernel.org +Signed-off-by: Kees Cook +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4xdr.c | 632 ++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 377 insertions(+), 255 deletions(-) + +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -770,16 +770,18 @@ nfsd4_decode_cb_sec(struct nfsd4_compoun + + static __be32 + nfsd4_decode_access(struct nfsd4_compoundargs *argp, +- struct nfsd4_access *access) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_access *access = &u->access; + if (xdr_stream_decode_u32(argp->xdr, &access->ac_req_access) < 0) + return nfserr_bad_xdr; + return nfs_ok; + } + + static __be32 +-nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) ++nfsd4_decode_close(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_close *close = &u->close; + if (xdr_stream_decode_u32(argp->xdr, &close->cl_seqid) < 0) + return nfserr_bad_xdr; + return nfsd4_decode_stateid4(argp, &close->cl_stateid); +@@ -787,8 +789,9 @@ nfsd4_decode_close(struct nfsd4_compound + + + static __be32 +-nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit) ++nfsd4_decode_commit(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_commit *commit = &u->commit; + if (xdr_stream_decode_u64(argp->xdr, &commit->co_offset) < 0) + return nfserr_bad_xdr; + if (xdr_stream_decode_u32(argp->xdr, &commit->co_count) < 0) +@@ -798,8 +801,9 @@ nfsd4_decode_commit(struct nfsd4_compoun + } + + static __be32 +-nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create) ++nfsd4_decode_create(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_create *create = &u->create; + __be32 *p, status; + + memset(create, 0, sizeof(*create)); +@@ -844,22 +848,25 @@ nfsd4_decode_create(struct nfsd4_compoun + } + + static inline __be32 +-nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr) ++nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_delegreturn *dr = &u->delegreturn; + return nfsd4_decode_stateid4(argp, &dr->dr_stateid); + } + + static inline __be32 +-nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr) ++nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_getattr *getattr = &u->getattr; + memset(getattr, 0, sizeof(*getattr)); + return nfsd4_decode_bitmap4(argp, getattr->ga_bmval, + ARRAY_SIZE(getattr->ga_bmval)); + } + + static __be32 +-nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link) ++nfsd4_decode_link(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_link *link = &u->link; + memset(link, 0, sizeof(*link)); + return nfsd4_decode_component4(argp, &link->li_name, &link->li_namelen); + } +@@ -907,8 +914,9 @@ nfsd4_decode_locker4(struct nfsd4_compou + } + + static __be32 +-nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) ++nfsd4_decode_lock(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_lock *lock = &u->lock; + memset(lock, 0, sizeof(*lock)); + if (xdr_stream_decode_u32(argp->xdr, &lock->lk_type) < 0) + return nfserr_bad_xdr; +@@ -924,8 +932,9 @@ nfsd4_decode_lock(struct nfsd4_compounda + } + + static __be32 +-nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) ++nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_lockt *lockt = &u->lockt; + memset(lockt, 0, sizeof(*lockt)); + if (xdr_stream_decode_u32(argp->xdr, &lockt->lt_type) < 0) + return nfserr_bad_xdr; +@@ -940,8 +949,9 @@ nfsd4_decode_lockt(struct nfsd4_compound + } + + static __be32 +-nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku) ++nfsd4_decode_locku(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_locku *locku = &u->locku; + __be32 status; + + if (xdr_stream_decode_u32(argp->xdr, &locku->lu_type) < 0) +@@ -962,8 +972,9 @@ nfsd4_decode_locku(struct nfsd4_compound + } + + static __be32 +-nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup) ++nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_lookup *lookup = &u->lookup; + return nfsd4_decode_component4(argp, &lookup->lo_name, &lookup->lo_len); + } + +@@ -1143,8 +1154,9 @@ nfsd4_decode_open_claim4(struct nfsd4_co + } + + static __be32 +-nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) ++nfsd4_decode_open(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_open *open = &u->open; + __be32 status; + u32 dummy; + +@@ -1171,8 +1183,10 @@ nfsd4_decode_open(struct nfsd4_compounda + } + + static __be32 +-nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) ++nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_open_confirm *open_conf = &u->open_confirm; + __be32 status; + + if (argp->minorversion >= 1) +@@ -1190,8 +1204,10 @@ nfsd4_decode_open_confirm(struct nfsd4_c + } + + static __be32 +-nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down) ++nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_open_downgrade *open_down = &u->open_downgrade; + __be32 status; + + memset(open_down, 0, sizeof(*open_down)); +@@ -1209,8 +1225,9 @@ nfsd4_decode_open_downgrade(struct nfsd4 + } + + static __be32 +-nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) ++nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_putfh *putfh = &u->putfh; + __be32 *p; + + if (xdr_stream_decode_u32(argp->xdr, &putfh->pf_fhlen) < 0) +@@ -1229,7 +1246,7 @@ nfsd4_decode_putfh(struct nfsd4_compound + } + + static __be32 +-nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p) ++nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, union nfsd4_op_u *p) + { + if (argp->minorversion == 0) + return nfs_ok; +@@ -1237,8 +1254,9 @@ nfsd4_decode_putpubfh(struct nfsd4_compo + } + + static __be32 +-nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) ++nfsd4_decode_read(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_read *read = &u->read; + __be32 status; + + memset(read, 0, sizeof(*read)); +@@ -1254,8 +1272,9 @@ nfsd4_decode_read(struct nfsd4_compounda + } + + static __be32 +-nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir) ++nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_readdir *readdir = &u->readdir; + __be32 status; + + memset(readdir, 0, sizeof(*readdir)); +@@ -1276,15 +1295,17 @@ nfsd4_decode_readdir(struct nfsd4_compou + } + + static __be32 +-nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove) ++nfsd4_decode_remove(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_remove *remove = &u->remove; + memset(&remove->rm_cinfo, 0, sizeof(remove->rm_cinfo)); + return nfsd4_decode_component4(argp, &remove->rm_name, &remove->rm_namelen); + } + + static __be32 +-nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename) ++nfsd4_decode_rename(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_rename *rename = &u->rename; + __be32 status; + + memset(rename, 0, sizeof(*rename)); +@@ -1295,22 +1316,25 @@ nfsd4_decode_rename(struct nfsd4_compoun + } + + static __be32 +-nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) ++nfsd4_decode_renew(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ clientid_t *clientid = &u->renew; + return nfsd4_decode_clientid4(argp, clientid); + } + + static __be32 + nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp, +- struct nfsd4_secinfo *secinfo) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_secinfo *secinfo = &u->secinfo; + secinfo->si_exp = NULL; + return nfsd4_decode_component4(argp, &secinfo->si_name, &secinfo->si_namelen); + } + + static __be32 +-nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) ++nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_setattr *setattr = &u->setattr; + __be32 status; + + memset(setattr, 0, sizeof(*setattr)); +@@ -1324,8 +1348,9 @@ nfsd4_decode_setattr(struct nfsd4_compou + } + + static __be32 +-nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid) ++nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_setclientid *setclientid = &u->setclientid; + __be32 *p, status; + + memset(setclientid, 0, sizeof(*setclientid)); +@@ -1367,8 +1392,10 @@ nfsd4_decode_setclientid(struct nfsd4_co + } + + static __be32 +-nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c) ++nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_setclientid_confirm *scd_c = &u->setclientid_confirm; + __be32 status; + + if (argp->minorversion >= 1) +@@ -1382,8 +1409,9 @@ nfsd4_decode_setclientid_confirm(struct + + /* Also used for NVERIFY */ + static __be32 +-nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify) ++nfsd4_decode_verify(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_verify *verify = &u->verify; + __be32 *p, status; + + memset(verify, 0, sizeof(*verify)); +@@ -1409,8 +1437,9 @@ nfsd4_decode_verify(struct nfsd4_compoun + } + + static __be32 +-nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) ++nfsd4_decode_write(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_write *write = &u->write; + __be32 status; + + status = nfsd4_decode_stateid4(argp, &write->wr_stateid); +@@ -1434,8 +1463,10 @@ nfsd4_decode_write(struct nfsd4_compound + } + + static __be32 +-nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner) ++nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_release_lockowner *rlockowner = &u->release_lockowner; + __be32 status; + + if (argp->minorversion >= 1) +@@ -1452,16 +1483,20 @@ nfsd4_decode_release_lockowner(struct nf + return nfs_ok; + } + +-static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc) ++static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_backchannel_ctl *bc = &u->backchannel_ctl; + memset(bc, 0, sizeof(*bc)); + if (xdr_stream_decode_u32(argp->xdr, &bc->bc_cb_program) < 0) + return nfserr_bad_xdr; + return nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec); + } + +-static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts) ++static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_bind_conn_to_session *bcts = &u->bind_conn_to_session; + u32 use_conn_in_rdma_mode; + __be32 status; + +@@ -1603,8 +1638,9 @@ nfsd4_decode_nfs_impl_id4(struct nfsd4_c + + static __be32 + nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp, +- struct nfsd4_exchange_id *exid) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_exchange_id *exid = &u->exchange_id; + __be32 status; + + memset(exid, 0, sizeof(*exid)); +@@ -1656,8 +1692,9 @@ nfsd4_decode_channel_attrs4(struct nfsd4 + + static __be32 + nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, +- struct nfsd4_create_session *sess) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_create_session *sess = &u->create_session; + __be32 status; + + memset(sess, 0, sizeof(*sess)); +@@ -1681,23 +1718,26 @@ nfsd4_decode_create_session(struct nfsd4 + + static __be32 + nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp, +- struct nfsd4_destroy_session *destroy_session) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_destroy_session *destroy_session = &u->destroy_session; + return nfsd4_decode_sessionid4(argp, &destroy_session->sessionid); + } + + static __be32 + nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp, +- struct nfsd4_free_stateid *free_stateid) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_free_stateid *free_stateid = &u->free_stateid; + return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid); + } + + #ifdef CONFIG_NFSD_PNFS + static __be32 + nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp, +- struct nfsd4_getdeviceinfo *gdev) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_getdeviceinfo *gdev = &u->getdeviceinfo; + __be32 status; + + memset(gdev, 0, sizeof(*gdev)); +@@ -1717,8 +1757,9 @@ nfsd4_decode_getdeviceinfo(struct nfsd4_ + + static __be32 + nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp, +- struct nfsd4_layoutcommit *lcp) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_layoutcommit *lcp = &u->layoutcommit; + __be32 *p, status; + + memset(lcp, 0, sizeof(*lcp)); +@@ -1753,8 +1794,9 @@ nfsd4_decode_layoutcommit(struct nfsd4_c + + static __be32 + nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp, +- struct nfsd4_layoutget *lgp) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_layoutget *lgp = &u->layoutget; + __be32 status; + + memset(lgp, 0, sizeof(*lgp)); +@@ -1781,8 +1823,9 @@ nfsd4_decode_layoutget(struct nfsd4_comp + + static __be32 + nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp, +- struct nfsd4_layoutreturn *lrp) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_layoutreturn *lrp = &u->layoutreturn; + memset(lrp, 0, sizeof(*lrp)); + if (xdr_stream_decode_bool(argp->xdr, &lrp->lr_reclaim) < 0) + return nfserr_bad_xdr; +@@ -1795,8 +1838,9 @@ nfsd4_decode_layoutreturn(struct nfsd4_c + #endif /* CONFIG_NFSD_PNFS */ + + static __be32 nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp, +- struct nfsd4_secinfo_no_name *sin) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_secinfo_no_name *sin = &u->secinfo_no_name; + if (xdr_stream_decode_u32(argp->xdr, &sin->sin_style) < 0) + return nfserr_bad_xdr; + +@@ -1806,8 +1850,9 @@ static __be32 nfsd4_decode_secinfo_no_na + + static __be32 + nfsd4_decode_sequence(struct nfsd4_compoundargs *argp, +- struct nfsd4_sequence *seq) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_sequence *seq = &u->sequence; + __be32 *p, status; + + status = nfsd4_decode_sessionid4(argp, &seq->sessionid); +@@ -1826,8 +1871,10 @@ nfsd4_decode_sequence(struct nfsd4_compo + } + + static __be32 +-nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid) ++nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_test_stateid *test_stateid = &u->test_stateid; + struct nfsd4_test_stateid_id *stateid; + __be32 status; + u32 i; +@@ -1852,14 +1899,16 @@ nfsd4_decode_test_stateid(struct nfsd4_c + } + + static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, +- struct nfsd4_destroy_clientid *dc) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_destroy_clientid *dc = &u->destroy_clientid; + return nfsd4_decode_clientid4(argp, &dc->clientid); + } + + static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, +- struct nfsd4_reclaim_complete *rc) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_reclaim_complete *rc = &u->reclaim_complete; + if (xdr_stream_decode_bool(argp->xdr, &rc->rca_one_fs) < 0) + return nfserr_bad_xdr; + return nfs_ok; +@@ -1867,8 +1916,9 @@ static __be32 nfsd4_decode_reclaim_compl + + static __be32 + nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp, +- struct nfsd4_fallocate *fallocate) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_fallocate *fallocate = &u->allocate; + __be32 status; + + status = nfsd4_decode_stateid4(argp, &fallocate->falloc_stateid); +@@ -1924,8 +1974,9 @@ static __be32 nfsd4_decode_nl4_server(st + } + + static __be32 +-nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy) ++nfsd4_decode_copy(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_copy *copy = &u->copy; + u32 consecutive, i, count, sync; + struct nl4_server *ns_dummy; + __be32 status; +@@ -1982,8 +2033,9 @@ nfsd4_decode_copy(struct nfsd4_compounda + + static __be32 + nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp, +- struct nfsd4_copy_notify *cn) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_copy_notify *cn = &u->copy_notify; + __be32 status; + + memset(cn, 0, sizeof(*cn)); +@@ -2002,16 +2054,18 @@ nfsd4_decode_copy_notify(struct nfsd4_co + + static __be32 + nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp, +- struct nfsd4_offload_status *os) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_offload_status *os = &u->offload_status; + os->count = 0; + os->status = 0; + return nfsd4_decode_stateid4(argp, &os->stateid); + } + + static __be32 +-nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) ++nfsd4_decode_seek(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_seek *seek = &u->seek; + __be32 status; + + status = nfsd4_decode_stateid4(argp, &seek->seek_stateid); +@@ -2028,8 +2082,9 @@ nfsd4_decode_seek(struct nfsd4_compounda + } + + static __be32 +-nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone) ++nfsd4_decode_clone(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) + { ++ struct nfsd4_clone *clone = &u->clone; + __be32 status; + + status = nfsd4_decode_stateid4(argp, &clone->cl_src_stateid); +@@ -2154,8 +2209,9 @@ nfsd4_decode_xattr_name(struct nfsd4_com + */ + static __be32 + nfsd4_decode_getxattr(struct nfsd4_compoundargs *argp, +- struct nfsd4_getxattr *getxattr) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_getxattr *getxattr = &u->getxattr; + __be32 status; + u32 maxcount; + +@@ -2173,8 +2229,9 @@ nfsd4_decode_getxattr(struct nfsd4_compo + + static __be32 + nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp, +- struct nfsd4_setxattr *setxattr) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_setxattr *setxattr = &u->setxattr; + u32 flags, maxcount, size; + __be32 status; + +@@ -2214,8 +2271,9 @@ nfsd4_decode_setxattr(struct nfsd4_compo + + static __be32 + nfsd4_decode_listxattrs(struct nfsd4_compoundargs *argp, +- struct nfsd4_listxattrs *listxattrs) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_listxattrs *listxattrs = &u->listxattrs; + u32 maxcount; + + memset(listxattrs, 0, sizeof(*listxattrs)); +@@ -2245,113 +2303,114 @@ nfsd4_decode_listxattrs(struct nfsd4_com + + static __be32 + nfsd4_decode_removexattr(struct nfsd4_compoundargs *argp, +- struct nfsd4_removexattr *removexattr) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_removexattr *removexattr = &u->removexattr; + memset(removexattr, 0, sizeof(*removexattr)); + return nfsd4_decode_xattr_name(argp, &removexattr->rmxa_name); + } + + static __be32 +-nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p) ++nfsd4_decode_noop(struct nfsd4_compoundargs *argp, union nfsd4_op_u *p) + { + return nfs_ok; + } + + static __be32 +-nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p) ++nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, union nfsd4_op_u *p) + { + return nfserr_notsupp; + } + +-typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *); ++typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u); + + static const nfsd4_dec nfsd4_dec_ops[] = { +- [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, +- [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close, +- [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit, +- [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create, +- [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn, +- [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr, +- [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop, +- [OP_LINK] = (nfsd4_dec)nfsd4_decode_link, +- [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock, +- [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt, +- [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku, +- [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup, +- [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop, +- [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify, +- [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open, +- [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm, +- [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, +- [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, +- [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_putpubfh, +- [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, +- [OP_READ] = (nfsd4_dec)nfsd4_decode_read, +- [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, +- [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop, +- [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove, +- [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename, +- [OP_RENEW] = (nfsd4_dec)nfsd4_decode_renew, +- [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop, +- [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop, +- [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo, +- [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr, +- [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_setclientid, +- [OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm, +- [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify, +- [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write, +- [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner, ++ [OP_ACCESS] = nfsd4_decode_access, ++ [OP_CLOSE] = nfsd4_decode_close, ++ [OP_COMMIT] = nfsd4_decode_commit, ++ [OP_CREATE] = nfsd4_decode_create, ++ [OP_DELEGPURGE] = nfsd4_decode_notsupp, ++ [OP_DELEGRETURN] = nfsd4_decode_delegreturn, ++ [OP_GETATTR] = nfsd4_decode_getattr, ++ [OP_GETFH] = nfsd4_decode_noop, ++ [OP_LINK] = nfsd4_decode_link, ++ [OP_LOCK] = nfsd4_decode_lock, ++ [OP_LOCKT] = nfsd4_decode_lockt, ++ [OP_LOCKU] = nfsd4_decode_locku, ++ [OP_LOOKUP] = nfsd4_decode_lookup, ++ [OP_LOOKUPP] = nfsd4_decode_noop, ++ [OP_NVERIFY] = nfsd4_decode_verify, ++ [OP_OPEN] = nfsd4_decode_open, ++ [OP_OPENATTR] = nfsd4_decode_notsupp, ++ [OP_OPEN_CONFIRM] = nfsd4_decode_open_confirm, ++ [OP_OPEN_DOWNGRADE] = nfsd4_decode_open_downgrade, ++ [OP_PUTFH] = nfsd4_decode_putfh, ++ [OP_PUTPUBFH] = nfsd4_decode_putpubfh, ++ [OP_PUTROOTFH] = nfsd4_decode_noop, ++ [OP_READ] = nfsd4_decode_read, ++ [OP_READDIR] = nfsd4_decode_readdir, ++ [OP_READLINK] = nfsd4_decode_noop, ++ [OP_REMOVE] = nfsd4_decode_remove, ++ [OP_RENAME] = nfsd4_decode_rename, ++ [OP_RENEW] = nfsd4_decode_renew, ++ [OP_RESTOREFH] = nfsd4_decode_noop, ++ [OP_SAVEFH] = nfsd4_decode_noop, ++ [OP_SECINFO] = nfsd4_decode_secinfo, ++ [OP_SETATTR] = nfsd4_decode_setattr, ++ [OP_SETCLIENTID] = nfsd4_decode_setclientid, ++ [OP_SETCLIENTID_CONFIRM] = nfsd4_decode_setclientid_confirm, ++ [OP_VERIFY] = nfsd4_decode_verify, ++ [OP_WRITE] = nfsd4_decode_write, ++ [OP_RELEASE_LOCKOWNER] = nfsd4_decode_release_lockowner, + + /* new operations for NFSv4.1 */ +- [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl, +- [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session, +- [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id, +- [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session, +- [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session, +- [OP_FREE_STATEID] = (nfsd4_dec)nfsd4_decode_free_stateid, +- [OP_GET_DIR_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, ++ [OP_BACKCHANNEL_CTL] = nfsd4_decode_backchannel_ctl, ++ [OP_BIND_CONN_TO_SESSION] = nfsd4_decode_bind_conn_to_session, ++ [OP_EXCHANGE_ID] = nfsd4_decode_exchange_id, ++ [OP_CREATE_SESSION] = nfsd4_decode_create_session, ++ [OP_DESTROY_SESSION] = nfsd4_decode_destroy_session, ++ [OP_FREE_STATEID] = nfsd4_decode_free_stateid, ++ [OP_GET_DIR_DELEGATION] = nfsd4_decode_notsupp, + #ifdef CONFIG_NFSD_PNFS +- [OP_GETDEVICEINFO] = (nfsd4_dec)nfsd4_decode_getdeviceinfo, +- [OP_GETDEVICELIST] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_layoutcommit, +- [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_layoutget, +- [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_layoutreturn, ++ [OP_GETDEVICEINFO] = nfsd4_decode_getdeviceinfo, ++ [OP_GETDEVICELIST] = nfsd4_decode_notsupp, ++ [OP_LAYOUTCOMMIT] = nfsd4_decode_layoutcommit, ++ [OP_LAYOUTGET] = nfsd4_decode_layoutget, ++ [OP_LAYOUTRETURN] = nfsd4_decode_layoutreturn, + #else +- [OP_GETDEVICEINFO] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_GETDEVICELIST] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp, ++ [OP_GETDEVICEINFO] = nfsd4_decode_notsupp, ++ [OP_GETDEVICELIST] = nfsd4_decode_notsupp, ++ [OP_LAYOUTCOMMIT] = nfsd4_decode_notsupp, ++ [OP_LAYOUTGET] = nfsd4_decode_notsupp, ++ [OP_LAYOUTRETURN] = nfsd4_decode_notsupp, + #endif +- [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_secinfo_no_name, +- [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence, +- [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_test_stateid, +- [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_destroy_clientid, +- [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, ++ [OP_SECINFO_NO_NAME] = nfsd4_decode_secinfo_no_name, ++ [OP_SEQUENCE] = nfsd4_decode_sequence, ++ [OP_SET_SSV] = nfsd4_decode_notsupp, ++ [OP_TEST_STATEID] = nfsd4_decode_test_stateid, ++ [OP_WANT_DELEGATION] = nfsd4_decode_notsupp, ++ [OP_DESTROY_CLIENTID] = nfsd4_decode_destroy_clientid, ++ [OP_RECLAIM_COMPLETE] = nfsd4_decode_reclaim_complete, + + /* new operations for NFSv4.2 */ +- [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, +- [OP_COPY] = (nfsd4_dec)nfsd4_decode_copy, +- [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_copy_notify, +- [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, +- [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_LAYOUTERROR] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_LAYOUTSTATS] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_OFFLOAD_CANCEL] = (nfsd4_dec)nfsd4_decode_offload_status, +- [OP_OFFLOAD_STATUS] = (nfsd4_dec)nfsd4_decode_offload_status, +- [OP_READ_PLUS] = (nfsd4_dec)nfsd4_decode_read, +- [OP_SEEK] = (nfsd4_dec)nfsd4_decode_seek, +- [OP_WRITE_SAME] = (nfsd4_dec)nfsd4_decode_notsupp, +- [OP_CLONE] = (nfsd4_dec)nfsd4_decode_clone, ++ [OP_ALLOCATE] = nfsd4_decode_fallocate, ++ [OP_COPY] = nfsd4_decode_copy, ++ [OP_COPY_NOTIFY] = nfsd4_decode_copy_notify, ++ [OP_DEALLOCATE] = nfsd4_decode_fallocate, ++ [OP_IO_ADVISE] = nfsd4_decode_notsupp, ++ [OP_LAYOUTERROR] = nfsd4_decode_notsupp, ++ [OP_LAYOUTSTATS] = nfsd4_decode_notsupp, ++ [OP_OFFLOAD_CANCEL] = nfsd4_decode_offload_status, ++ [OP_OFFLOAD_STATUS] = nfsd4_decode_offload_status, ++ [OP_READ_PLUS] = nfsd4_decode_read, ++ [OP_SEEK] = nfsd4_decode_seek, ++ [OP_WRITE_SAME] = nfsd4_decode_notsupp, ++ [OP_CLONE] = nfsd4_decode_clone, + /* RFC 8276 extended atributes operations */ +- [OP_GETXATTR] = (nfsd4_dec)nfsd4_decode_getxattr, +- [OP_SETXATTR] = (nfsd4_dec)nfsd4_decode_setxattr, +- [OP_LISTXATTRS] = (nfsd4_dec)nfsd4_decode_listxattrs, +- [OP_REMOVEXATTR] = (nfsd4_dec)nfsd4_decode_removexattr, ++ [OP_GETXATTR] = nfsd4_decode_getxattr, ++ [OP_SETXATTR] = nfsd4_decode_setxattr, ++ [OP_LISTXATTRS] = nfsd4_decode_listxattrs, ++ [OP_REMOVEXATTR] = nfsd4_decode_removexattr, + }; + + static inline bool +@@ -3643,8 +3702,10 @@ nfsd4_encode_stateid(struct xdr_stream * + } + + static __be32 +-nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access) ++nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_access *access = &u->access; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -3656,8 +3717,10 @@ nfsd4_encode_access(struct nfsd4_compoun + return 0; + } + +-static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts) ++static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_bind_conn_to_session *bcts = &u->bind_conn_to_session; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -3673,8 +3736,10 @@ static __be32 nfsd4_encode_bind_conn_to_ + } + + static __be32 +-nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) ++nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_close *close = &u->close; + struct xdr_stream *xdr = resp->xdr; + + return nfsd4_encode_stateid(xdr, &close->cl_stateid); +@@ -3682,8 +3747,10 @@ nfsd4_encode_close(struct nfsd4_compound + + + static __be32 +-nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit) ++nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_commit *commit = &u->commit; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -3696,8 +3763,10 @@ nfsd4_encode_commit(struct nfsd4_compoun + } + + static __be32 +-nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create) ++nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_create *create = &u->create; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -3710,8 +3779,10 @@ nfsd4_encode_create(struct nfsd4_compoun + } + + static __be32 +-nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr) ++nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_getattr *getattr = &u->getattr; + struct svc_fh *fhp = getattr->ga_fhp; + struct xdr_stream *xdr = resp->xdr; + +@@ -3720,8 +3791,10 @@ nfsd4_encode_getattr(struct nfsd4_compou + } + + static __be32 +-nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp) ++nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct svc_fh **fhpp = &u->getfh; + struct xdr_stream *xdr = resp->xdr; + struct svc_fh *fhp = *fhpp; + unsigned int len; +@@ -3775,8 +3848,10 @@ again: + } + + static __be32 +-nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock) ++nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_lock *lock = &u->lock; + struct xdr_stream *xdr = resp->xdr; + + if (!nfserr) +@@ -3788,8 +3863,10 @@ nfsd4_encode_lock(struct nfsd4_compoundr + } + + static __be32 +-nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt) ++nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_lockt *lockt = &u->lockt; + struct xdr_stream *xdr = resp->xdr; + + if (nfserr == nfserr_denied) +@@ -3798,8 +3875,10 @@ nfsd4_encode_lockt(struct nfsd4_compound + } + + static __be32 +-nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku) ++nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_locku *locku = &u->locku; + struct xdr_stream *xdr = resp->xdr; + + return nfsd4_encode_stateid(xdr, &locku->lu_stateid); +@@ -3807,8 +3886,10 @@ nfsd4_encode_locku(struct nfsd4_compound + + + static __be32 +-nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link) ++nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_link *link = &u->link; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -3821,8 +3902,10 @@ nfsd4_encode_link(struct nfsd4_compoundr + + + static __be32 +-nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open) ++nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_open *open = &u->open; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -3915,16 +3998,20 @@ nfsd4_encode_open(struct nfsd4_compoundr + } + + static __be32 +-nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc) ++nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_open_confirm *oc = &u->open_confirm; + struct xdr_stream *xdr = resp->xdr; + + return nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid); + } + + static __be32 +-nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od) ++nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_open_downgrade *od = &u->open_downgrade; + struct xdr_stream *xdr = resp->xdr; + + return nfsd4_encode_stateid(xdr, &od->od_stateid); +@@ -4023,8 +4110,9 @@ static __be32 nfsd4_encode_readv(struct + + static __be32 + nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_read *read) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_read *read = &u->read; + bool splice_ok = test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags); + unsigned long maxcount; + struct xdr_stream *xdr = resp->xdr; +@@ -4065,8 +4153,10 @@ nfsd4_encode_read(struct nfsd4_compoundr + } + + static __be32 +-nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink) ++nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_readlink *readlink = &u->readlink; + __be32 *p, *maxcount_p, zero = xdr_zero; + struct xdr_stream *xdr = resp->xdr; + int length_offset = xdr->buf->len; +@@ -4110,8 +4200,10 @@ out_err: + } + + static __be32 +-nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir) ++nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_readdir *readdir = &u->readdir; + int maxcount; + int bytes_left; + loff_t offset; +@@ -4201,8 +4293,10 @@ err_no_verf: + } + + static __be32 +-nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove) ++nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_remove *remove = &u->remove; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -4214,8 +4308,10 @@ nfsd4_encode_remove(struct nfsd4_compoun + } + + static __be32 +-nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename) ++nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_rename *rename = &u->rename; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -4297,8 +4393,9 @@ nfsd4_do_encode_secinfo(struct xdr_strea + + static __be32 + nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_secinfo *secinfo) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_secinfo *secinfo = &u->secinfo; + struct xdr_stream *xdr = resp->xdr; + + return nfsd4_do_encode_secinfo(xdr, secinfo->si_exp); +@@ -4306,8 +4403,9 @@ nfsd4_encode_secinfo(struct nfsd4_compou + + static __be32 + nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_secinfo_no_name *secinfo) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_secinfo_no_name *secinfo = &u->secinfo_no_name; + struct xdr_stream *xdr = resp->xdr; + + return nfsd4_do_encode_secinfo(xdr, secinfo->sin_exp); +@@ -4318,8 +4416,10 @@ nfsd4_encode_secinfo_no_name(struct nfsd + * regardless of the error status. + */ + static __be32 +-nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr) ++nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_setattr *setattr = &u->setattr; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -4342,8 +4442,10 @@ nfsd4_encode_setattr(struct nfsd4_compou + } + + static __be32 +-nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd) ++nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_setclientid *scd = &u->setclientid; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -4366,8 +4468,10 @@ nfsd4_encode_setclientid(struct nfsd4_co + } + + static __be32 +-nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write) ++nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *u) + { ++ struct nfsd4_write *write = &u->write; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -4383,8 +4487,9 @@ nfsd4_encode_write(struct nfsd4_compound + + static __be32 + nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_exchange_id *exid) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_exchange_id *exid = &u->exchange_id; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + char *major_id; +@@ -4461,8 +4566,9 @@ nfsd4_encode_exchange_id(struct nfsd4_co + + static __be32 + nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_create_session *sess) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_create_session *sess = &u->create_session; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -4514,8 +4620,9 @@ nfsd4_encode_create_session(struct nfsd4 + + static __be32 + nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_sequence *seq) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_sequence *seq = &u->sequence; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -4537,8 +4644,9 @@ nfsd4_encode_sequence(struct nfsd4_compo + + static __be32 + nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_test_stateid *test_stateid) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_test_stateid *test_stateid = &u->test_stateid; + struct xdr_stream *xdr = resp->xdr; + struct nfsd4_test_stateid_id *stateid, *next; + __be32 *p; +@@ -4558,8 +4666,9 @@ nfsd4_encode_test_stateid(struct nfsd4_c + #ifdef CONFIG_NFSD_PNFS + static __be32 + nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_getdeviceinfo *gdev) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_getdeviceinfo *gdev = &u->getdeviceinfo; + struct xdr_stream *xdr = resp->xdr; + const struct nfsd4_layout_ops *ops; + u32 starting_len = xdr->buf->len, needed_len; +@@ -4611,8 +4720,9 @@ toosmall: + + static __be32 + nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_layoutget *lgp) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_layoutget *lgp = &u->layoutget; + struct xdr_stream *xdr = resp->xdr; + const struct nfsd4_layout_ops *ops; + __be32 *p; +@@ -4638,8 +4748,9 @@ nfsd4_encode_layoutget(struct nfsd4_comp + + static __be32 + nfsd4_encode_layoutcommit(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_layoutcommit *lcp) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_layoutcommit *lcp = &u->layoutcommit; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -4659,8 +4770,9 @@ nfsd4_encode_layoutcommit(struct nfsd4_c + + static __be32 + nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_layoutreturn *lrp) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_layoutreturn *lrp = &u->layoutreturn; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -4745,8 +4857,9 @@ nfsd42_encode_nl4_server(struct nfsd4_co + + static __be32 + nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_copy *copy) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_copy *copy = &u->copy; + __be32 *p; + + nfserr = nfsd42_encode_write_res(resp, ©->cp_res, +@@ -4762,8 +4875,9 @@ nfsd4_encode_copy(struct nfsd4_compoundr + + static __be32 + nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_offload_status *os) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_offload_status *os = &u->offload_status; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -4813,8 +4927,9 @@ nfsd4_encode_read_plus_data(struct nfsd4 + + static __be32 + nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_read *read) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_read *read = &u->read; + struct file *file = read->rd_nf->nf_file; + struct xdr_stream *xdr = resp->xdr; + int starting_len = xdr->buf->len; +@@ -4850,8 +4965,9 @@ out: + + static __be32 + nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_copy_notify *cn) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_copy_notify *cn = &u->copy_notify; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -4885,8 +5001,9 @@ nfsd4_encode_copy_notify(struct nfsd4_co + + static __be32 + nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_seek *seek) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_seek *seek = &u->seek; + __be32 *p; + + p = xdr_reserve_space(resp->xdr, 4 + 8); +@@ -4897,7 +5014,8 @@ nfsd4_encode_seek(struct nfsd4_compoundr + } + + static __be32 +-nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p) ++nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, ++ union nfsd4_op_u *p) + { + return nfserr; + } +@@ -4948,8 +5066,9 @@ nfsd4_vbuf_to_stream(struct xdr_stream * + + static __be32 + nfsd4_encode_getxattr(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_getxattr *getxattr) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_getxattr *getxattr = &u->getxattr; + struct xdr_stream *xdr = resp->xdr; + __be32 *p, err; + +@@ -4972,8 +5091,9 @@ nfsd4_encode_getxattr(struct nfsd4_compo + + static __be32 + nfsd4_encode_setxattr(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_setxattr *setxattr) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_setxattr *setxattr = &u->setxattr; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -5013,8 +5133,9 @@ nfsd4_listxattr_validate_cookie(struct n + + static __be32 + nfsd4_encode_listxattrs(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_listxattrs *listxattrs) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_listxattrs *listxattrs = &u->listxattrs; + struct xdr_stream *xdr = resp->xdr; + u32 cookie_offset, count_offset, eof; + u32 left, xdrleft, slen, count; +@@ -5124,8 +5245,9 @@ out: + + static __be32 + nfsd4_encode_removexattr(struct nfsd4_compoundres *resp, __be32 nfserr, +- struct nfsd4_removexattr *removexattr) ++ union nfsd4_op_u *u) + { ++ struct nfsd4_removexattr *removexattr = &u->removexattr; + struct xdr_stream *xdr = resp->xdr; + __be32 *p; + +@@ -5137,7 +5259,7 @@ nfsd4_encode_removexattr(struct nfsd4_co + return 0; + } + +-typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *); ++typedef __be32(*nfsd4_enc)(struct nfsd4_compoundres *, __be32, union nfsd4_op_u *u); + + /* + * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1 +@@ -5145,93 +5267,93 @@ typedef __be32(* nfsd4_enc)(struct nfsd4 + * done in the decoding phase. + */ + static const nfsd4_enc nfsd4_enc_ops[] = { +- [OP_ACCESS] = (nfsd4_enc)nfsd4_encode_access, +- [OP_CLOSE] = (nfsd4_enc)nfsd4_encode_close, +- [OP_COMMIT] = (nfsd4_enc)nfsd4_encode_commit, +- [OP_CREATE] = (nfsd4_enc)nfsd4_encode_create, +- [OP_DELEGPURGE] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_DELEGRETURN] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_GETATTR] = (nfsd4_enc)nfsd4_encode_getattr, +- [OP_GETFH] = (nfsd4_enc)nfsd4_encode_getfh, +- [OP_LINK] = (nfsd4_enc)nfsd4_encode_link, +- [OP_LOCK] = (nfsd4_enc)nfsd4_encode_lock, +- [OP_LOCKT] = (nfsd4_enc)nfsd4_encode_lockt, +- [OP_LOCKU] = (nfsd4_enc)nfsd4_encode_locku, +- [OP_LOOKUP] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open, +- [OP_OPENATTR] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm, +- [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade, +- [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_PUTPUBFH] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_PUTROOTFH] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_READ] = (nfsd4_enc)nfsd4_encode_read, +- [OP_READDIR] = (nfsd4_enc)nfsd4_encode_readdir, +- [OP_READLINK] = (nfsd4_enc)nfsd4_encode_readlink, +- [OP_REMOVE] = (nfsd4_enc)nfsd4_encode_remove, +- [OP_RENAME] = (nfsd4_enc)nfsd4_encode_rename, +- [OP_RENEW] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_RESTOREFH] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_SAVEFH] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_SECINFO] = (nfsd4_enc)nfsd4_encode_secinfo, +- [OP_SETATTR] = (nfsd4_enc)nfsd4_encode_setattr, +- [OP_SETCLIENTID] = (nfsd4_enc)nfsd4_encode_setclientid, +- [OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_VERIFY] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_WRITE] = (nfsd4_enc)nfsd4_encode_write, +- [OP_RELEASE_LOCKOWNER] = (nfsd4_enc)nfsd4_encode_noop, ++ [OP_ACCESS] = nfsd4_encode_access, ++ [OP_CLOSE] = nfsd4_encode_close, ++ [OP_COMMIT] = nfsd4_encode_commit, ++ [OP_CREATE] = nfsd4_encode_create, ++ [OP_DELEGPURGE] = nfsd4_encode_noop, ++ [OP_DELEGRETURN] = nfsd4_encode_noop, ++ [OP_GETATTR] = nfsd4_encode_getattr, ++ [OP_GETFH] = nfsd4_encode_getfh, ++ [OP_LINK] = nfsd4_encode_link, ++ [OP_LOCK] = nfsd4_encode_lock, ++ [OP_LOCKT] = nfsd4_encode_lockt, ++ [OP_LOCKU] = nfsd4_encode_locku, ++ [OP_LOOKUP] = nfsd4_encode_noop, ++ [OP_LOOKUPP] = nfsd4_encode_noop, ++ [OP_NVERIFY] = nfsd4_encode_noop, ++ [OP_OPEN] = nfsd4_encode_open, ++ [OP_OPENATTR] = nfsd4_encode_noop, ++ [OP_OPEN_CONFIRM] = nfsd4_encode_open_confirm, ++ [OP_OPEN_DOWNGRADE] = nfsd4_encode_open_downgrade, ++ [OP_PUTFH] = nfsd4_encode_noop, ++ [OP_PUTPUBFH] = nfsd4_encode_noop, ++ [OP_PUTROOTFH] = nfsd4_encode_noop, ++ [OP_READ] = nfsd4_encode_read, ++ [OP_READDIR] = nfsd4_encode_readdir, ++ [OP_READLINK] = nfsd4_encode_readlink, ++ [OP_REMOVE] = nfsd4_encode_remove, ++ [OP_RENAME] = nfsd4_encode_rename, ++ [OP_RENEW] = nfsd4_encode_noop, ++ [OP_RESTOREFH] = nfsd4_encode_noop, ++ [OP_SAVEFH] = nfsd4_encode_noop, ++ [OP_SECINFO] = nfsd4_encode_secinfo, ++ [OP_SETATTR] = nfsd4_encode_setattr, ++ [OP_SETCLIENTID] = nfsd4_encode_setclientid, ++ [OP_SETCLIENTID_CONFIRM] = nfsd4_encode_noop, ++ [OP_VERIFY] = nfsd4_encode_noop, ++ [OP_WRITE] = nfsd4_encode_write, ++ [OP_RELEASE_LOCKOWNER] = nfsd4_encode_noop, + + /* NFSv4.1 operations */ +- [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session, +- [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id, +- [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session, +- [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop, ++ [OP_BACKCHANNEL_CTL] = nfsd4_encode_noop, ++ [OP_BIND_CONN_TO_SESSION] = nfsd4_encode_bind_conn_to_session, ++ [OP_EXCHANGE_ID] = nfsd4_encode_exchange_id, ++ [OP_CREATE_SESSION] = nfsd4_encode_create_session, ++ [OP_DESTROY_SESSION] = nfsd4_encode_noop, ++ [OP_FREE_STATEID] = nfsd4_encode_noop, ++ [OP_GET_DIR_DELEGATION] = nfsd4_encode_noop, + #ifdef CONFIG_NFSD_PNFS +- [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_getdeviceinfo, +- [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_layoutcommit, +- [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_layoutget, +- [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_layoutreturn, ++ [OP_GETDEVICEINFO] = nfsd4_encode_getdeviceinfo, ++ [OP_GETDEVICELIST] = nfsd4_encode_noop, ++ [OP_LAYOUTCOMMIT] = nfsd4_encode_layoutcommit, ++ [OP_LAYOUTGET] = nfsd4_encode_layoutget, ++ [OP_LAYOUTRETURN] = nfsd4_encode_layoutreturn, + #else +- [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop, ++ [OP_GETDEVICEINFO] = nfsd4_encode_noop, ++ [OP_GETDEVICELIST] = nfsd4_encode_noop, ++ [OP_LAYOUTCOMMIT] = nfsd4_encode_noop, ++ [OP_LAYOUTGET] = nfsd4_encode_noop, ++ [OP_LAYOUTRETURN] = nfsd4_encode_noop, + #endif +- [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo_no_name, +- [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence, +- [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_test_stateid, +- [OP_WANT_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_DESTROY_CLIENTID] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_RECLAIM_COMPLETE] = (nfsd4_enc)nfsd4_encode_noop, ++ [OP_SECINFO_NO_NAME] = nfsd4_encode_secinfo_no_name, ++ [OP_SEQUENCE] = nfsd4_encode_sequence, ++ [OP_SET_SSV] = nfsd4_encode_noop, ++ [OP_TEST_STATEID] = nfsd4_encode_test_stateid, ++ [OP_WANT_DELEGATION] = nfsd4_encode_noop, ++ [OP_DESTROY_CLIENTID] = nfsd4_encode_noop, ++ [OP_RECLAIM_COMPLETE] = nfsd4_encode_noop, + + /* NFSv4.2 operations */ +- [OP_ALLOCATE] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_COPY] = (nfsd4_enc)nfsd4_encode_copy, +- [OP_COPY_NOTIFY] = (nfsd4_enc)nfsd4_encode_copy_notify, +- [OP_DEALLOCATE] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_IO_ADVISE] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_LAYOUTERROR] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_LAYOUTSTATS] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_OFFLOAD_CANCEL] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_OFFLOAD_STATUS] = (nfsd4_enc)nfsd4_encode_offload_status, +- [OP_READ_PLUS] = (nfsd4_enc)nfsd4_encode_read_plus, +- [OP_SEEK] = (nfsd4_enc)nfsd4_encode_seek, +- [OP_WRITE_SAME] = (nfsd4_enc)nfsd4_encode_noop, +- [OP_CLONE] = (nfsd4_enc)nfsd4_encode_noop, ++ [OP_ALLOCATE] = nfsd4_encode_noop, ++ [OP_COPY] = nfsd4_encode_copy, ++ [OP_COPY_NOTIFY] = nfsd4_encode_copy_notify, ++ [OP_DEALLOCATE] = nfsd4_encode_noop, ++ [OP_IO_ADVISE] = nfsd4_encode_noop, ++ [OP_LAYOUTERROR] = nfsd4_encode_noop, ++ [OP_LAYOUTSTATS] = nfsd4_encode_noop, ++ [OP_OFFLOAD_CANCEL] = nfsd4_encode_noop, ++ [OP_OFFLOAD_STATUS] = nfsd4_encode_offload_status, ++ [OP_READ_PLUS] = nfsd4_encode_read_plus, ++ [OP_SEEK] = nfsd4_encode_seek, ++ [OP_WRITE_SAME] = nfsd4_encode_noop, ++ [OP_CLONE] = nfsd4_encode_noop, + + /* RFC 8276 extended atributes operations */ +- [OP_GETXATTR] = (nfsd4_enc)nfsd4_encode_getxattr, +- [OP_SETXATTR] = (nfsd4_enc)nfsd4_encode_setxattr, +- [OP_LISTXATTRS] = (nfsd4_enc)nfsd4_encode_listxattrs, +- [OP_REMOVEXATTR] = (nfsd4_enc)nfsd4_encode_removexattr, ++ [OP_GETXATTR] = nfsd4_encode_getxattr, ++ [OP_SETXATTR] = nfsd4_encode_setxattr, ++ [OP_LISTXATTRS] = nfsd4_encode_listxattrs, ++ [OP_REMOVEXATTR] = nfsd4_encode_removexattr, + }; + + /* diff --git a/queue-6.1/nfsd-clean-up-find_or_add_file.patch b/queue-6.1/nfsd-clean-up-find_or_add_file.patch new file mode 100644 index 00000000000..77f48b6bec2 --- /dev/null +++ b/queue-6.1/nfsd-clean-up-find_or_add_file.patch @@ -0,0 +1,123 @@ +From 51805844c0d7f3311515967959269b4f38278d31 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Fri, 28 Oct 2022 10:47:41 -0400 +Subject: NFSD: Clean up find_or_add_file() + +From: Chuck Lever + +[ Upstream commit 9270fc514ba7d415636b23bcb937573a1ce54f6a ] + +Remove the call to find_file_locked() in insert_nfs4_file(). Tracing +shows that over 99% of these calls return NULL. Thus it is not worth +the expense of the extra bucket list traversal. insert_file() already +deals correctly with the case where the item is already in the hash +bucket. + +Since nfsd4_file_hash_insert() is now just a wrapper around +insert_file(), move the meat of insert_file() into +nfsd4_file_hash_insert() and get rid of it. + +Signed-off-by: Chuck Lever +Reviewed-by: NeilBrown +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 64 ++++++++++++++++++++++------------------------------ + 1 file changed, 28 insertions(+), 36 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -4699,24 +4699,42 @@ find_file_locked(const struct svc_fh *fh + return NULL; + } + +-static struct nfs4_file *insert_file(struct nfs4_file *new, struct svc_fh *fh, +- unsigned int hashval) ++static struct nfs4_file * find_file(struct svc_fh *fh) + { + struct nfs4_file *fp; ++ unsigned int hashval = file_hashval(fh); ++ ++ rcu_read_lock(); ++ fp = find_file_locked(fh, hashval); ++ rcu_read_unlock(); ++ return fp; ++} ++ ++/* ++ * On hash insertion, identify entries with the same inode but ++ * distinct filehandles. They will all be in the same hash bucket ++ * because nfs4_file's are hashed by the address in the fi_inode ++ * field. ++ */ ++static noinline_for_stack struct nfs4_file * ++nfsd4_file_hash_insert(struct nfs4_file *new, const struct svc_fh *fhp) ++{ ++ unsigned int hashval = file_hashval(fhp); + struct nfs4_file *ret = NULL; + bool alias_found = false; ++ struct nfs4_file *fi; + + spin_lock(&state_lock); +- hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash, ++ hlist_for_each_entry_rcu(fi, &file_hashtbl[hashval], fi_hash, + lockdep_is_held(&state_lock)) { +- if (fh_match(&fp->fi_fhandle, &fh->fh_handle)) { +- if (refcount_inc_not_zero(&fp->fi_ref)) +- ret = fp; +- } else if (d_inode(fh->fh_dentry) == fp->fi_inode) +- fp->fi_aliased = alias_found = true; ++ if (fh_match(&fi->fi_fhandle, &fhp->fh_handle)) { ++ if (refcount_inc_not_zero(&fi->fi_ref)) ++ ret = fi; ++ } else if (d_inode(fhp->fh_dentry) == fi->fi_inode) ++ fi->fi_aliased = alias_found = true; + } + if (likely(ret == NULL)) { +- nfsd4_file_init(fh, new); ++ nfsd4_file_init(fhp, new); + hlist_add_head_rcu(&new->fi_hash, &file_hashtbl[hashval]); + new->fi_aliased = alias_found; + ret = new; +@@ -4725,32 +4743,6 @@ static struct nfs4_file *insert_file(str + return ret; + } + +-static struct nfs4_file * find_file(struct svc_fh *fh) +-{ +- struct nfs4_file *fp; +- unsigned int hashval = file_hashval(fh); +- +- rcu_read_lock(); +- fp = find_file_locked(fh, hashval); +- rcu_read_unlock(); +- return fp; +-} +- +-static struct nfs4_file * +-find_or_add_file(struct nfs4_file *new, struct svc_fh *fh) +-{ +- struct nfs4_file *fp; +- unsigned int hashval = file_hashval(fh); +- +- rcu_read_lock(); +- fp = find_file_locked(fh, hashval); +- rcu_read_unlock(); +- if (fp) +- return fp; +- +- return insert_file(new, fh, hashval); +-} +- + static noinline_for_stack void nfsd4_file_hash_remove(struct nfs4_file *fi) + { + hlist_del_rcu(&fi->fi_hash); +@@ -5661,7 +5653,7 @@ nfsd4_process_open2(struct svc_rqst *rqs + * and check for delegations in the process of being recalled. + * If not found, create the nfs4_file struct + */ +- fp = find_or_add_file(open->op_file, current_fh); ++ fp = nfsd4_file_hash_insert(open->op_file, current_fh); + if (fp != open->op_file) { + status = nfs4_check_deleg(cl, open, &dp); + if (status) diff --git a/queue-6.1/nfsd-clean-up-nfs4_preprocess_stateid_op-call-sites.patch b/queue-6.1/nfsd-clean-up-nfs4_preprocess_stateid_op-call-sites.patch new file mode 100644 index 00000000000..5b59f20b34f --- /dev/null +++ b/queue-6.1/nfsd-clean-up-nfs4_preprocess_stateid_op-call-sites.patch @@ -0,0 +1,106 @@ +From 757d584649721520e10e32a12d7919f5035e0334 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Fri, 28 Oct 2022 10:46:57 -0400 +Subject: NFSD: Clean up nfs4_preprocess_stateid_op() call sites + +From: Chuck Lever + +[ Upstream commit eeff73f7c1c583f79a401284f46c619294859310 ] + +Remove the lame-duck dprintk()s around nfs4_preprocess_stateid_op() +call sites. + +Signed-off-by: Chuck Lever +Tested-by: Jeff Layton +Reviewed-by: Jeff Layton +Reviewed-by: NeilBrown +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4proc.c | 31 +++++++------------------------ + 1 file changed, 7 insertions(+), 24 deletions(-) + +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -943,12 +943,7 @@ nfsd4_read(struct svc_rqst *rqstp, struc + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + &read->rd_stateid, RD_STATE, + &read->rd_nf, NULL); +- if (status) { +- dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); +- goto out; +- } +- status = nfs_ok; +-out: ++ + read->rd_rqstp = rqstp; + read->rd_fhp = &cstate->current_fh; + return status; +@@ -1117,10 +1112,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, st + status = nfs4_preprocess_stateid_op(rqstp, cstate, + &cstate->current_fh, &setattr->sa_stateid, + WR_STATE, NULL, NULL); +- if (status) { +- dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); ++ if (status) + return status; +- } + } + err = fh_want_write(&cstate->current_fh); + if (err) +@@ -1170,10 +1163,8 @@ nfsd4_write(struct svc_rqst *rqstp, stru + write->wr_offset, cnt); + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + stateid, WR_STATE, &nf, NULL); +- if (status) { +- dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); ++ if (status) + return status; +- } + + write->wr_how_written = write->wr_stable_how; + +@@ -1204,17 +1195,13 @@ nfsd4_verify_copy(struct svc_rqst *rqstp + + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh, + src_stateid, RD_STATE, src, NULL); +- if (status) { +- dprintk("NFSD: %s: couldn't process src stateid!\n", __func__); ++ if (status) + goto out; +- } + + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + dst_stateid, WR_STATE, dst, NULL); +- if (status) { +- dprintk("NFSD: %s: couldn't process dst stateid!\n", __func__); ++ if (status) + goto out_put_src; +- } + + /* fix up for NFS-specific error code */ + if (!S_ISREG(file_inode((*src)->nf_file)->i_mode) || +@@ -1935,10 +1922,8 @@ nfsd4_fallocate(struct svc_rqst *rqstp, + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + &fallocate->falloc_stateid, + WR_STATE, &nf, NULL); +- if (status != nfs_ok) { +- dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n"); ++ if (status != nfs_ok) + return status; +- } + + status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, nf->nf_file, + fallocate->falloc_offset, +@@ -1994,10 +1979,8 @@ nfsd4_seek(struct svc_rqst *rqstp, struc + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + &seek->seek_stateid, + RD_STATE, &nf, NULL); +- if (status) { +- dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n"); ++ if (status) + return status; +- } + + switch (seek->seek_whence) { + case NFS4_CONTENT_DATA: diff --git a/queue-6.1/nfsd-clean-up-nfsd4_init_file.patch b/queue-6.1/nfsd-clean-up-nfsd4_init_file.patch new file mode 100644 index 00000000000..72e8059eef2 --- /dev/null +++ b/queue-6.1/nfsd-clean-up-nfsd4_init_file.patch @@ -0,0 +1,61 @@ +From 4ff0477fc99f1f54c18bb867bf4b4fcfc752a090 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Fri, 28 Oct 2022 10:47:28 -0400 +Subject: NFSD: Clean up nfsd4_init_file() + +From: Chuck Lever + +[ Upstream commit 81a21fa3e7fdecb3c5b97014f0fc5a17d5806cae ] + +Name this function more consistently. I'm going to use nfsd4_file_ +and nfsd4_file_hash_ for these helpers. + +Change the @fh parameter to be const pointer for better type safety. + +Finally, move the hash insertion operation to the caller. This is +typical for most other "init_object" type helpers, and it is where +most of the other nfs4_file hash table operations are located. + +Signed-off-by: Chuck Lever +Reviewed-by: NeilBrown +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -4278,11 +4278,9 @@ static struct nfs4_file *nfsd4_alloc_fil + } + + /* OPEN Share state helper functions */ +-static void nfsd4_init_file(struct svc_fh *fh, unsigned int hashval, +- struct nfs4_file *fp) +-{ +- lockdep_assert_held(&state_lock); + ++static void nfsd4_file_init(const struct svc_fh *fh, struct nfs4_file *fp) ++{ + refcount_set(&fp->fi_ref, 1); + spin_lock_init(&fp->fi_lock); + INIT_LIST_HEAD(&fp->fi_stateids); +@@ -4300,7 +4298,6 @@ static void nfsd4_init_file(struct svc_f + INIT_LIST_HEAD(&fp->fi_lo_states); + atomic_set(&fp->fi_lo_recalls, 0); + #endif +- hlist_add_head_rcu(&fp->fi_hash, &file_hashtbl[hashval]); + } + + void +@@ -4718,7 +4715,8 @@ static struct nfs4_file *insert_file(str + fp->fi_aliased = alias_found = true; + } + if (likely(ret == NULL)) { +- nfsd4_init_file(fh, hashval, new); ++ nfsd4_file_init(fh, new); ++ hlist_add_head_rcu(&new->fi_hash, &file_hashtbl[hashval]); + new->fi_aliased = alias_found; + ret = new; + } diff --git a/queue-6.1/nfsd-don-t-destroy-global-nfs4_file-table-in-per-net-shutdown.patch b/queue-6.1/nfsd-don-t-destroy-global-nfs4_file-table-in-per-net-shutdown.patch new file mode 100644 index 00000000000..4994ca31926 --- /dev/null +++ b/queue-6.1/nfsd-don-t-destroy-global-nfs4_file-table-in-per-net-shutdown.patch @@ -0,0 +1,42 @@ +From a6bc8b37ffcdf3cbd880a5725b717c4c215b7196 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Sat, 11 Feb 2023 07:50:08 -0500 +Subject: nfsd: don't destroy global nfs4_file table in per-net shutdown + +From: Jeff Layton + +[ Upstream commit 4102db175b5d884d133270fdbd0e59111ce688fc ] + +The nfs4_file table is global, so shutting it down when a containerized +nfsd is shut down is wrong and can lead to double-frees. Tear down the +nfs4_file_rhltable in nfs4_state_shutdown instead of +nfs4_state_shutdown_net. + +Fixes: d47b295e8d76 ("NFSD: Use rhashtable for managing nfs4_file objects") +Link: https://bugzilla.redhat.com/show_bug.cgi?id=2169017 +Reported-by: JianHong Yin +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -8212,7 +8212,6 @@ nfs4_state_shutdown_net(struct net *net) + + nfsd4_client_tracking_exit(net); + nfs4_state_destroy_net(net); +- rhltable_destroy(&nfs4_file_rhltable); + #ifdef CONFIG_NFSD_V4_2_INTER_SSC + nfsd4_ssc_shutdown_umount(nn); + #endif +@@ -8222,6 +8221,7 @@ void + nfs4_state_shutdown(void) + { + nfsd4_destroy_callback_queue(); ++ rhltable_destroy(&nfs4_file_rhltable); + } + + static void diff --git a/queue-6.1/nfsd-fix-licensing-header-in-filecache.c.patch b/queue-6.1/nfsd-fix-licensing-header-in-filecache.c.patch new file mode 100644 index 00000000000..a57a7e51bc9 --- /dev/null +++ b/queue-6.1/nfsd-fix-licensing-header-in-filecache.c.patch @@ -0,0 +1,29 @@ +From 275fc0e08f2112b49b304af978f149b684d4ac14 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Mon, 31 Oct 2022 09:53:26 -0400 +Subject: NFSD: Fix licensing header in filecache.c + +From: Chuck Lever + +[ Upstream commit 3f054211b29c0fa06dfdcab402c795fd7e906be1 ] + +Add a missing SPDX header. + +Signed-off-by: Chuck Lever +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/filecache.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -1,5 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0 + /* +- * Open file cache. ++ * The NFSD open file cache. + * + * (c) 2015 - Jeff Layton + * diff --git a/queue-6.1/nfsd-fix-up-the-filecache-laundrette-scheduling.patch b/queue-6.1/nfsd-fix-up-the-filecache-laundrette-scheduling.patch new file mode 100644 index 00000000000..2b8f57e4e17 --- /dev/null +++ b/queue-6.1/nfsd-fix-up-the-filecache-laundrette-scheduling.patch @@ -0,0 +1,53 @@ +From 98f2fa4692468cd565264518f82d6d669e982547 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Wed, 2 Nov 2022 14:44:50 -0400 +Subject: nfsd: fix up the filecache laundrette scheduling + +From: Jeff Layton + +[ Upstream commit 22ae4c114f77b55a4c5036e8f70409a0799a08f8 ] + +We don't really care whether there are hashed entries when it comes to +scheduling the laundrette. They might all be non-gc entries, after all. +We only want to schedule it if there are entries on the LRU. + +Switch to using list_lru_count, and move the check into +nfsd_file_gc_worker. The other callsite in nfsd_file_put doesn't need to +count entries, since it only schedules the laundrette after adding an +entry to the LRU. + +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/filecache.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -211,12 +211,9 @@ static const struct rhashtable_params nf + static void + nfsd_file_schedule_laundrette(void) + { +- if ((atomic_read(&nfsd_file_rhash_tbl.nelems) == 0) || +- test_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 0) +- return; +- +- queue_delayed_work(system_wq, &nfsd_filecache_laundrette, +- NFSD_LAUNDRETTE_DELAY); ++ if (test_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags)) ++ queue_delayed_work(system_wq, &nfsd_filecache_laundrette, ++ NFSD_LAUNDRETTE_DELAY); + } + + static void +@@ -614,7 +611,8 @@ static void + nfsd_file_gc_worker(struct work_struct *work) + { + nfsd_file_gc(); +- nfsd_file_schedule_laundrette(); ++ if (list_lru_count(&nfsd_file_lru)) ++ nfsd_file_schedule_laundrette(); + } + + static unsigned long diff --git a/queue-6.1/nfsd-flesh-out-a-documenting-comment-for-filecache.c.patch b/queue-6.1/nfsd-flesh-out-a-documenting-comment-for-filecache.c.patch new file mode 100644 index 00000000000..5a00adac4c1 --- /dev/null +++ b/queue-6.1/nfsd-flesh-out-a-documenting-comment-for-filecache.c.patch @@ -0,0 +1,54 @@ +From 06d8447f0ae19330b1214367aa39fbd956dc4fee Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Tue, 1 Nov 2022 13:30:46 -0400 +Subject: NFSD: Flesh out a documenting comment for filecache.c + +From: Chuck Lever + +[ Upstream commit b3276c1f5b268ff56622e9e125b792b4c3dc03ac ] + +Record what we've learned recently about the NFSD filecache in a +documenting comment so our future selves don't forget what all this +is for. + +Signed-off-by: Chuck Lever +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/filecache.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -2,6 +2,30 @@ + * Open file cache. + * + * (c) 2015 - Jeff Layton ++ * ++ * An nfsd_file object is a per-file collection of open state that binds ++ * together: ++ * - a struct file * ++ * - a user credential ++ * - a network namespace ++ * - a read-ahead context ++ * - monitoring for writeback errors ++ * ++ * nfsd_file objects are reference-counted. Consumers acquire a new ++ * object via the nfsd_file_acquire API. They manage their interest in ++ * the acquired object, and hence the object's reference count, via ++ * nfsd_file_get and nfsd_file_put. There are two varieties of nfsd_file ++ * object: ++ * ++ * * non-garbage-collected: When a consumer wants to precisely control ++ * the lifetime of a file's open state, it acquires a non-garbage- ++ * collected nfsd_file. The final nfsd_file_put releases the open ++ * state immediately. ++ * ++ * * garbage-collected: When a consumer does not control the lifetime ++ * of open state, it acquires a garbage-collected nfsd_file. The ++ * final nfsd_file_put allows the open state to linger for a period ++ * during which it may be re-used. + */ + + #include diff --git a/queue-6.1/nfsd-ignore-requests-to-disable-unsupported-versions.patch b/queue-6.1/nfsd-ignore-requests-to-disable-unsupported-versions.patch new file mode 100644 index 00000000000..f69f9f92755 --- /dev/null +++ b/queue-6.1/nfsd-ignore-requests-to-disable-unsupported-versions.patch @@ -0,0 +1,35 @@ +From 8fdcafa904d391a0b4e26c8bcc9b7126676c4631 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Tue, 18 Oct 2022 07:47:54 -0400 +Subject: nfsd: ignore requests to disable unsupported versions + +From: Jeff Layton + +[ Upstream commit 8e823bafff2308753d430566256c83d8085952da ] + +The kernel currently errors out if you attempt to enable or disable a +version that it doesn't recognize. Change it to ignore attempts to +disable an unrecognized version. If we don't support it, then there is +no harm in doing so. + +Signed-off-by: Jeff Layton +Reviewed-by: Tom Talpey +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfsctl.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -601,7 +601,9 @@ static ssize_t __write_versions(struct f + } + break; + default: +- return -EINVAL; ++ /* Ignore requests to disable non-existent versions */ ++ if (cmd == NFSD_SET) ++ return -EINVAL; + } + vers += len + 1; + } while ((len = qword_get(&mesg, vers, size)) > 0); diff --git a/queue-6.1/nfsd-move-nfserrno-to-vfs.c.patch b/queue-6.1/nfsd-move-nfserrno-to-vfs.c.patch new file mode 100644 index 00000000000..e26f593f505 --- /dev/null +++ b/queue-6.1/nfsd-move-nfserrno-to-vfs.c.patch @@ -0,0 +1,231 @@ +From 7cc60aa13f695b5585a494331d16d0c7e31fc05f Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Tue, 18 Oct 2022 07:47:55 -0400 +Subject: nfsd: move nfserrno() to vfs.c + +From: Jeff Layton + +[ Upstream commit cb12fae1c34b1fa7eaae92c5aadc72d86d7fae19 ] + +nfserrno() is common to all nfs versions, but nfsproc.c is specifically +for NFSv2. Move it to vfs.c, and the prototype to vfs.h. + +While we're in here, remove the #ifdef EDQUOT check in this function. +It's apparently a holdover from the initial merge of the nfsd code in +1997. No other place in the kernel checks that that symbol is defined +before using it, so I think we can dispense with it here. + +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/blocklayout.c | 1 + fs/nfsd/blocklayoutxdr.c | 1 + fs/nfsd/export.h | 1 + fs/nfsd/flexfilelayout.c | 1 + fs/nfsd/nfs4idmap.c | 1 + fs/nfsd/nfsproc.c | 62 ---------------------------------------------- + fs/nfsd/vfs.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++ + fs/nfsd/vfs.h | 1 + 8 files changed, 68 insertions(+), 63 deletions(-) + +--- a/fs/nfsd/blocklayout.c ++++ b/fs/nfsd/blocklayout.c +@@ -12,6 +12,7 @@ + #include "blocklayoutxdr.h" + #include "pnfs.h" + #include "filecache.h" ++#include "vfs.h" + + #define NFSDDBG_FACILITY NFSDDBG_PNFS + +--- a/fs/nfsd/blocklayoutxdr.c ++++ b/fs/nfsd/blocklayoutxdr.c +@@ -9,6 +9,7 @@ + + #include "nfsd.h" + #include "blocklayoutxdr.h" ++#include "vfs.h" + + #define NFSDDBG_FACILITY NFSDDBG_PNFS + +--- a/fs/nfsd/export.h ++++ b/fs/nfsd/export.h +@@ -115,7 +115,6 @@ struct svc_export * rqst_find_fsidzero_e + int exp_rootfh(struct net *, struct auth_domain *, + char *path, struct knfsd_fh *, int maxsize); + __be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *); +-__be32 nfserrno(int errno); + + static inline void exp_put(struct svc_export *exp) + { +--- a/fs/nfsd/flexfilelayout.c ++++ b/fs/nfsd/flexfilelayout.c +@@ -15,6 +15,7 @@ + + #include "flexfilelayoutxdr.h" + #include "pnfs.h" ++#include "vfs.h" + + #define NFSDDBG_FACILITY NFSDDBG_PNFS + +--- a/fs/nfsd/nfs4idmap.c ++++ b/fs/nfsd/nfs4idmap.c +@@ -41,6 +41,7 @@ + #include "idmap.h" + #include "nfsd.h" + #include "netns.h" ++#include "vfs.h" + + /* + * Turn off idmapping when using AUTH_SYS. +--- a/fs/nfsd/nfsproc.c ++++ b/fs/nfsd/nfsproc.c +@@ -848,65 +848,3 @@ const struct svc_version nfsd_version2 = + .vs_dispatch = nfsd_dispatch, + .vs_xdrsize = NFS2_SVC_XDRSIZE, + }; +- +-/* +- * Map errnos to NFS errnos. +- */ +-__be32 +-nfserrno (int errno) +-{ +- static struct { +- __be32 nfserr; +- int syserr; +- } nfs_errtbl[] = { +- { nfs_ok, 0 }, +- { nfserr_perm, -EPERM }, +- { nfserr_noent, -ENOENT }, +- { nfserr_io, -EIO }, +- { nfserr_nxio, -ENXIO }, +- { nfserr_fbig, -E2BIG }, +- { nfserr_stale, -EBADF }, +- { nfserr_acces, -EACCES }, +- { nfserr_exist, -EEXIST }, +- { nfserr_xdev, -EXDEV }, +- { nfserr_mlink, -EMLINK }, +- { nfserr_nodev, -ENODEV }, +- { nfserr_notdir, -ENOTDIR }, +- { nfserr_isdir, -EISDIR }, +- { nfserr_inval, -EINVAL }, +- { nfserr_fbig, -EFBIG }, +- { nfserr_nospc, -ENOSPC }, +- { nfserr_rofs, -EROFS }, +- { nfserr_mlink, -EMLINK }, +- { nfserr_nametoolong, -ENAMETOOLONG }, +- { nfserr_notempty, -ENOTEMPTY }, +-#ifdef EDQUOT +- { nfserr_dquot, -EDQUOT }, +-#endif +- { nfserr_stale, -ESTALE }, +- { nfserr_jukebox, -ETIMEDOUT }, +- { nfserr_jukebox, -ERESTARTSYS }, +- { nfserr_jukebox, -EAGAIN }, +- { nfserr_jukebox, -EWOULDBLOCK }, +- { nfserr_jukebox, -ENOMEM }, +- { nfserr_io, -ETXTBSY }, +- { nfserr_notsupp, -EOPNOTSUPP }, +- { nfserr_toosmall, -ETOOSMALL }, +- { nfserr_serverfault, -ESERVERFAULT }, +- { nfserr_serverfault, -ENFILE }, +- { nfserr_io, -EREMOTEIO }, +- { nfserr_stale, -EOPENSTALE }, +- { nfserr_io, -EUCLEAN }, +- { nfserr_perm, -ENOKEY }, +- { nfserr_no_grace, -ENOGRACE}, +- }; +- int i; +- +- for (i = 0; i < ARRAY_SIZE(nfs_errtbl); i++) { +- if (nfs_errtbl[i].syserr == errno) +- return nfs_errtbl[i].nfserr; +- } +- WARN_ONCE(1, "nfsd: non-standard errno: %d\n", errno); +- return nfserr_io; +-} +- +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -49,6 +49,69 @@ + + #define NFSDDBG_FACILITY NFSDDBG_FILEOP + ++/** ++ * nfserrno - Map Linux errnos to NFS errnos ++ * @errno: POSIX(-ish) error code to be mapped ++ * ++ * Returns the appropriate (net-endian) nfserr_* (or nfs_ok if errno is 0). If ++ * it's an error we don't expect, log it once and return nfserr_io. ++ */ ++__be32 ++nfserrno (int errno) ++{ ++ static struct { ++ __be32 nfserr; ++ int syserr; ++ } nfs_errtbl[] = { ++ { nfs_ok, 0 }, ++ { nfserr_perm, -EPERM }, ++ { nfserr_noent, -ENOENT }, ++ { nfserr_io, -EIO }, ++ { nfserr_nxio, -ENXIO }, ++ { nfserr_fbig, -E2BIG }, ++ { nfserr_stale, -EBADF }, ++ { nfserr_acces, -EACCES }, ++ { nfserr_exist, -EEXIST }, ++ { nfserr_xdev, -EXDEV }, ++ { nfserr_mlink, -EMLINK }, ++ { nfserr_nodev, -ENODEV }, ++ { nfserr_notdir, -ENOTDIR }, ++ { nfserr_isdir, -EISDIR }, ++ { nfserr_inval, -EINVAL }, ++ { nfserr_fbig, -EFBIG }, ++ { nfserr_nospc, -ENOSPC }, ++ { nfserr_rofs, -EROFS }, ++ { nfserr_mlink, -EMLINK }, ++ { nfserr_nametoolong, -ENAMETOOLONG }, ++ { nfserr_notempty, -ENOTEMPTY }, ++ { nfserr_dquot, -EDQUOT }, ++ { nfserr_stale, -ESTALE }, ++ { nfserr_jukebox, -ETIMEDOUT }, ++ { nfserr_jukebox, -ERESTARTSYS }, ++ { nfserr_jukebox, -EAGAIN }, ++ { nfserr_jukebox, -EWOULDBLOCK }, ++ { nfserr_jukebox, -ENOMEM }, ++ { nfserr_io, -ETXTBSY }, ++ { nfserr_notsupp, -EOPNOTSUPP }, ++ { nfserr_toosmall, -ETOOSMALL }, ++ { nfserr_serverfault, -ESERVERFAULT }, ++ { nfserr_serverfault, -ENFILE }, ++ { nfserr_io, -EREMOTEIO }, ++ { nfserr_stale, -EOPENSTALE }, ++ { nfserr_io, -EUCLEAN }, ++ { nfserr_perm, -ENOKEY }, ++ { nfserr_no_grace, -ENOGRACE}, ++ }; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(nfs_errtbl); i++) { ++ if (nfs_errtbl[i].syserr == errno) ++ return nfs_errtbl[i].nfserr; ++ } ++ WARN_ONCE(1, "nfsd: non-standard errno: %d\n", errno); ++ return nfserr_io; ++} ++ + /* + * Called from nfsd_lookup and encode_dirent. Check if we have crossed + * a mount point. +--- a/fs/nfsd/vfs.h ++++ b/fs/nfsd/vfs.h +@@ -60,6 +60,7 @@ static inline void nfsd_attrs_free(struc + posix_acl_release(attrs->na_dpacl); + } + ++__be32 nfserrno (int errno); + int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, + struct svc_export **expp); + __be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *, diff --git a/queue-6.1/nfsd-refactor-find_file.patch b/queue-6.1/nfsd-refactor-find_file.patch new file mode 100644 index 00000000000..b27b853c996 --- /dev/null +++ b/queue-6.1/nfsd-refactor-find_file.patch @@ -0,0 +1,80 @@ +From 77b17162b368c0ba3ac6f505cbee2d23a01d6294 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Fri, 28 Oct 2022 10:47:47 -0400 +Subject: NFSD: Refactor find_file() + +From: Chuck Lever + +[ Upstream commit 15424748001a9b5ea62b3e6ad45f0a8b27f01df9 ] + +find_file() is now the only caller of find_file_locked(), so just +fold these two together. + +Signed-off-by: Chuck Lever +Reviewed-by: NeilBrown +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 36 +++++++++++++++--------------------- + 1 file changed, 15 insertions(+), 21 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -4683,31 +4683,24 @@ move_to_close_lru(struct nfs4_ol_stateid + nfs4_put_stid(&last->st_stid); + } + +-/* search file_hashtbl[] for file */ +-static struct nfs4_file * +-find_file_locked(const struct svc_fh *fh, unsigned int hashval) ++static noinline_for_stack struct nfs4_file * ++nfsd4_file_hash_lookup(const struct svc_fh *fhp) + { +- struct nfs4_file *fp; ++ unsigned int hashval = file_hashval(fhp); ++ struct nfs4_file *fi; + +- hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash, +- lockdep_is_held(&state_lock)) { +- if (fh_match(&fp->fi_fhandle, &fh->fh_handle)) { +- if (refcount_inc_not_zero(&fp->fi_ref)) +- return fp; ++ rcu_read_lock(); ++ hlist_for_each_entry_rcu(fi, &file_hashtbl[hashval], fi_hash, ++ lockdep_is_held(&state_lock)) { ++ if (fh_match(&fi->fi_fhandle, &fhp->fh_handle)) { ++ if (refcount_inc_not_zero(&fi->fi_ref)) { ++ rcu_read_unlock(); ++ return fi; ++ } + } + } +- return NULL; +-} +- +-static struct nfs4_file * find_file(struct svc_fh *fh) +-{ +- struct nfs4_file *fp; +- unsigned int hashval = file_hashval(fh); +- +- rcu_read_lock(); +- fp = find_file_locked(fh, hashval); + rcu_read_unlock(); +- return fp; ++ return NULL; + } + + /* +@@ -4758,9 +4751,10 @@ nfs4_share_conflict(struct svc_fh *curre + struct nfs4_file *fp; + __be32 ret = nfs_ok; + +- fp = find_file(current_fh); ++ fp = nfsd4_file_hash_lookup(current_fh); + if (!fp) + return ret; ++ + /* Check for conflicting share reservations */ + spin_lock(&fp->fi_lock); + if (fp->fi_share_deny & deny_type) diff --git a/queue-6.1/nfsd-refactoring-courtesy_client_reaper-to-a-generic-low-memory-shrinker.patch b/queue-6.1/nfsd-refactoring-courtesy_client_reaper-to-a-generic-low-memory-shrinker.patch new file mode 100644 index 00000000000..3a642ce02f0 --- /dev/null +++ b/queue-6.1/nfsd-refactoring-courtesy_client_reaper-to-a-generic-low-memory-shrinker.patch @@ -0,0 +1,88 @@ +From 1644e0ed649c0f951c08c81853485cbbcb3d5eaf Mon Sep 17 00:00:00 2001 +From: Dai Ngo +Date: Wed, 16 Nov 2022 19:44:45 -0800 +Subject: NFSD: refactoring courtesy_client_reaper to a generic low memory shrinker + +From: Dai Ngo + +[ Upstream commit a1049eb47f20b9eabf9afb218578fff16b4baca6 ] + +Refactoring courtesy_client_reaper to generic low memory +shrinker so it can be used for other purposes. + +Signed-off-by: Dai Ngo +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 25 ++++++++++++++++--------- + 1 file changed, 16 insertions(+), 9 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -4362,7 +4362,7 @@ out: + } + + static unsigned long +-nfsd_courtesy_client_count(struct shrinker *shrink, struct shrink_control *sc) ++nfsd4_state_shrinker_count(struct shrinker *shrink, struct shrink_control *sc) + { + int cnt; + struct nfsd_net *nn = container_of(shrink, +@@ -4375,7 +4375,7 @@ nfsd_courtesy_client_count(struct shrink + } + + static unsigned long +-nfsd_courtesy_client_scan(struct shrinker *shrink, struct shrink_control *sc) ++nfsd4_state_shrinker_scan(struct shrinker *shrink, struct shrink_control *sc) + { + return SHRINK_STOP; + } +@@ -4402,8 +4402,8 @@ nfsd4_init_leases_net(struct nfsd_net *n + nn->nfs4_max_clients = max_t(int, max_clients, NFS4_CLIENTS_PER_GB); + + atomic_set(&nn->nfsd_courtesy_clients, 0); +- nn->nfsd_client_shrinker.scan_objects = nfsd_courtesy_client_scan; +- nn->nfsd_client_shrinker.count_objects = nfsd_courtesy_client_count; ++ nn->nfsd_client_shrinker.scan_objects = nfsd4_state_shrinker_scan; ++ nn->nfsd_client_shrinker.count_objects = nfsd4_state_shrinker_count; + nn->nfsd_client_shrinker.seeks = DEFAULT_SEEKS; + return register_shrinker(&nn->nfsd_client_shrinker, "nfsd-client"); + } +@@ -6171,17 +6171,24 @@ laundromat_main(struct work_struct *laun + } + + static void +-courtesy_client_reaper(struct work_struct *reaper) ++courtesy_client_reaper(struct nfsd_net *nn) + { + struct list_head reaplist; +- struct delayed_work *dwork = to_delayed_work(reaper); +- struct nfsd_net *nn = container_of(dwork, struct nfsd_net, +- nfsd_shrinker_work); + + nfs4_get_courtesy_client_reaplist(nn, &reaplist); + nfs4_process_client_reaplist(&reaplist); + } + ++static void ++nfsd4_state_shrinker_worker(struct work_struct *work) ++{ ++ struct delayed_work *dwork = to_delayed_work(work); ++ struct nfsd_net *nn = container_of(dwork, struct nfsd_net, ++ nfsd_shrinker_work); ++ ++ courtesy_client_reaper(nn); ++} ++ + static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stid *stp) + { + if (!fh_match(&fhp->fh_handle, &stp->sc_file->fi_fhandle)) +@@ -8007,7 +8014,7 @@ static int nfs4_state_create_net(struct + INIT_LIST_HEAD(&nn->blocked_locks_lru); + + INIT_DELAYED_WORK(&nn->laundromat_work, laundromat_main); +- INIT_DELAYED_WORK(&nn->nfsd_shrinker_work, courtesy_client_reaper); ++ INIT_DELAYED_WORK(&nn->nfsd_shrinker_work, nfsd4_state_shrinker_worker); + get_net(net); + + return 0; diff --git a/queue-6.1/nfsd-register-unregister-of-nfsd-client-shrinker-at-nfsd-startup-shutdown-time.patch b/queue-6.1/nfsd-register-unregister-of-nfsd-client-shrinker-at-nfsd-startup-shutdown-time.patch new file mode 100644 index 00000000000..1a2d399e840 --- /dev/null +++ b/queue-6.1/nfsd-register-unregister-of-nfsd-client-shrinker-at-nfsd-startup-shutdown-time.patch @@ -0,0 +1,136 @@ +From 11c632570a2654947799ddc6d16db0780d2232c2 Mon Sep 17 00:00:00 2001 +From: Dai Ngo +Date: Wed, 11 Jan 2023 12:17:09 -0800 +Subject: NFSD: register/unregister of nfsd-client shrinker at nfsd startup/shutdown time + +From: Dai Ngo + +[ Upstream commit f385f7d244134246f984975ed34cd75f77de479f ] + +Currently the nfsd-client shrinker is registered and unregistered at +the time the nfsd module is loaded and unloaded. The problem with this +is the shrinker is being registered before all of the relevant fields +in nfsd_net are initialized when nfsd is started. This can lead to an +oops when memory is low and the shrinker is called while nfsd is not +running. + +This patch moves the register/unregister of nfsd-client shrinker from +module load/unload time to nfsd startup/shutdown time. + +Fixes: 44df6f439a17 ("NFSD: add delegation reaper to react to low memory condition") +Reported-by: Mike Galbraith +Signed-off-by: Dai Ngo +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 22 +++++++++++----------- + fs/nfsd/nfsctl.c | 7 +------ + fs/nfsd/nfsd.h | 6 ++---- + 3 files changed, 14 insertions(+), 21 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -4422,7 +4422,7 @@ nfsd4_state_shrinker_scan(struct shrinke + return SHRINK_STOP; + } + +-int ++void + nfsd4_init_leases_net(struct nfsd_net *nn) + { + struct sysinfo si; +@@ -4444,16 +4444,6 @@ nfsd4_init_leases_net(struct nfsd_net *n + nn->nfs4_max_clients = max_t(int, max_clients, NFS4_CLIENTS_PER_GB); + + atomic_set(&nn->nfsd_courtesy_clients, 0); +- nn->nfsd_client_shrinker.scan_objects = nfsd4_state_shrinker_scan; +- nn->nfsd_client_shrinker.count_objects = nfsd4_state_shrinker_count; +- nn->nfsd_client_shrinker.seeks = DEFAULT_SEEKS; +- return register_shrinker(&nn->nfsd_client_shrinker, "nfsd-client"); +-} +- +-void +-nfsd4_leases_net_shutdown(struct nfsd_net *nn) +-{ +- unregister_shrinker(&nn->nfsd_client_shrinker); + } + + static void init_nfs4_replay(struct nfs4_replay *rp) +@@ -8099,8 +8089,17 @@ static int nfs4_state_create_net(struct + INIT_DELAYED_WORK(&nn->nfsd_shrinker_work, nfsd4_state_shrinker_worker); + get_net(net); + ++ nn->nfsd_client_shrinker.scan_objects = nfsd4_state_shrinker_scan; ++ nn->nfsd_client_shrinker.count_objects = nfsd4_state_shrinker_count; ++ nn->nfsd_client_shrinker.seeks = DEFAULT_SEEKS; ++ ++ if (register_shrinker(&nn->nfsd_client_shrinker, "nfsd-client")) ++ goto err_shrinker; + return 0; + ++err_shrinker: ++ put_net(net); ++ kfree(nn->sessionid_hashtbl); + err_sessionid: + kfree(nn->unconf_id_hashtbl); + err_unconf_id: +@@ -8193,6 +8192,7 @@ nfs4_state_shutdown_net(struct net *net) + struct list_head *pos, *next, reaplist; + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + ++ unregister_shrinker(&nn->nfsd_client_shrinker); + cancel_delayed_work_sync(&nn->laundromat_work); + locks_end_grace(&nn->nfsd4_manager); + +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -1452,9 +1452,7 @@ static __net_init int nfsd_init_net(stru + goto out_idmap_error; + nn->nfsd_versions = NULL; + nn->nfsd4_minorversions = NULL; +- retval = nfsd4_init_leases_net(nn); +- if (retval) +- goto out_drc_error; ++ nfsd4_init_leases_net(nn); + retval = nfsd_reply_cache_init(nn); + if (retval) + goto out_cache_error; +@@ -1464,8 +1462,6 @@ static __net_init int nfsd_init_net(stru + return 0; + + out_cache_error: +- nfsd4_leases_net_shutdown(nn); +-out_drc_error: + nfsd_idmap_shutdown(net); + out_idmap_error: + nfsd_export_shutdown(net); +@@ -1481,7 +1477,6 @@ static __net_exit void nfsd_exit_net(str + nfsd_idmap_shutdown(net); + nfsd_export_shutdown(net); + nfsd_netns_free_versions(net_generic(net, nfsd_net_id)); +- nfsd4_leases_net_shutdown(nn); + } + + static struct pernet_operations nfsd_net_ops = { +--- a/fs/nfsd/nfsd.h ++++ b/fs/nfsd/nfsd.h +@@ -504,8 +504,7 @@ extern void unregister_cld_notifier(void + extern void nfsd4_ssc_init_umount_work(struct nfsd_net *nn); + #endif + +-extern int nfsd4_init_leases_net(struct nfsd_net *nn); +-extern void nfsd4_leases_net_shutdown(struct nfsd_net *nn); ++extern void nfsd4_init_leases_net(struct nfsd_net *nn); + + #else /* CONFIG_NFSD_V4 */ + static inline int nfsd4_is_junction(struct dentry *dentry) +@@ -513,8 +512,7 @@ static inline int nfsd4_is_junction(stru + return 0; + } + +-static inline int nfsd4_init_leases_net(struct nfsd_net *nn) { return 0; }; +-static inline void nfsd4_leases_net_shutdown(struct nfsd_net *nn) {}; ++static inline void nfsd4_init_leases_net(struct nfsd_net *nn) { }; + + #define register_cld_notifier() 0 + #define unregister_cld_notifier() do { } while(0) diff --git a/queue-6.1/nfsd-remove-redundant-assignment-to-variable-host_err.patch b/queue-6.1/nfsd-remove-redundant-assignment-to-variable-host_err.patch new file mode 100644 index 00000000000..d06efc80aa4 --- /dev/null +++ b/queue-6.1/nfsd-remove-redundant-assignment-to-variable-host_err.patch @@ -0,0 +1,34 @@ +From 2e3aa79f392f5bfca11a1dbbdf422bc088a1a65a Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Mon, 10 Oct 2022 21:24:23 +0100 +Subject: NFSD: Remove redundant assignment to variable host_err + +From: Colin Ian King + +[ Upstream commit 69eed23baf877bbb1f14d7f4df54f89807c9ee2a ] + +Variable host_err is assigned a value that is never read, it is being +re-assigned a value in every different execution path in the following +switch statement. The assignment is redundant and can be removed. + +Cleans up clang-scan warning: +warning: Value stored to 'host_err' is never read [deadcode.DeadStores] + +Signed-off-by: Colin Ian King +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/vfs.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -1317,7 +1317,6 @@ nfsd_create_locked(struct svc_rqst *rqst + iap->ia_mode &= ~current_umask(); + + err = 0; +- host_err = 0; + switch (type) { + case S_IFREG: + host_err = vfs_create(&init_user_ns, dirp, dchild, iap->ia_mode, true); diff --git a/queue-6.1/nfsd-replace-delayed_work-with-work_struct-for-nfsd_client_shrinker.patch b/queue-6.1/nfsd-replace-delayed_work-with-work_struct-for-nfsd_client_shrinker.patch new file mode 100644 index 00000000000..6f6b2617a0f --- /dev/null +++ b/queue-6.1/nfsd-replace-delayed_work-with-work_struct-for-nfsd_client_shrinker.patch @@ -0,0 +1,74 @@ +From da15771ea07c26181d5eece014d9336ff7ff6d07 Mon Sep 17 00:00:00 2001 +From: Dai Ngo +Date: Wed, 11 Jan 2023 16:06:51 -0800 +Subject: NFSD: replace delayed_work with work_struct for nfsd_client_shrinker + +From: Dai Ngo + +[ Upstream commit 7c24fa225081f31bc6da6a355c1ba801889ab29a ] + +Since nfsd4_state_shrinker_count always calls mod_delayed_work with +0 delay, we can replace delayed_work with work_struct to save some +space and overhead. + +Also add the call to cancel_work after unregister the shrinker +in nfs4_state_shutdown_net. + +Signed-off-by: Dai Ngo +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/netns.h | 2 +- + fs/nfsd/nfs4state.c | 8 ++++---- + 2 files changed, 5 insertions(+), 5 deletions(-) + +--- a/fs/nfsd/netns.h ++++ b/fs/nfsd/netns.h +@@ -195,7 +195,7 @@ struct nfsd_net { + + atomic_t nfsd_courtesy_clients; + struct shrinker nfsd_client_shrinker; +- struct delayed_work nfsd_shrinker_work; ++ struct work_struct nfsd_shrinker_work; + }; + + /* Simple check to find out if a given net was properly initialized */ +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -4412,7 +4412,7 @@ nfsd4_state_shrinker_count(struct shrink + if (!count) + count = atomic_long_read(&num_delegations); + if (count) +- mod_delayed_work(laundry_wq, &nn->nfsd_shrinker_work, 0); ++ queue_work(laundry_wq, &nn->nfsd_shrinker_work); + return (unsigned long)count; + } + +@@ -6253,8 +6253,7 @@ deleg_reaper(struct nfsd_net *nn) + static void + nfsd4_state_shrinker_worker(struct work_struct *work) + { +- struct delayed_work *dwork = to_delayed_work(work); +- struct nfsd_net *nn = container_of(dwork, struct nfsd_net, ++ struct nfsd_net *nn = container_of(work, struct nfsd_net, + nfsd_shrinker_work); + + courtesy_client_reaper(nn); +@@ -8086,7 +8085,7 @@ static int nfs4_state_create_net(struct + INIT_LIST_HEAD(&nn->blocked_locks_lru); + + INIT_DELAYED_WORK(&nn->laundromat_work, laundromat_main); +- INIT_DELAYED_WORK(&nn->nfsd_shrinker_work, nfsd4_state_shrinker_worker); ++ INIT_WORK(&nn->nfsd_shrinker_work, nfsd4_state_shrinker_worker); + get_net(net); + + nn->nfsd_client_shrinker.scan_objects = nfsd4_state_shrinker_scan; +@@ -8193,6 +8192,7 @@ nfs4_state_shutdown_net(struct net *net) + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + + unregister_shrinker(&nn->nfsd_client_shrinker); ++ cancel_work(&nn->nfsd_shrinker_work); + cancel_delayed_work_sync(&nn->laundromat_work); + locks_end_grace(&nn->nfsd4_manager); + diff --git a/queue-6.1/nfsd-simplify-read_plus.patch b/queue-6.1/nfsd-simplify-read_plus.patch new file mode 100644 index 00000000000..a4ac0864955 --- /dev/null +++ b/queue-6.1/nfsd-simplify-read_plus.patch @@ -0,0 +1,205 @@ +From 46a3747d8b4e5aa83a6f8cc8adbad5c1643a69a1 Mon Sep 17 00:00:00 2001 +From: Anna Schumaker +Date: Tue, 13 Sep 2022 14:01:51 -0400 +Subject: NFSD: Simplify READ_PLUS + +From: Anna Schumaker + +[ Upstream commit eeadcb75794516839078c28b3730132aeb700ce6 ] + +Chuck had suggested reverting READ_PLUS so it returns a single DATA +segment covering the requested read range. This prepares the server for +a future "sparse read" function so support can easily be added without +needing to rip out the old READ_PLUS code at the same time. + +Signed-off-by: Anna Schumaker +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4xdr.c | 139 ++++++++++++------------------------------------------ + 1 file changed, 32 insertions(+), 107 deletions(-) + +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -4777,79 +4777,37 @@ nfsd4_encode_offload_status(struct nfsd4 + + static __be32 + nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp, +- struct nfsd4_read *read, +- unsigned long *maxcount, u32 *eof, +- loff_t *pos) ++ struct nfsd4_read *read) + { +- struct xdr_stream *xdr = resp->xdr; ++ bool splice_ok = test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags); + struct file *file = read->rd_nf->nf_file; +- int starting_len = xdr->buf->len; +- loff_t hole_pos; +- __be32 nfserr; +- __be32 *p, tmp; +- __be64 tmp64; +- +- hole_pos = pos ? *pos : vfs_llseek(file, read->rd_offset, SEEK_HOLE); +- if (hole_pos > read->rd_offset) +- *maxcount = min_t(unsigned long, *maxcount, hole_pos - read->rd_offset); +- *maxcount = min_t(unsigned long, *maxcount, (xdr->buf->buflen - xdr->buf->len)); ++ struct xdr_stream *xdr = resp->xdr; ++ unsigned long maxcount; ++ __be32 nfserr, *p; + + /* Content type, offset, byte count */ + p = xdr_reserve_space(xdr, 4 + 8 + 4); + if (!p) +- return nfserr_resource; ++ return nfserr_io; ++ if (resp->xdr->buf->page_len && splice_ok) { ++ WARN_ON_ONCE(splice_ok); ++ return nfserr_serverfault; ++ } + +- read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, *maxcount); +- if (read->rd_vlen < 0) +- return nfserr_resource; ++ maxcount = min_t(unsigned long, read->rd_length, ++ (xdr->buf->buflen - xdr->buf->len)); + +- nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset, +- resp->rqstp->rq_vec, read->rd_vlen, maxcount, eof); ++ if (file->f_op->splice_read && splice_ok) ++ nfserr = nfsd4_encode_splice_read(resp, read, file, maxcount); ++ else ++ nfserr = nfsd4_encode_readv(resp, read, file, maxcount); + if (nfserr) + return nfserr; +- xdr_truncate_encode(xdr, starting_len + 16 + xdr_align_size(*maxcount)); +- +- tmp = htonl(NFS4_CONTENT_DATA); +- write_bytes_to_xdr_buf(xdr->buf, starting_len, &tmp, 4); +- tmp64 = cpu_to_be64(read->rd_offset); +- write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp64, 8); +- tmp = htonl(*maxcount); +- write_bytes_to_xdr_buf(xdr->buf, starting_len + 12, &tmp, 4); +- +- tmp = xdr_zero; +- write_bytes_to_xdr_buf(xdr->buf, starting_len + 16 + *maxcount, &tmp, +- xdr_pad_size(*maxcount)); +- return nfs_ok; +-} +- +-static __be32 +-nfsd4_encode_read_plus_hole(struct nfsd4_compoundres *resp, +- struct nfsd4_read *read, +- unsigned long *maxcount, u32 *eof) +-{ +- struct file *file = read->rd_nf->nf_file; +- loff_t data_pos = vfs_llseek(file, read->rd_offset, SEEK_DATA); +- loff_t f_size = i_size_read(file_inode(file)); +- unsigned long count; +- __be32 *p; +- +- if (data_pos == -ENXIO) +- data_pos = f_size; +- else if (data_pos <= read->rd_offset || (data_pos < f_size && data_pos % PAGE_SIZE)) +- return nfsd4_encode_read_plus_data(resp, read, maxcount, eof, &f_size); +- count = data_pos - read->rd_offset; + +- /* Content type, offset, byte count */ +- p = xdr_reserve_space(resp->xdr, 4 + 8 + 8); +- if (!p) +- return nfserr_resource; +- +- *p++ = htonl(NFS4_CONTENT_HOLE); ++ *p++ = cpu_to_be32(NFS4_CONTENT_DATA); + p = xdr_encode_hyper(p, read->rd_offset); +- p = xdr_encode_hyper(p, count); ++ *p = cpu_to_be32(read->rd_length); + +- *eof = (read->rd_offset + count) >= f_size; +- *maxcount = min_t(unsigned long, count, *maxcount); + return nfs_ok; + } + +@@ -4857,69 +4815,36 @@ static __be32 + nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr, + struct nfsd4_read *read) + { +- unsigned long maxcount, count; ++ struct file *file = read->rd_nf->nf_file; + struct xdr_stream *xdr = resp->xdr; +- struct file *file; + int starting_len = xdr->buf->len; +- int last_segment = xdr->buf->len; +- int segments = 0; +- __be32 *p, tmp; +- bool is_data; +- loff_t pos; +- u32 eof; ++ u32 segments = 0; ++ __be32 *p; + + if (nfserr) + return nfserr; +- file = read->rd_nf->nf_file; + + /* eof flag, segment count */ + p = xdr_reserve_space(xdr, 4 + 4); + if (!p) +- return nfserr_resource; ++ return nfserr_io; + xdr_commit_encode(xdr); + +- maxcount = min_t(unsigned long, read->rd_length, +- (xdr->buf->buflen - xdr->buf->len)); +- count = maxcount; +- +- eof = read->rd_offset >= i_size_read(file_inode(file)); +- if (eof) ++ read->rd_eof = read->rd_offset >= i_size_read(file_inode(file)); ++ if (read->rd_eof) + goto out; + +- pos = vfs_llseek(file, read->rd_offset, SEEK_HOLE); +- is_data = pos > read->rd_offset; +- +- while (count > 0 && !eof) { +- maxcount = count; +- if (is_data) +- nfserr = nfsd4_encode_read_plus_data(resp, read, &maxcount, &eof, +- segments == 0 ? &pos : NULL); +- else +- nfserr = nfsd4_encode_read_plus_hole(resp, read, &maxcount, &eof); +- if (nfserr) +- goto out; +- count -= maxcount; +- read->rd_offset += maxcount; +- is_data = !is_data; +- last_segment = xdr->buf->len; +- segments++; +- } +- +-out: +- if (nfserr && segments == 0) ++ nfserr = nfsd4_encode_read_plus_data(resp, read); ++ if (nfserr) { + xdr_truncate_encode(xdr, starting_len); +- else { +- if (nfserr) { +- xdr_truncate_encode(xdr, last_segment); +- nfserr = nfs_ok; +- eof = 0; +- } +- tmp = htonl(eof); +- write_bytes_to_xdr_buf(xdr->buf, starting_len, &tmp, 4); +- tmp = htonl(segments); +- write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp, 4); ++ return nfserr; + } + ++ segments++; ++ ++out: ++ p = xdr_encode_bool(p, read->rd_eof); ++ *p = cpu_to_be32(segments); + return nfserr; + } + diff --git a/queue-6.1/nfsd-trace-delegation-revocations.patch b/queue-6.1/nfsd-trace-delegation-revocations.patch new file mode 100644 index 00000000000..983e6d0c2a3 --- /dev/null +++ b/queue-6.1/nfsd-trace-delegation-revocations.patch @@ -0,0 +1,103 @@ +From b41a2f6cb1d1aeea3275b6a96504ea5dc82b0012 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Fri, 28 Oct 2022 10:47:09 -0400 +Subject: NFSD: Trace delegation revocations + +From: Chuck Lever + +[ Upstream commit a1c74569bbde91299f24535abf711be5c84df9de ] + +Delegation revocation is an exceptional event that is not otherwise +visible externally (eg, no network traffic is emitted). Generate a +trace record when it occurs so that revocation can be observed or +other activity can be triggered. Example: + +nfsd-1104 [005] 1912.002544: nfsd_stid_revoke: client 633c9343:4e82788d stateid 00000003:00000001 ref=2 type=DELEG + +Trace infrastructure is provided for subsequent additional tracing +related to nfs4_stid activity. + +Signed-off-by: Chuck Lever +Tested-by: Jeff Layton +Reviewed-by: Jeff Layton +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 2 + + fs/nfsd/trace.h | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 57 insertions(+) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -1367,6 +1367,8 @@ static void revoke_delegation(struct nfs + + WARN_ON(!list_empty(&dp->dl_recall_lru)); + ++ trace_nfsd_stid_revoke(&dp->dl_stid); ++ + if (clp->cl_minorversion) { + spin_lock(&clp->cl_lock); + dp->dl_stid.sc_type = NFS4_REVOKED_DELEG_STID; +--- a/fs/nfsd/trace.h ++++ b/fs/nfsd/trace.h +@@ -637,6 +637,61 @@ DEFINE_EVENT(nfsd_stateseqid_class, nfsd + DEFINE_STATESEQID_EVENT(preprocess); + DEFINE_STATESEQID_EVENT(open_confirm); + ++TRACE_DEFINE_ENUM(NFS4_OPEN_STID); ++TRACE_DEFINE_ENUM(NFS4_LOCK_STID); ++TRACE_DEFINE_ENUM(NFS4_DELEG_STID); ++TRACE_DEFINE_ENUM(NFS4_CLOSED_STID); ++TRACE_DEFINE_ENUM(NFS4_REVOKED_DELEG_STID); ++TRACE_DEFINE_ENUM(NFS4_CLOSED_DELEG_STID); ++TRACE_DEFINE_ENUM(NFS4_LAYOUT_STID); ++ ++#define show_stid_type(x) \ ++ __print_flags(x, "|", \ ++ { NFS4_OPEN_STID, "OPEN" }, \ ++ { NFS4_LOCK_STID, "LOCK" }, \ ++ { NFS4_DELEG_STID, "DELEG" }, \ ++ { NFS4_CLOSED_STID, "CLOSED" }, \ ++ { NFS4_REVOKED_DELEG_STID, "REVOKED" }, \ ++ { NFS4_CLOSED_DELEG_STID, "CLOSED_DELEG" }, \ ++ { NFS4_LAYOUT_STID, "LAYOUT" }) ++ ++DECLARE_EVENT_CLASS(nfsd_stid_class, ++ TP_PROTO( ++ const struct nfs4_stid *stid ++ ), ++ TP_ARGS(stid), ++ TP_STRUCT__entry( ++ __field(unsigned long, sc_type) ++ __field(int, sc_count) ++ __field(u32, cl_boot) ++ __field(u32, cl_id) ++ __field(u32, si_id) ++ __field(u32, si_generation) ++ ), ++ TP_fast_assign( ++ const stateid_t *stp = &stid->sc_stateid; ++ ++ __entry->sc_type = stid->sc_type; ++ __entry->sc_count = refcount_read(&stid->sc_count); ++ __entry->cl_boot = stp->si_opaque.so_clid.cl_boot; ++ __entry->cl_id = stp->si_opaque.so_clid.cl_id; ++ __entry->si_id = stp->si_opaque.so_id; ++ __entry->si_generation = stp->si_generation; ++ ), ++ TP_printk("client %08x:%08x stateid %08x:%08x ref=%d type=%s", ++ __entry->cl_boot, __entry->cl_id, ++ __entry->si_id, __entry->si_generation, ++ __entry->sc_count, show_stid_type(__entry->sc_type) ++ ) ++); ++ ++#define DEFINE_STID_EVENT(name) \ ++DEFINE_EVENT(nfsd_stid_class, nfsd_stid_##name, \ ++ TP_PROTO(const struct nfs4_stid *stid), \ ++ TP_ARGS(stid)) ++ ++DEFINE_STID_EVENT(revoke); ++ + DECLARE_EVENT_CLASS(nfsd_clientid_class, + TP_PROTO(const clientid_t *clid), + TP_ARGS(clid), diff --git a/queue-6.1/nfsd-trace-stateids-returned-via-delegreturn.patch b/queue-6.1/nfsd-trace-stateids-returned-via-delegreturn.patch new file mode 100644 index 00000000000..76ad26e2946 --- /dev/null +++ b/queue-6.1/nfsd-trace-stateids-returned-via-delegreturn.patch @@ -0,0 +1,42 @@ +From 8bf3a8b39dca377e31a2fb35c6166bcd09e4c614 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Fri, 28 Oct 2022 10:47:03 -0400 +Subject: NFSD: Trace stateids returned via DELEGRETURN + +From: Chuck Lever + +[ Upstream commit 20eee313ff4b8a7e71ae9560f5c4ba27cd763005 ] + +Handing out a delegation stateid is recorded with the +nfsd_deleg_read tracepoint, but there isn't a matching tracepoint +for recording when the stateid is returned. + +Signed-off-by: Chuck Lever +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 1 + + fs/nfsd/trace.h | 1 + + 2 files changed, 2 insertions(+) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -6935,6 +6935,7 @@ nfsd4_delegreturn(struct svc_rqst *rqstp + if (status) + goto put_stateid; + ++ trace_nfsd_deleg_return(stateid); + wake_up_var(d_inode(cstate->current_fh.fh_dentry)); + destroy_delegation(dp); + put_stateid: +--- a/fs/nfsd/trace.h ++++ b/fs/nfsd/trace.h +@@ -604,6 +604,7 @@ DEFINE_STATEID_EVENT(layout_recall_relea + + DEFINE_STATEID_EVENT(open); + DEFINE_STATEID_EVENT(deleg_read); ++DEFINE_STATEID_EVENT(deleg_return); + DEFINE_STATEID_EVENT(deleg_recall); + + DECLARE_EVENT_CLASS(nfsd_stateseqid_class, diff --git a/queue-6.1/nfsd-update-file_hashtbl-helpers.patch b/queue-6.1/nfsd-update-file_hashtbl-helpers.patch new file mode 100644 index 00000000000..bce7a2e8dc1 --- /dev/null +++ b/queue-6.1/nfsd-update-file_hashtbl-helpers.patch @@ -0,0 +1,40 @@ +From 3ac41c7dc2312e3fd4ce27676c54c596f06981f4 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Fri, 28 Oct 2022 10:47:22 -0400 +Subject: NFSD: Update file_hashtbl() helpers + +From: Chuck Lever + +[ Upstream commit 3fe828caddd81e68e9d29353c6e9285a658ca056 ] + +Enable callers to use const pointers for type safety. + +Signed-off-by: Chuck Lever +Reviewed-by: NeilBrown +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -721,7 +721,7 @@ static unsigned int ownerstr_hashval(str + #define FILE_HASH_BITS 8 + #define FILE_HASH_SIZE (1 << FILE_HASH_BITS) + +-static unsigned int file_hashval(struct svc_fh *fh) ++static unsigned int file_hashval(const struct svc_fh *fh) + { + struct inode *inode = d_inode(fh->fh_dentry); + +@@ -4687,7 +4687,7 @@ move_to_close_lru(struct nfs4_ol_stateid + + /* search file_hashtbl[] for file */ + static struct nfs4_file * +-find_file_locked(struct svc_fh *fh, unsigned int hashval) ++find_file_locked(const struct svc_fh *fh, unsigned int hashval) + { + struct nfs4_file *fp; + diff --git a/queue-6.1/nfsd-use-const-pointers-as-parameters-to-fh_-helpers.patch b/queue-6.1/nfsd-use-const-pointers-as-parameters-to-fh_-helpers.patch new file mode 100644 index 00000000000..0ee4a4af179 --- /dev/null +++ b/queue-6.1/nfsd-use-const-pointers-as-parameters-to-fh_-helpers.patch @@ -0,0 +1,61 @@ +From 26e1bf703d792962a07841f94026324d690a938d Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Fri, 28 Oct 2022 10:47:16 -0400 +Subject: NFSD: Use const pointers as parameters to fh_ helpers + +From: Chuck Lever + +[ Upstream commit b48f8056c034f28dd54668399f1d22be421b0bef ] + +Enable callers to use const pointers where they are able to. + +Signed-off-by: Chuck Lever +Tested-by: Jeff Layton +Reviewed-by: Jeff Layton +Reviewed-by: NeilBrown +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfsfh.h | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/fs/nfsd/nfsfh.h ++++ b/fs/nfsd/nfsfh.h +@@ -220,7 +220,7 @@ __be32 fh_update(struct svc_fh *); + void fh_put(struct svc_fh *); + + static __inline__ struct svc_fh * +-fh_copy(struct svc_fh *dst, struct svc_fh *src) ++fh_copy(struct svc_fh *dst, const struct svc_fh *src) + { + WARN_ON(src->fh_dentry); + +@@ -229,7 +229,7 @@ fh_copy(struct svc_fh *dst, struct svc_f + } + + static inline void +-fh_copy_shallow(struct knfsd_fh *dst, struct knfsd_fh *src) ++fh_copy_shallow(struct knfsd_fh *dst, const struct knfsd_fh *src) + { + dst->fh_size = src->fh_size; + memcpy(&dst->fh_raw, &src->fh_raw, src->fh_size); +@@ -243,7 +243,8 @@ fh_init(struct svc_fh *fhp, int maxsize) + return fhp; + } + +-static inline bool fh_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2) ++static inline bool fh_match(const struct knfsd_fh *fh1, ++ const struct knfsd_fh *fh2) + { + if (fh1->fh_size != fh2->fh_size) + return false; +@@ -252,7 +253,8 @@ static inline bool fh_match(struct knfsd + return true; + } + +-static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2) ++static inline bool fh_fsid_match(const struct knfsd_fh *fh1, ++ const struct knfsd_fh *fh2) + { + if (fh1->fh_fsid_type != fh2->fh_fsid_type) + return false; diff --git a/queue-6.1/nfsd-use-locks_inode_context-helper.patch b/queue-6.1/nfsd-use-locks_inode_context-helper.patch new file mode 100644 index 00000000000..544f8200513 --- /dev/null +++ b/queue-6.1/nfsd-use-locks_inode_context-helper.patch @@ -0,0 +1,51 @@ +From 38d71d411f45436b789a5db9bfeb814a049ea1d3 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Wed, 16 Nov 2022 09:36:07 -0500 +Subject: nfsd: use locks_inode_context helper + +From: Jeff Layton + +[ Upstream commit 77c67530e1f95ac25c7075635f32f04367380894 ] + +nfsd currently doesn't access i_flctx safely everywhere. This requires a +smp_load_acquire, as the pointer is set via cmpxchg (a release +operation). + +Acked-by: Chuck Lever +Reviewed-by: Christoph Hellwig +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -4784,7 +4784,7 @@ nfs4_share_conflict(struct svc_fh *curre + + static bool nfsd4_deleg_present(const struct inode *inode) + { +- struct file_lock_context *ctx = smp_load_acquire(&inode->i_flctx); ++ struct file_lock_context *ctx = locks_inode_context(inode); + + return ctx && !list_empty_careful(&ctx->flc_lease); + } +@@ -5944,7 +5944,7 @@ nfs4_lockowner_has_blockers(struct nfs4_ + + list_for_each_entry(stp, &lo->lo_owner.so_stateids, st_perstateowner) { + nf = stp->st_stid.sc_file; +- ctx = nf->fi_inode->i_flctx; ++ ctx = locks_inode_context(nf->fi_inode); + if (!ctx) + continue; + if (locks_owner_has_blockers(ctx, lo)) +@@ -7761,7 +7761,7 @@ check_for_locks(struct nfs4_file *fp, st + } + + inode = locks_inode(nf->nf_file); +- flctx = inode->i_flctx; ++ flctx = locks_inode_context(inode); + + if (flctx && !list_empty_careful(&flctx->flc_posix)) { + spin_lock(&flctx->flc_lock); diff --git a/queue-6.1/nfsd-use-only-rq_dropme-to-signal-the-need-to-drop-a-reply.patch b/queue-6.1/nfsd-use-only-rq_dropme-to-signal-the-need-to-drop-a-reply.patch new file mode 100644 index 00000000000..ef4167a15be --- /dev/null +++ b/queue-6.1/nfsd-use-only-rq_dropme-to-signal-the-need-to-drop-a-reply.patch @@ -0,0 +1,53 @@ +From c719a184ac3261c27c996d0ca852456be53ed7b8 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Sat, 26 Nov 2022 15:55:30 -0500 +Subject: NFSD: Use only RQ_DROPME to signal the need to drop a reply + +From: Chuck Lever + +[ Upstream commit 9315564747cb6a570e99196b3a4880fb817635fd ] + +Clean up: NFSv2 has the only two usages of rpc_drop_reply in the +NFSD code base. Since NFSv2 is going away at some point, replace +these in order to simplify the "drop this reply?" check in +nfsd_dispatch(). + +Signed-off-by: Chuck Lever +Reviewed-by: Jeff Layton +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfsproc.c | 4 ++-- + fs/nfsd/nfssvc.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/nfsd/nfsproc.c ++++ b/fs/nfsd/nfsproc.c +@@ -211,7 +211,7 @@ nfsd_proc_read(struct svc_rqst *rqstp) + if (resp->status == nfs_ok) + resp->status = fh_getattr(&resp->fh, &resp->stat); + else if (resp->status == nfserr_jukebox) +- return rpc_drop_reply; ++ __set_bit(RQ_DROPME, &rqstp->rq_flags); + return rpc_success; + } + +@@ -246,7 +246,7 @@ nfsd_proc_write(struct svc_rqst *rqstp) + if (resp->status == nfs_ok) + resp->status = fh_getattr(&resp->fh, &resp->stat); + else if (resp->status == nfserr_jukebox) +- return rpc_drop_reply; ++ __set_bit(RQ_DROPME, &rqstp->rq_flags); + return rpc_success; + } + +--- a/fs/nfsd/nfssvc.c ++++ b/fs/nfsd/nfssvc.c +@@ -1071,7 +1071,7 @@ int nfsd_dispatch(struct svc_rqst *rqstp + + nfs_reply = xdr_inline_decode(&rqstp->rq_res_stream, 0); + *statp = proc->pc_func(rqstp); +- if (*statp == rpc_drop_reply || test_bit(RQ_DROPME, &rqstp->rq_flags)) ++ if (test_bit(RQ_DROPME, &rqstp->rq_flags)) + goto out_update_drop; + + if (!proc->pc_encode(rqstp, &rqstp->rq_res_stream)) diff --git a/queue-6.1/nfsd-use-rhashtable-for-managing-nfs4_file-objects.patch b/queue-6.1/nfsd-use-rhashtable-for-managing-nfs4_file-objects.patch new file mode 100644 index 00000000000..307326f9714 --- /dev/null +++ b/queue-6.1/nfsd-use-rhashtable-for-managing-nfs4_file-objects.patch @@ -0,0 +1,244 @@ +From d43d4bc06612be58600f8999e59dc569c0c45ca8 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Fri, 28 Oct 2022 10:47:53 -0400 +Subject: NFSD: Use rhashtable for managing nfs4_file objects + +From: Chuck Lever + +[ Upstream commit d47b295e8d76a4d69f0e2ea0cd8a79c9d3488280 ] + +fh_match() is costly, especially when filehandles are large (as is +the case for NFSv4). It needs to be used sparingly when searching +data structures. Unfortunately, with common workloads, I see +multiple thousands of objects stored in file_hashtbl[], which has +just 256 buckets, making its bucket hash chains quite lengthy. + +Walking long hash chains with the state_lock held blocks other +activity that needs that lock. Sizable hash chains are a common +occurrance once the server has handed out some delegations, for +example -- IIUC, each delegated file is held open on the server by +an nfs4_file object. + +To help mitigate the cost of searching with fh_match(), replace the +nfs4_file hash table with an rhashtable, which can dynamically +resize its bucket array to minimize hash chain length. + +The result of this modification is an improvement in the latency of +NFSv4 operations, and the reduction of nfsd CPU utilization due to +eliminating the cost of multiple calls to fh_match() and reducing +the CPU cache misses incurred while walking long hash chains in the +nfs4_file hash table. + +Signed-off-by: Chuck Lever +Reviewed-by: NeilBrown +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 97 +++++++++++++++++++++++++++++++++------------------- + fs/nfsd/state.h | 5 -- + 2 files changed, 63 insertions(+), 39 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -44,7 +44,9 @@ + #include + #include + #include ++#include + #include ++ + #include "xdr4.h" + #include "xdr4cb.h" + #include "vfs.h" +@@ -589,11 +591,8 @@ static void nfsd4_free_file_rcu(struct r + void + put_nfs4_file(struct nfs4_file *fi) + { +- might_lock(&state_lock); +- +- if (refcount_dec_and_lock(&fi->fi_ref, &state_lock)) { ++ if (refcount_dec_and_test(&fi->fi_ref)) { + nfsd4_file_hash_remove(fi); +- spin_unlock(&state_lock); + WARN_ON_ONCE(!list_empty(&fi->fi_clnt_odstate)); + WARN_ON_ONCE(!list_empty(&fi->fi_delegations)); + call_rcu(&fi->fi_rcu, nfsd4_free_file_rcu); +@@ -718,19 +717,20 @@ static unsigned int ownerstr_hashval(str + return ret & OWNER_HASH_MASK; + } + +-/* hash table for nfs4_file */ +-#define FILE_HASH_BITS 8 +-#define FILE_HASH_SIZE (1 << FILE_HASH_BITS) +- +-static unsigned int file_hashval(const struct svc_fh *fh) +-{ +- struct inode *inode = d_inode(fh->fh_dentry); ++static struct rhltable nfs4_file_rhltable ____cacheline_aligned_in_smp; + +- /* XXX: why not (here & in file cache) use inode? */ +- return (unsigned int)hash_long(inode->i_ino, FILE_HASH_BITS); +-} ++static const struct rhashtable_params nfs4_file_rhash_params = { ++ .key_len = sizeof_field(struct nfs4_file, fi_inode), ++ .key_offset = offsetof(struct nfs4_file, fi_inode), ++ .head_offset = offsetof(struct nfs4_file, fi_rlist), + +-static struct hlist_head file_hashtbl[FILE_HASH_SIZE]; ++ /* ++ * Start with a single page hash table to reduce resizing churn ++ * on light workloads. ++ */ ++ .min_size = 256, ++ .automatic_shrinking = true, ++}; + + /* + * Check if courtesy clients have conflicting access and resolve it if possible +@@ -4686,12 +4686,14 @@ move_to_close_lru(struct nfs4_ol_stateid + static noinline_for_stack struct nfs4_file * + nfsd4_file_hash_lookup(const struct svc_fh *fhp) + { +- unsigned int hashval = file_hashval(fhp); ++ struct inode *inode = d_inode(fhp->fh_dentry); ++ struct rhlist_head *tmp, *list; + struct nfs4_file *fi; + + rcu_read_lock(); +- hlist_for_each_entry_rcu(fi, &file_hashtbl[hashval], fi_hash, +- lockdep_is_held(&state_lock)) { ++ list = rhltable_lookup(&nfs4_file_rhltable, &inode, ++ nfs4_file_rhash_params); ++ rhl_for_each_entry_rcu(fi, tmp, list, fi_rlist) { + if (fh_match(&fi->fi_fhandle, &fhp->fh_handle)) { + if (refcount_inc_not_zero(&fi->fi_ref)) { + rcu_read_unlock(); +@@ -4705,40 +4707,56 @@ nfsd4_file_hash_lookup(const struct svc_ + + /* + * On hash insertion, identify entries with the same inode but +- * distinct filehandles. They will all be in the same hash bucket +- * because nfs4_file's are hashed by the address in the fi_inode +- * field. ++ * distinct filehandles. They will all be on the list returned ++ * by rhltable_lookup(). ++ * ++ * inode->i_lock prevents racing insertions from adding an entry ++ * for the same inode/fhp pair twice. + */ + static noinline_for_stack struct nfs4_file * + nfsd4_file_hash_insert(struct nfs4_file *new, const struct svc_fh *fhp) + { +- unsigned int hashval = file_hashval(fhp); ++ struct inode *inode = d_inode(fhp->fh_dentry); ++ struct rhlist_head *tmp, *list; + struct nfs4_file *ret = NULL; + bool alias_found = false; + struct nfs4_file *fi; ++ int err; + +- spin_lock(&state_lock); +- hlist_for_each_entry_rcu(fi, &file_hashtbl[hashval], fi_hash, +- lockdep_is_held(&state_lock)) { ++ rcu_read_lock(); ++ spin_lock(&inode->i_lock); ++ ++ list = rhltable_lookup(&nfs4_file_rhltable, &inode, ++ nfs4_file_rhash_params); ++ rhl_for_each_entry_rcu(fi, tmp, list, fi_rlist) { + if (fh_match(&fi->fi_fhandle, &fhp->fh_handle)) { + if (refcount_inc_not_zero(&fi->fi_ref)) + ret = fi; +- } else if (d_inode(fhp->fh_dentry) == fi->fi_inode) ++ } else + fi->fi_aliased = alias_found = true; + } +- if (likely(ret == NULL)) { +- nfsd4_file_init(fhp, new); +- hlist_add_head_rcu(&new->fi_hash, &file_hashtbl[hashval]); +- new->fi_aliased = alias_found; +- ret = new; +- } +- spin_unlock(&state_lock); ++ if (ret) ++ goto out_unlock; ++ ++ nfsd4_file_init(fhp, new); ++ err = rhltable_insert(&nfs4_file_rhltable, &new->fi_rlist, ++ nfs4_file_rhash_params); ++ if (err) ++ goto out_unlock; ++ ++ new->fi_aliased = alias_found; ++ ret = new; ++ ++out_unlock: ++ spin_unlock(&inode->i_lock); ++ rcu_read_unlock(); + return ret; + } + + static noinline_for_stack void nfsd4_file_hash_remove(struct nfs4_file *fi) + { +- hlist_del_rcu(&fi->fi_hash); ++ rhltable_remove(&nfs4_file_rhltable, &fi->fi_rlist, ++ nfs4_file_rhash_params); + } + + /* +@@ -5648,6 +5666,8 @@ nfsd4_process_open2(struct svc_rqst *rqs + * If not found, create the nfs4_file struct + */ + fp = nfsd4_file_hash_insert(open->op_file, current_fh); ++ if (unlikely(!fp)) ++ return nfserr_jukebox; + if (fp != open->op_file) { + status = nfs4_check_deleg(cl, open, &dp); + if (status) +@@ -8064,10 +8084,16 @@ nfs4_state_start(void) + { + int ret; + +- ret = nfsd4_create_callback_queue(); ++ ret = rhltable_init(&nfs4_file_rhltable, &nfs4_file_rhash_params); + if (ret) + return ret; + ++ ret = nfsd4_create_callback_queue(); ++ if (ret) { ++ rhltable_destroy(&nfs4_file_rhltable); ++ return ret; ++ } ++ + set_max_delegations(); + return 0; + } +@@ -8098,6 +8124,7 @@ nfs4_state_shutdown_net(struct net *net) + + nfsd4_client_tracking_exit(net); + nfs4_state_destroy_net(net); ++ rhltable_destroy(&nfs4_file_rhltable); + #ifdef CONFIG_NFSD_V4_2_INTER_SSC + nfsd4_ssc_shutdown_umount(nn); + #endif +--- a/fs/nfsd/state.h ++++ b/fs/nfsd/state.h +@@ -536,16 +536,13 @@ struct nfs4_clnt_odstate { + * inode can have multiple filehandles associated with it, so there is + * (potentially) a many to one relationship between this struct and struct + * inode. +- * +- * These are hashed by filehandle in the file_hashtbl, which is protected by +- * the global state_lock spinlock. + */ + struct nfs4_file { + refcount_t fi_ref; + struct inode * fi_inode; + bool fi_aliased; + spinlock_t fi_lock; +- struct hlist_node fi_hash; /* hash on fi_fhandle */ ++ struct rhlist_head fi_rlist; + struct list_head fi_stateids; + union { + struct list_head fi_delegations; diff --git a/queue-6.1/nfsd-use-set_bit-rq_dropme.patch b/queue-6.1/nfsd-use-set_bit-rq_dropme.patch new file mode 100644 index 00000000000..18de91af64d --- /dev/null +++ b/queue-6.1/nfsd-use-set_bit-rq_dropme.patch @@ -0,0 +1,41 @@ +From a84e0f59363de87491392d26c0b8a61993276898 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Sat, 7 Jan 2023 10:15:35 -0500 +Subject: NFSD: Use set_bit(RQ_DROPME) + +From: Chuck Lever + +[ Upstream commit 5304930dbae82d259bcf7e5611db7c81e7a42eff ] + +The premise that "Once an svc thread is scheduled and executing an +RPC, no other processes will touch svc_rqst::rq_flags" is false. +svc_xprt_enqueue() examines the RQ_BUSY flag in scheduled nfsd +threads when determining which thread to wake up next. + +Fixes: 9315564747cb ("NFSD: Use only RQ_DROPME to signal the need to drop a reply") +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfsproc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/nfsd/nfsproc.c ++++ b/fs/nfsd/nfsproc.c +@@ -211,7 +211,7 @@ nfsd_proc_read(struct svc_rqst *rqstp) + if (resp->status == nfs_ok) + resp->status = fh_getattr(&resp->fh, &resp->stat); + else if (resp->status == nfserr_jukebox) +- __set_bit(RQ_DROPME, &rqstp->rq_flags); ++ set_bit(RQ_DROPME, &rqstp->rq_flags); + return rpc_success; + } + +@@ -246,7 +246,7 @@ nfsd_proc_write(struct svc_rqst *rqstp) + if (resp->status == nfs_ok) + resp->status = fh_getattr(&resp->fh, &resp->stat); + else if (resp->status == nfserr_jukebox) +- __set_bit(RQ_DROPME, &rqstp->rq_flags); ++ set_bit(RQ_DROPME, &rqstp->rq_flags); + return rpc_success; + } + diff --git a/queue-6.1/nfsd-use-struct_size-helper-in-alloc_session.patch b/queue-6.1/nfsd-use-struct_size-helper-in-alloc_session.patch new file mode 100644 index 00000000000..cc02fc33c8c --- /dev/null +++ b/queue-6.1/nfsd-use-struct_size-helper-in-alloc_session.patch @@ -0,0 +1,39 @@ +From dd2b71cd068ca2cad01164b0500faae1dc607005 Mon Sep 17 00:00:00 2001 +From: Xiu Jianfeng +Date: Fri, 11 Nov 2022 17:18:35 +0800 +Subject: NFSD: Use struct_size() helper in alloc_session() + +From: Xiu Jianfeng + +[ Upstream commit 85a0d0c9a58002ef7d1bf5e3ea630f4fbd42a4f0 ] + +Use struct_size() helper to simplify the code, no functional changes. + +Signed-off-by: Xiu Jianfeng +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -1834,13 +1834,12 @@ static struct nfsd4_session *alloc_sessi + int numslots = fattrs->maxreqs; + int slotsize = slot_bytes(fattrs); + struct nfsd4_session *new; +- int mem, i; ++ int i; + +- BUILD_BUG_ON(NFSD_MAX_SLOTS_PER_SESSION * sizeof(struct nfsd4_slot *) +- + sizeof(struct nfsd4_session) > PAGE_SIZE); +- mem = numslots * sizeof(struct nfsd4_slot *); ++ BUILD_BUG_ON(struct_size(new, se_slots, NFSD_MAX_SLOTS_PER_SESSION) ++ > PAGE_SIZE); + +- new = kzalloc(sizeof(*new) + mem, GFP_KERNEL); ++ new = kzalloc(struct_size(new, se_slots, numslots), GFP_KERNEL); + if (!new) + return NULL; + /* allocate each struct nfsd4_slot and data cache in one piece */ diff --git a/queue-6.1/series b/queue-6.1/series index c56397b0b3e..c8819c120b6 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -141,3 +141,40 @@ x86-decompressor-move-global-symbol-references-to-c-code.patch decompress-use-8-byte-alignment.patch drm-amd-display-increase-frame-warning-limit-with-kasan-or-kcsan-in-dml.patch nfs-fix-data-corruption-caused-by-congestion.patch +nfsd-simplify-read_plus.patch +nfsd-remove-redundant-assignment-to-variable-host_err.patch +nfsd-ignore-requests-to-disable-unsupported-versions.patch +nfsd-move-nfserrno-to-vfs.c.patch +nfsd-allow-disabling-nfsv2-at-compile-time.patch +exportfs-use-pr_debug-for-unreachable-debug-statements.patch +nfsd-flesh-out-a-documenting-comment-for-filecache.c.patch +nfsd-clean-up-nfs4_preprocess_stateid_op-call-sites.patch +nfsd-trace-stateids-returned-via-delegreturn.patch +nfsd-trace-delegation-revocations.patch +nfsd-use-const-pointers-as-parameters-to-fh_-helpers.patch +nfsd-update-file_hashtbl-helpers.patch +nfsd-clean-up-nfsd4_init_file.patch +nfsd-add-a-nfsd4_file_hash_remove-helper.patch +nfsd-clean-up-find_or_add_file.patch +nfsd-refactor-find_file.patch +nfsd-use-rhashtable-for-managing-nfs4_file-objects.patch +nfsd-fix-licensing-header-in-filecache.c.patch +filelock-add-a-new-locks_inode_context-accessor-function.patch +lockd-use-locks_inode_context-helper.patch +nfsd-use-locks_inode_context-helper.patch +nfsd-fix-up-the-filecache-laundrette-scheduling.patch +nfsd-use-struct_size-helper-in-alloc_session.patch +lockd-set-missing-fl_flags-field-when-retrieving-args.patch +lockd-ensure-we-use-the-correct-file-descriptor-when-unlocking.patch +lockd-fix-file-selection-in-nlmsvc_cancel_blocked.patch +trace-relocate-event-helper-files.patch +nfsd-refactoring-courtesy_client_reaper-to-a-generic-low-memory-shrinker.patch +nfsd-add-support-for-sending-cb_recall_any.patch +nfsd-add-delegation-reaper-to-react-to-low-memory-condition.patch +nfsd-add-cb_recall_any-tracepoints.patch +nfsd-use-only-rq_dropme-to-signal-the-need-to-drop-a-reply.patch +nfsd-avoid-clashing-function-prototypes.patch +nfsd-use-set_bit-rq_dropme.patch +nfsd-register-unregister-of-nfsd-client-shrinker-at-nfsd-startup-shutdown-time.patch +nfsd-replace-delayed_work-with-work_struct-for-nfsd_client_shrinker.patch +nfsd-don-t-destroy-global-nfs4_file-table-in-per-net-shutdown.patch diff --git a/queue-6.1/trace-relocate-event-helper-files.patch b/queue-6.1/trace-relocate-event-helper-files.patch new file mode 100644 index 00000000000..34ee35f9ecc --- /dev/null +++ b/queue-6.1/trace-relocate-event-helper-files.patch @@ -0,0 +1,1559 @@ +From 9611f3b43fd527f64ebd2a6620268096affc46e8 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Mon, 14 Nov 2022 08:57:43 -0500 +Subject: trace: Relocate event helper files + +From: Chuck Lever + +[ Upstream commit 247c01ff5f8d66e62a404c91733be52fecb8b7f6 ] + +Steven Rostedt says: +> The include/trace/events/ directory should only hold files that +> are to create events, not headers that hold helper functions. +> +> Can you please move them out of include/trace/events/ as that +> directory is "special" in the creation of events. + +Signed-off-by: Chuck Lever +Acked-by: Leon Romanovsky +Acked-by: Steven Rostedt (Google) +Acked-by: Anna Schumaker +Stable-dep-of: 638593be55c0 ("NFSD: add CB_RECALL_ANY tracepoints") +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + MAINTAINERS | 7 +++++++ + drivers/infiniband/core/cm_trace.h | 2 +- + drivers/infiniband/core/cma_trace.h | 2 +- + fs/nfs/nfs4trace.h | 6 +++--- + fs/nfs/nfstrace.h | 6 +++--- + include/trace/events/rpcgss.h | 2 +- + include/trace/events/rpcrdma.h | 4 ++-- + include/trace/events/sunrpc.h | 2 +- + include/trace/{events => misc}/fs.h | 0 + include/trace/{events => misc}/nfs.h | 0 + include/trace/{events => misc}/rdma.h | 0 + include/trace/{events/sunrpc_base.h => misc/sunrpc.h} | 0 + MAINTAINERS | 7 + drivers/infiniband/core/cm_trace.h | 2 + drivers/infiniband/core/cma_trace.h | 2 + fs/nfs/nfs4trace.h | 6 + fs/nfs/nfstrace.h | 6 + include/trace/events/fs.h | 122 ----------- + include/trace/events/nfs.h | 375 ------------------------------------ + include/trace/events/rdma.h | 168 ---------------- + include/trace/events/rpcgss.h | 2 + include/trace/events/rpcrdma.h | 4 + include/trace/events/sunrpc.h | 2 + include/trace/events/sunrpc_base.h | 18 - + include/trace/misc/fs.h | 122 +++++++++++ + include/trace/misc/nfs.h | 375 ++++++++++++++++++++++++++++++++++++ + include/trace/misc/rdma.h | 168 ++++++++++++++++ + include/trace/misc/sunrpc.h | 18 + + 16 files changed, 702 insertions(+), 695 deletions(-) + rename include/trace/{events => misc}/fs.h (100%) + rename include/trace/{events => misc}/nfs.h (100%) + rename include/trace/{events => misc}/rdma.h (100%) + rename include/trace/{events/sunrpc_base.h => misc/sunrpc.h} (100%) + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -10051,6 +10051,7 @@ F: drivers/infiniband/ + F: include/rdma/ + F: include/trace/events/ib_mad.h + F: include/trace/events/ib_umad.h ++F: include/trace/misc/rdma.h + F: include/uapi/linux/if_infiniband.h + F: include/uapi/rdma/ + F: samples/bpf/ibumad_kern.c +@@ -11139,6 +11140,12 @@ F: fs/nfs_common/ + F: fs/nfsd/ + F: include/linux/lockd/ + F: include/linux/sunrpc/ ++F: include/trace/events/rpcgss.h ++F: include/trace/events/rpcrdma.h ++F: include/trace/events/sunrpc.h ++F: include/trace/misc/fs.h ++F: include/trace/misc/nfs.h ++F: include/trace/misc/sunrpc.h + F: include/uapi/linux/nfsd/ + F: include/uapi/linux/sunrpc/ + F: net/sunrpc/ +--- a/drivers/infiniband/core/cm_trace.h ++++ b/drivers/infiniband/core/cm_trace.h +@@ -16,7 +16,7 @@ + + #include + #include +-#include ++#include + + /* + * enum ib_cm_state, from include/rdma/ib_cm.h +--- a/drivers/infiniband/core/cma_trace.h ++++ b/drivers/infiniband/core/cma_trace.h +@@ -15,7 +15,7 @@ + #define _TRACE_RDMA_CMA_H + + #include +-#include ++#include + + + DECLARE_EVENT_CLASS(cma_fsm_class, +--- a/fs/nfs/nfs4trace.h ++++ b/fs/nfs/nfs4trace.h +@@ -9,10 +9,10 @@ + #define _TRACE_NFS4_H + + #include +-#include ++#include + +-#include +-#include ++#include ++#include + + #define show_nfs_fattr_flags(valid) \ + __print_flags((unsigned long)valid, "|", \ +--- a/fs/nfs/nfstrace.h ++++ b/fs/nfs/nfstrace.h +@@ -11,9 +11,9 @@ + #include + #include + +-#include +-#include +-#include ++#include ++#include ++#include + + #define nfs_show_cache_validity(v) \ + __print_flags(v, "|", \ +--- a/include/trace/events/fs.h ++++ /dev/null +@@ -1,122 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Display helpers for generic filesystem items +- * +- * Author: Chuck Lever +- * +- * Copyright (c) 2020, Oracle and/or its affiliates. +- */ +- +-#include +- +-#define show_fs_dirent_type(x) \ +- __print_symbolic(x, \ +- { DT_UNKNOWN, "UNKNOWN" }, \ +- { DT_FIFO, "FIFO" }, \ +- { DT_CHR, "CHR" }, \ +- { DT_DIR, "DIR" }, \ +- { DT_BLK, "BLK" }, \ +- { DT_REG, "REG" }, \ +- { DT_LNK, "LNK" }, \ +- { DT_SOCK, "SOCK" }, \ +- { DT_WHT, "WHT" }) +- +-#define show_fs_fcntl_open_flags(x) \ +- __print_flags(x, "|", \ +- { O_WRONLY, "O_WRONLY" }, \ +- { O_RDWR, "O_RDWR" }, \ +- { O_CREAT, "O_CREAT" }, \ +- { O_EXCL, "O_EXCL" }, \ +- { O_NOCTTY, "O_NOCTTY" }, \ +- { O_TRUNC, "O_TRUNC" }, \ +- { O_APPEND, "O_APPEND" }, \ +- { O_NONBLOCK, "O_NONBLOCK" }, \ +- { O_DSYNC, "O_DSYNC" }, \ +- { O_DIRECT, "O_DIRECT" }, \ +- { O_LARGEFILE, "O_LARGEFILE" }, \ +- { O_DIRECTORY, "O_DIRECTORY" }, \ +- { O_NOFOLLOW, "O_NOFOLLOW" }, \ +- { O_NOATIME, "O_NOATIME" }, \ +- { O_CLOEXEC, "O_CLOEXEC" }) +- +-#define __fmode_flag(x) { (__force unsigned long)FMODE_##x, #x } +-#define show_fs_fmode_flags(x) \ +- __print_flags(x, "|", \ +- __fmode_flag(READ), \ +- __fmode_flag(WRITE), \ +- __fmode_flag(EXEC)) +- +-#ifdef CONFIG_64BIT +-#define show_fs_fcntl_cmd(x) \ +- __print_symbolic(x, \ +- { F_DUPFD, "DUPFD" }, \ +- { F_GETFD, "GETFD" }, \ +- { F_SETFD, "SETFD" }, \ +- { F_GETFL, "GETFL" }, \ +- { F_SETFL, "SETFL" }, \ +- { F_GETLK, "GETLK" }, \ +- { F_SETLK, "SETLK" }, \ +- { F_SETLKW, "SETLKW" }, \ +- { F_SETOWN, "SETOWN" }, \ +- { F_GETOWN, "GETOWN" }, \ +- { F_SETSIG, "SETSIG" }, \ +- { F_GETSIG, "GETSIG" }, \ +- { F_SETOWN_EX, "SETOWN_EX" }, \ +- { F_GETOWN_EX, "GETOWN_EX" }, \ +- { F_GETOWNER_UIDS, "GETOWNER_UIDS" }, \ +- { F_OFD_GETLK, "OFD_GETLK" }, \ +- { F_OFD_SETLK, "OFD_SETLK" }, \ +- { F_OFD_SETLKW, "OFD_SETLKW" }) +-#else /* CONFIG_64BIT */ +-#define show_fs_fcntl_cmd(x) \ +- __print_symbolic(x, \ +- { F_DUPFD, "DUPFD" }, \ +- { F_GETFD, "GETFD" }, \ +- { F_SETFD, "SETFD" }, \ +- { F_GETFL, "GETFL" }, \ +- { F_SETFL, "SETFL" }, \ +- { F_GETLK, "GETLK" }, \ +- { F_SETLK, "SETLK" }, \ +- { F_SETLKW, "SETLKW" }, \ +- { F_SETOWN, "SETOWN" }, \ +- { F_GETOWN, "GETOWN" }, \ +- { F_SETSIG, "SETSIG" }, \ +- { F_GETSIG, "GETSIG" }, \ +- { F_GETLK64, "GETLK64" }, \ +- { F_SETLK64, "SETLK64" }, \ +- { F_SETLKW64, "SETLKW64" }, \ +- { F_SETOWN_EX, "SETOWN_EX" }, \ +- { F_GETOWN_EX, "GETOWN_EX" }, \ +- { F_GETOWNER_UIDS, "GETOWNER_UIDS" }, \ +- { F_OFD_GETLK, "OFD_GETLK" }, \ +- { F_OFD_SETLK, "OFD_SETLK" }, \ +- { F_OFD_SETLKW, "OFD_SETLKW" }) +-#endif /* CONFIG_64BIT */ +- +-#define show_fs_fcntl_lock_type(x) \ +- __print_symbolic(x, \ +- { F_RDLCK, "RDLCK" }, \ +- { F_WRLCK, "WRLCK" }, \ +- { F_UNLCK, "UNLCK" }) +- +-#define show_fs_lookup_flags(flags) \ +- __print_flags(flags, "|", \ +- { LOOKUP_FOLLOW, "FOLLOW" }, \ +- { LOOKUP_DIRECTORY, "DIRECTORY" }, \ +- { LOOKUP_AUTOMOUNT, "AUTOMOUNT" }, \ +- { LOOKUP_EMPTY, "EMPTY" }, \ +- { LOOKUP_DOWN, "DOWN" }, \ +- { LOOKUP_MOUNTPOINT, "MOUNTPOINT" }, \ +- { LOOKUP_REVAL, "REVAL" }, \ +- { LOOKUP_RCU, "RCU" }, \ +- { LOOKUP_OPEN, "OPEN" }, \ +- { LOOKUP_CREATE, "CREATE" }, \ +- { LOOKUP_EXCL, "EXCL" }, \ +- { LOOKUP_RENAME_TARGET, "RENAME_TARGET" }, \ +- { LOOKUP_PARENT, "PARENT" }, \ +- { LOOKUP_NO_SYMLINKS, "NO_SYMLINKS" }, \ +- { LOOKUP_NO_MAGICLINKS, "NO_MAGICLINKS" }, \ +- { LOOKUP_NO_XDEV, "NO_XDEV" }, \ +- { LOOKUP_BENEATH, "BENEATH" }, \ +- { LOOKUP_IN_ROOT, "IN_ROOT" }, \ +- { LOOKUP_CACHED, "CACHED" }) +--- a/include/trace/events/nfs.h ++++ /dev/null +@@ -1,375 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Display helpers for NFS protocol elements +- * +- * Author: Chuck Lever +- * +- * Copyright (c) 2020, Oracle and/or its affiliates. +- */ +- +-#include +-#include +-#include +- +-TRACE_DEFINE_ENUM(NFS_OK); +-TRACE_DEFINE_ENUM(NFSERR_PERM); +-TRACE_DEFINE_ENUM(NFSERR_NOENT); +-TRACE_DEFINE_ENUM(NFSERR_IO); +-TRACE_DEFINE_ENUM(NFSERR_NXIO); +-TRACE_DEFINE_ENUM(NFSERR_EAGAIN); +-TRACE_DEFINE_ENUM(NFSERR_ACCES); +-TRACE_DEFINE_ENUM(NFSERR_EXIST); +-TRACE_DEFINE_ENUM(NFSERR_XDEV); +-TRACE_DEFINE_ENUM(NFSERR_NODEV); +-TRACE_DEFINE_ENUM(NFSERR_NOTDIR); +-TRACE_DEFINE_ENUM(NFSERR_ISDIR); +-TRACE_DEFINE_ENUM(NFSERR_INVAL); +-TRACE_DEFINE_ENUM(NFSERR_FBIG); +-TRACE_DEFINE_ENUM(NFSERR_NOSPC); +-TRACE_DEFINE_ENUM(NFSERR_ROFS); +-TRACE_DEFINE_ENUM(NFSERR_MLINK); +-TRACE_DEFINE_ENUM(NFSERR_OPNOTSUPP); +-TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG); +-TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY); +-TRACE_DEFINE_ENUM(NFSERR_DQUOT); +-TRACE_DEFINE_ENUM(NFSERR_STALE); +-TRACE_DEFINE_ENUM(NFSERR_REMOTE); +-TRACE_DEFINE_ENUM(NFSERR_WFLUSH); +-TRACE_DEFINE_ENUM(NFSERR_BADHANDLE); +-TRACE_DEFINE_ENUM(NFSERR_NOT_SYNC); +-TRACE_DEFINE_ENUM(NFSERR_BAD_COOKIE); +-TRACE_DEFINE_ENUM(NFSERR_NOTSUPP); +-TRACE_DEFINE_ENUM(NFSERR_TOOSMALL); +-TRACE_DEFINE_ENUM(NFSERR_SERVERFAULT); +-TRACE_DEFINE_ENUM(NFSERR_BADTYPE); +-TRACE_DEFINE_ENUM(NFSERR_JUKEBOX); +- +-#define show_nfs_status(x) \ +- __print_symbolic(x, \ +- { NFS_OK, "OK" }, \ +- { NFSERR_PERM, "PERM" }, \ +- { NFSERR_NOENT, "NOENT" }, \ +- { NFSERR_IO, "IO" }, \ +- { NFSERR_NXIO, "NXIO" }, \ +- { ECHILD, "CHILD" }, \ +- { NFSERR_EAGAIN, "AGAIN" }, \ +- { NFSERR_ACCES, "ACCES" }, \ +- { NFSERR_EXIST, "EXIST" }, \ +- { NFSERR_XDEV, "XDEV" }, \ +- { NFSERR_NODEV, "NODEV" }, \ +- { NFSERR_NOTDIR, "NOTDIR" }, \ +- { NFSERR_ISDIR, "ISDIR" }, \ +- { NFSERR_INVAL, "INVAL" }, \ +- { NFSERR_FBIG, "FBIG" }, \ +- { NFSERR_NOSPC, "NOSPC" }, \ +- { NFSERR_ROFS, "ROFS" }, \ +- { NFSERR_MLINK, "MLINK" }, \ +- { NFSERR_OPNOTSUPP, "OPNOTSUPP" }, \ +- { NFSERR_NAMETOOLONG, "NAMETOOLONG" }, \ +- { NFSERR_NOTEMPTY, "NOTEMPTY" }, \ +- { NFSERR_DQUOT, "DQUOT" }, \ +- { NFSERR_STALE, "STALE" }, \ +- { NFSERR_REMOTE, "REMOTE" }, \ +- { NFSERR_WFLUSH, "WFLUSH" }, \ +- { NFSERR_BADHANDLE, "BADHANDLE" }, \ +- { NFSERR_NOT_SYNC, "NOTSYNC" }, \ +- { NFSERR_BAD_COOKIE, "BADCOOKIE" }, \ +- { NFSERR_NOTSUPP, "NOTSUPP" }, \ +- { NFSERR_TOOSMALL, "TOOSMALL" }, \ +- { NFSERR_SERVERFAULT, "REMOTEIO" }, \ +- { NFSERR_BADTYPE, "BADTYPE" }, \ +- { NFSERR_JUKEBOX, "JUKEBOX" }) +- +-TRACE_DEFINE_ENUM(NFS_UNSTABLE); +-TRACE_DEFINE_ENUM(NFS_DATA_SYNC); +-TRACE_DEFINE_ENUM(NFS_FILE_SYNC); +- +-#define show_nfs_stable_how(x) \ +- __print_symbolic(x, \ +- { NFS_UNSTABLE, "UNSTABLE" }, \ +- { NFS_DATA_SYNC, "DATA_SYNC" }, \ +- { NFS_FILE_SYNC, "FILE_SYNC" }) +- +-TRACE_DEFINE_ENUM(NFS4_OK); +-TRACE_DEFINE_ENUM(NFS4ERR_ACCESS); +-TRACE_DEFINE_ENUM(NFS4ERR_ATTRNOTSUPP); +-TRACE_DEFINE_ENUM(NFS4ERR_ADMIN_REVOKED); +-TRACE_DEFINE_ENUM(NFS4ERR_BACK_CHAN_BUSY); +-TRACE_DEFINE_ENUM(NFS4ERR_BADCHAR); +-TRACE_DEFINE_ENUM(NFS4ERR_BADHANDLE); +-TRACE_DEFINE_ENUM(NFS4ERR_BADIOMODE); +-TRACE_DEFINE_ENUM(NFS4ERR_BADLAYOUT); +-TRACE_DEFINE_ENUM(NFS4ERR_BADLABEL); +-TRACE_DEFINE_ENUM(NFS4ERR_BADNAME); +-TRACE_DEFINE_ENUM(NFS4ERR_BADOWNER); +-TRACE_DEFINE_ENUM(NFS4ERR_BADSESSION); +-TRACE_DEFINE_ENUM(NFS4ERR_BADSLOT); +-TRACE_DEFINE_ENUM(NFS4ERR_BADTYPE); +-TRACE_DEFINE_ENUM(NFS4ERR_BADXDR); +-TRACE_DEFINE_ENUM(NFS4ERR_BAD_COOKIE); +-TRACE_DEFINE_ENUM(NFS4ERR_BAD_HIGH_SLOT); +-TRACE_DEFINE_ENUM(NFS4ERR_BAD_RANGE); +-TRACE_DEFINE_ENUM(NFS4ERR_BAD_SEQID); +-TRACE_DEFINE_ENUM(NFS4ERR_BAD_SESSION_DIGEST); +-TRACE_DEFINE_ENUM(NFS4ERR_BAD_STATEID); +-TRACE_DEFINE_ENUM(NFS4ERR_CB_PATH_DOWN); +-TRACE_DEFINE_ENUM(NFS4ERR_CLID_INUSE); +-TRACE_DEFINE_ENUM(NFS4ERR_CLIENTID_BUSY); +-TRACE_DEFINE_ENUM(NFS4ERR_COMPLETE_ALREADY); +-TRACE_DEFINE_ENUM(NFS4ERR_CONN_NOT_BOUND_TO_SESSION); +-TRACE_DEFINE_ENUM(NFS4ERR_DEADLOCK); +-TRACE_DEFINE_ENUM(NFS4ERR_DEADSESSION); +-TRACE_DEFINE_ENUM(NFS4ERR_DELAY); +-TRACE_DEFINE_ENUM(NFS4ERR_DELEG_ALREADY_WANTED); +-TRACE_DEFINE_ENUM(NFS4ERR_DELEG_REVOKED); +-TRACE_DEFINE_ENUM(NFS4ERR_DENIED); +-TRACE_DEFINE_ENUM(NFS4ERR_DIRDELEG_UNAVAIL); +-TRACE_DEFINE_ENUM(NFS4ERR_DQUOT); +-TRACE_DEFINE_ENUM(NFS4ERR_ENCR_ALG_UNSUPP); +-TRACE_DEFINE_ENUM(NFS4ERR_EXIST); +-TRACE_DEFINE_ENUM(NFS4ERR_EXPIRED); +-TRACE_DEFINE_ENUM(NFS4ERR_FBIG); +-TRACE_DEFINE_ENUM(NFS4ERR_FHEXPIRED); +-TRACE_DEFINE_ENUM(NFS4ERR_FILE_OPEN); +-TRACE_DEFINE_ENUM(NFS4ERR_GRACE); +-TRACE_DEFINE_ENUM(NFS4ERR_HASH_ALG_UNSUPP); +-TRACE_DEFINE_ENUM(NFS4ERR_INVAL); +-TRACE_DEFINE_ENUM(NFS4ERR_IO); +-TRACE_DEFINE_ENUM(NFS4ERR_ISDIR); +-TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTTRYLATER); +-TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTUNAVAILABLE); +-TRACE_DEFINE_ENUM(NFS4ERR_LEASE_MOVED); +-TRACE_DEFINE_ENUM(NFS4ERR_LOCKED); +-TRACE_DEFINE_ENUM(NFS4ERR_LOCKS_HELD); +-TRACE_DEFINE_ENUM(NFS4ERR_LOCK_RANGE); +-TRACE_DEFINE_ENUM(NFS4ERR_MINOR_VERS_MISMATCH); +-TRACE_DEFINE_ENUM(NFS4ERR_MLINK); +-TRACE_DEFINE_ENUM(NFS4ERR_MOVED); +-TRACE_DEFINE_ENUM(NFS4ERR_NAMETOOLONG); +-TRACE_DEFINE_ENUM(NFS4ERR_NOENT); +-TRACE_DEFINE_ENUM(NFS4ERR_NOFILEHANDLE); +-TRACE_DEFINE_ENUM(NFS4ERR_NOMATCHING_LAYOUT); +-TRACE_DEFINE_ENUM(NFS4ERR_NOSPC); +-TRACE_DEFINE_ENUM(NFS4ERR_NOTDIR); +-TRACE_DEFINE_ENUM(NFS4ERR_NOTEMPTY); +-TRACE_DEFINE_ENUM(NFS4ERR_NOTSUPP); +-TRACE_DEFINE_ENUM(NFS4ERR_NOT_ONLY_OP); +-TRACE_DEFINE_ENUM(NFS4ERR_NOT_SAME); +-TRACE_DEFINE_ENUM(NFS4ERR_NO_GRACE); +-TRACE_DEFINE_ENUM(NFS4ERR_NXIO); +-TRACE_DEFINE_ENUM(NFS4ERR_OLD_STATEID); +-TRACE_DEFINE_ENUM(NFS4ERR_OPENMODE); +-TRACE_DEFINE_ENUM(NFS4ERR_OP_ILLEGAL); +-TRACE_DEFINE_ENUM(NFS4ERR_OP_NOT_IN_SESSION); +-TRACE_DEFINE_ENUM(NFS4ERR_PERM); +-TRACE_DEFINE_ENUM(NFS4ERR_PNFS_IO_HOLE); +-TRACE_DEFINE_ENUM(NFS4ERR_PNFS_NO_LAYOUT); +-TRACE_DEFINE_ENUM(NFS4ERR_RECALLCONFLICT); +-TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_BAD); +-TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_CONFLICT); +-TRACE_DEFINE_ENUM(NFS4ERR_REJECT_DELEG); +-TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG); +-TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG_TO_CACHE); +-TRACE_DEFINE_ENUM(NFS4ERR_REQ_TOO_BIG); +-TRACE_DEFINE_ENUM(NFS4ERR_RESOURCE); +-TRACE_DEFINE_ENUM(NFS4ERR_RESTOREFH); +-TRACE_DEFINE_ENUM(NFS4ERR_RETRY_UNCACHED_REP); +-TRACE_DEFINE_ENUM(NFS4ERR_RETURNCONFLICT); +-TRACE_DEFINE_ENUM(NFS4ERR_ROFS); +-TRACE_DEFINE_ENUM(NFS4ERR_SAME); +-TRACE_DEFINE_ENUM(NFS4ERR_SHARE_DENIED); +-TRACE_DEFINE_ENUM(NFS4ERR_SEQUENCE_POS); +-TRACE_DEFINE_ENUM(NFS4ERR_SEQ_FALSE_RETRY); +-TRACE_DEFINE_ENUM(NFS4ERR_SEQ_MISORDERED); +-TRACE_DEFINE_ENUM(NFS4ERR_SERVERFAULT); +-TRACE_DEFINE_ENUM(NFS4ERR_STALE); +-TRACE_DEFINE_ENUM(NFS4ERR_STALE_CLIENTID); +-TRACE_DEFINE_ENUM(NFS4ERR_STALE_STATEID); +-TRACE_DEFINE_ENUM(NFS4ERR_SYMLINK); +-TRACE_DEFINE_ENUM(NFS4ERR_TOOSMALL); +-TRACE_DEFINE_ENUM(NFS4ERR_TOO_MANY_OPS); +-TRACE_DEFINE_ENUM(NFS4ERR_UNKNOWN_LAYOUTTYPE); +-TRACE_DEFINE_ENUM(NFS4ERR_UNSAFE_COMPOUND); +-TRACE_DEFINE_ENUM(NFS4ERR_WRONGSEC); +-TRACE_DEFINE_ENUM(NFS4ERR_WRONG_CRED); +-TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE); +-TRACE_DEFINE_ENUM(NFS4ERR_XDEV); +- +-TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_MDS); +-TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS); +- +-#define show_nfs4_status(x) \ +- __print_symbolic(x, \ +- { NFS4_OK, "OK" }, \ +- { EPERM, "EPERM" }, \ +- { ENOENT, "ENOENT" }, \ +- { EIO, "EIO" }, \ +- { ENXIO, "ENXIO" }, \ +- { EACCES, "EACCES" }, \ +- { EEXIST, "EEXIST" }, \ +- { EXDEV, "EXDEV" }, \ +- { ENOTDIR, "ENOTDIR" }, \ +- { EISDIR, "EISDIR" }, \ +- { EFBIG, "EFBIG" }, \ +- { ENOSPC, "ENOSPC" }, \ +- { EROFS, "EROFS" }, \ +- { EMLINK, "EMLINK" }, \ +- { ENAMETOOLONG, "ENAMETOOLONG" }, \ +- { ENOTEMPTY, "ENOTEMPTY" }, \ +- { EDQUOT, "EDQUOT" }, \ +- { ESTALE, "ESTALE" }, \ +- { EBADHANDLE, "EBADHANDLE" }, \ +- { EBADCOOKIE, "EBADCOOKIE" }, \ +- { ENOTSUPP, "ENOTSUPP" }, \ +- { ETOOSMALL, "ETOOSMALL" }, \ +- { EREMOTEIO, "EREMOTEIO" }, \ +- { EBADTYPE, "EBADTYPE" }, \ +- { EAGAIN, "EAGAIN" }, \ +- { ELOOP, "ELOOP" }, \ +- { EOPNOTSUPP, "EOPNOTSUPP" }, \ +- { EDEADLK, "EDEADLK" }, \ +- { ENOMEM, "ENOMEM" }, \ +- { EKEYEXPIRED, "EKEYEXPIRED" }, \ +- { ETIMEDOUT, "ETIMEDOUT" }, \ +- { ERESTARTSYS, "ERESTARTSYS" }, \ +- { ECONNREFUSED, "ECONNREFUSED" }, \ +- { ECONNRESET, "ECONNRESET" }, \ +- { ENETUNREACH, "ENETUNREACH" }, \ +- { EHOSTUNREACH, "EHOSTUNREACH" }, \ +- { EHOSTDOWN, "EHOSTDOWN" }, \ +- { EPIPE, "EPIPE" }, \ +- { EPFNOSUPPORT, "EPFNOSUPPORT" }, \ +- { EPROTONOSUPPORT, "EPROTONOSUPPORT" }, \ +- { NFS4ERR_ACCESS, "ACCESS" }, \ +- { NFS4ERR_ATTRNOTSUPP, "ATTRNOTSUPP" }, \ +- { NFS4ERR_ADMIN_REVOKED, "ADMIN_REVOKED" }, \ +- { NFS4ERR_BACK_CHAN_BUSY, "BACK_CHAN_BUSY" }, \ +- { NFS4ERR_BADCHAR, "BADCHAR" }, \ +- { NFS4ERR_BADHANDLE, "BADHANDLE" }, \ +- { NFS4ERR_BADIOMODE, "BADIOMODE" }, \ +- { NFS4ERR_BADLAYOUT, "BADLAYOUT" }, \ +- { NFS4ERR_BADLABEL, "BADLABEL" }, \ +- { NFS4ERR_BADNAME, "BADNAME" }, \ +- { NFS4ERR_BADOWNER, "BADOWNER" }, \ +- { NFS4ERR_BADSESSION, "BADSESSION" }, \ +- { NFS4ERR_BADSLOT, "BADSLOT" }, \ +- { NFS4ERR_BADTYPE, "BADTYPE" }, \ +- { NFS4ERR_BADXDR, "BADXDR" }, \ +- { NFS4ERR_BAD_COOKIE, "BAD_COOKIE" }, \ +- { NFS4ERR_BAD_HIGH_SLOT, "BAD_HIGH_SLOT" }, \ +- { NFS4ERR_BAD_RANGE, "BAD_RANGE" }, \ +- { NFS4ERR_BAD_SEQID, "BAD_SEQID" }, \ +- { NFS4ERR_BAD_SESSION_DIGEST, "BAD_SESSION_DIGEST" }, \ +- { NFS4ERR_BAD_STATEID, "BAD_STATEID" }, \ +- { NFS4ERR_CB_PATH_DOWN, "CB_PATH_DOWN" }, \ +- { NFS4ERR_CLID_INUSE, "CLID_INUSE" }, \ +- { NFS4ERR_CLIENTID_BUSY, "CLIENTID_BUSY" }, \ +- { NFS4ERR_COMPLETE_ALREADY, "COMPLETE_ALREADY" }, \ +- { NFS4ERR_CONN_NOT_BOUND_TO_SESSION, "CONN_NOT_BOUND_TO_SESSION" }, \ +- { NFS4ERR_DEADLOCK, "DEADLOCK" }, \ +- { NFS4ERR_DEADSESSION, "DEAD_SESSION" }, \ +- { NFS4ERR_DELAY, "DELAY" }, \ +- { NFS4ERR_DELEG_ALREADY_WANTED, "DELEG_ALREADY_WANTED" }, \ +- { NFS4ERR_DELEG_REVOKED, "DELEG_REVOKED" }, \ +- { NFS4ERR_DENIED, "DENIED" }, \ +- { NFS4ERR_DIRDELEG_UNAVAIL, "DIRDELEG_UNAVAIL" }, \ +- { NFS4ERR_DQUOT, "DQUOT" }, \ +- { NFS4ERR_ENCR_ALG_UNSUPP, "ENCR_ALG_UNSUPP" }, \ +- { NFS4ERR_EXIST, "EXIST" }, \ +- { NFS4ERR_EXPIRED, "EXPIRED" }, \ +- { NFS4ERR_FBIG, "FBIG" }, \ +- { NFS4ERR_FHEXPIRED, "FHEXPIRED" }, \ +- { NFS4ERR_FILE_OPEN, "FILE_OPEN" }, \ +- { NFS4ERR_GRACE, "GRACE" }, \ +- { NFS4ERR_HASH_ALG_UNSUPP, "HASH_ALG_UNSUPP" }, \ +- { NFS4ERR_INVAL, "INVAL" }, \ +- { NFS4ERR_IO, "IO" }, \ +- { NFS4ERR_ISDIR, "ISDIR" }, \ +- { NFS4ERR_LAYOUTTRYLATER, "LAYOUTTRYLATER" }, \ +- { NFS4ERR_LAYOUTUNAVAILABLE, "LAYOUTUNAVAILABLE" }, \ +- { NFS4ERR_LEASE_MOVED, "LEASE_MOVED" }, \ +- { NFS4ERR_LOCKED, "LOCKED" }, \ +- { NFS4ERR_LOCKS_HELD, "LOCKS_HELD" }, \ +- { NFS4ERR_LOCK_RANGE, "LOCK_RANGE" }, \ +- { NFS4ERR_MINOR_VERS_MISMATCH, "MINOR_VERS_MISMATCH" }, \ +- { NFS4ERR_MLINK, "MLINK" }, \ +- { NFS4ERR_MOVED, "MOVED" }, \ +- { NFS4ERR_NAMETOOLONG, "NAMETOOLONG" }, \ +- { NFS4ERR_NOENT, "NOENT" }, \ +- { NFS4ERR_NOFILEHANDLE, "NOFILEHANDLE" }, \ +- { NFS4ERR_NOMATCHING_LAYOUT, "NOMATCHING_LAYOUT" }, \ +- { NFS4ERR_NOSPC, "NOSPC" }, \ +- { NFS4ERR_NOTDIR, "NOTDIR" }, \ +- { NFS4ERR_NOTEMPTY, "NOTEMPTY" }, \ +- { NFS4ERR_NOTSUPP, "NOTSUPP" }, \ +- { NFS4ERR_NOT_ONLY_OP, "NOT_ONLY_OP" }, \ +- { NFS4ERR_NOT_SAME, "NOT_SAME" }, \ +- { NFS4ERR_NO_GRACE, "NO_GRACE" }, \ +- { NFS4ERR_NXIO, "NXIO" }, \ +- { NFS4ERR_OLD_STATEID, "OLD_STATEID" }, \ +- { NFS4ERR_OPENMODE, "OPENMODE" }, \ +- { NFS4ERR_OP_ILLEGAL, "OP_ILLEGAL" }, \ +- { NFS4ERR_OP_NOT_IN_SESSION, "OP_NOT_IN_SESSION" }, \ +- { NFS4ERR_PERM, "PERM" }, \ +- { NFS4ERR_PNFS_IO_HOLE, "PNFS_IO_HOLE" }, \ +- { NFS4ERR_PNFS_NO_LAYOUT, "PNFS_NO_LAYOUT" }, \ +- { NFS4ERR_RECALLCONFLICT, "RECALLCONFLICT" }, \ +- { NFS4ERR_RECLAIM_BAD, "RECLAIM_BAD" }, \ +- { NFS4ERR_RECLAIM_CONFLICT, "RECLAIM_CONFLICT" }, \ +- { NFS4ERR_REJECT_DELEG, "REJECT_DELEG" }, \ +- { NFS4ERR_REP_TOO_BIG, "REP_TOO_BIG" }, \ +- { NFS4ERR_REP_TOO_BIG_TO_CACHE, "REP_TOO_BIG_TO_CACHE" }, \ +- { NFS4ERR_REQ_TOO_BIG, "REQ_TOO_BIG" }, \ +- { NFS4ERR_RESOURCE, "RESOURCE" }, \ +- { NFS4ERR_RESTOREFH, "RESTOREFH" }, \ +- { NFS4ERR_RETRY_UNCACHED_REP, "RETRY_UNCACHED_REP" }, \ +- { NFS4ERR_RETURNCONFLICT, "RETURNCONFLICT" }, \ +- { NFS4ERR_ROFS, "ROFS" }, \ +- { NFS4ERR_SAME, "SAME" }, \ +- { NFS4ERR_SHARE_DENIED, "SHARE_DENIED" }, \ +- { NFS4ERR_SEQUENCE_POS, "SEQUENCE_POS" }, \ +- { NFS4ERR_SEQ_FALSE_RETRY, "SEQ_FALSE_RETRY" }, \ +- { NFS4ERR_SEQ_MISORDERED, "SEQ_MISORDERED" }, \ +- { NFS4ERR_SERVERFAULT, "SERVERFAULT" }, \ +- { NFS4ERR_STALE, "STALE" }, \ +- { NFS4ERR_STALE_CLIENTID, "STALE_CLIENTID" }, \ +- { NFS4ERR_STALE_STATEID, "STALE_STATEID" }, \ +- { NFS4ERR_SYMLINK, "SYMLINK" }, \ +- { NFS4ERR_TOOSMALL, "TOOSMALL" }, \ +- { NFS4ERR_TOO_MANY_OPS, "TOO_MANY_OPS" }, \ +- { NFS4ERR_UNKNOWN_LAYOUTTYPE, "UNKNOWN_LAYOUTTYPE" }, \ +- { NFS4ERR_UNSAFE_COMPOUND, "UNSAFE_COMPOUND" }, \ +- { NFS4ERR_WRONGSEC, "WRONGSEC" }, \ +- { NFS4ERR_WRONG_CRED, "WRONG_CRED" }, \ +- { NFS4ERR_WRONG_TYPE, "WRONG_TYPE" }, \ +- { NFS4ERR_XDEV, "XDEV" }, \ +- /* ***** Internal to Linux NFS client ***** */ \ +- { NFS4ERR_RESET_TO_MDS, "RESET_TO_MDS" }, \ +- { NFS4ERR_RESET_TO_PNFS, "RESET_TO_PNFS" }) +- +-#define show_nfs4_verifier(x) \ +- __print_hex_str(x, NFS4_VERIFIER_SIZE) +- +-TRACE_DEFINE_ENUM(IOMODE_READ); +-TRACE_DEFINE_ENUM(IOMODE_RW); +-TRACE_DEFINE_ENUM(IOMODE_ANY); +- +-#define show_pnfs_layout_iomode(x) \ +- __print_symbolic(x, \ +- { IOMODE_READ, "READ" }, \ +- { IOMODE_RW, "RW" }, \ +- { IOMODE_ANY, "ANY" }) +- +-#define show_nfs4_seq4_status(x) \ +- __print_flags(x, "|", \ +- { SEQ4_STATUS_CB_PATH_DOWN, "CB_PATH_DOWN" }, \ +- { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING, "CB_GSS_CONTEXTS_EXPIRING" }, \ +- { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED, "CB_GSS_CONTEXTS_EXPIRED" }, \ +- { SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, "EXPIRED_ALL_STATE_REVOKED" }, \ +- { SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, "EXPIRED_SOME_STATE_REVOKED" }, \ +- { SEQ4_STATUS_ADMIN_STATE_REVOKED, "ADMIN_STATE_REVOKED" }, \ +- { SEQ4_STATUS_RECALLABLE_STATE_REVOKED, "RECALLABLE_STATE_REVOKED" }, \ +- { SEQ4_STATUS_LEASE_MOVED, "LEASE_MOVED" }, \ +- { SEQ4_STATUS_RESTART_RECLAIM_NEEDED, "RESTART_RECLAIM_NEEDED" }, \ +- { SEQ4_STATUS_CB_PATH_DOWN_SESSION, "CB_PATH_DOWN_SESSION" }, \ +- { SEQ4_STATUS_BACKCHANNEL_FAULT, "BACKCHANNEL_FAULT" }) +--- a/include/trace/events/rdma.h ++++ /dev/null +@@ -1,168 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Copyright (c) 2017 Oracle. All rights reserved. +- */ +- +-/* +- * enum ib_event_type, from include/rdma/ib_verbs.h +- */ +-#define IB_EVENT_LIST \ +- ib_event(CQ_ERR) \ +- ib_event(QP_FATAL) \ +- ib_event(QP_REQ_ERR) \ +- ib_event(QP_ACCESS_ERR) \ +- ib_event(COMM_EST) \ +- ib_event(SQ_DRAINED) \ +- ib_event(PATH_MIG) \ +- ib_event(PATH_MIG_ERR) \ +- ib_event(DEVICE_FATAL) \ +- ib_event(PORT_ACTIVE) \ +- ib_event(PORT_ERR) \ +- ib_event(LID_CHANGE) \ +- ib_event(PKEY_CHANGE) \ +- ib_event(SM_CHANGE) \ +- ib_event(SRQ_ERR) \ +- ib_event(SRQ_LIMIT_REACHED) \ +- ib_event(QP_LAST_WQE_REACHED) \ +- ib_event(CLIENT_REREGISTER) \ +- ib_event(GID_CHANGE) \ +- ib_event_end(WQ_FATAL) +- +-#undef ib_event +-#undef ib_event_end +- +-#define ib_event(x) TRACE_DEFINE_ENUM(IB_EVENT_##x); +-#define ib_event_end(x) TRACE_DEFINE_ENUM(IB_EVENT_##x); +- +-IB_EVENT_LIST +- +-#undef ib_event +-#undef ib_event_end +- +-#define ib_event(x) { IB_EVENT_##x, #x }, +-#define ib_event_end(x) { IB_EVENT_##x, #x } +- +-#define rdma_show_ib_event(x) \ +- __print_symbolic(x, IB_EVENT_LIST) +- +-/* +- * enum ib_wc_status type, from include/rdma/ib_verbs.h +- */ +-#define IB_WC_STATUS_LIST \ +- ib_wc_status(SUCCESS) \ +- ib_wc_status(LOC_LEN_ERR) \ +- ib_wc_status(LOC_QP_OP_ERR) \ +- ib_wc_status(LOC_EEC_OP_ERR) \ +- ib_wc_status(LOC_PROT_ERR) \ +- ib_wc_status(WR_FLUSH_ERR) \ +- ib_wc_status(MW_BIND_ERR) \ +- ib_wc_status(BAD_RESP_ERR) \ +- ib_wc_status(LOC_ACCESS_ERR) \ +- ib_wc_status(REM_INV_REQ_ERR) \ +- ib_wc_status(REM_ACCESS_ERR) \ +- ib_wc_status(REM_OP_ERR) \ +- ib_wc_status(RETRY_EXC_ERR) \ +- ib_wc_status(RNR_RETRY_EXC_ERR) \ +- ib_wc_status(LOC_RDD_VIOL_ERR) \ +- ib_wc_status(REM_INV_RD_REQ_ERR) \ +- ib_wc_status(REM_ABORT_ERR) \ +- ib_wc_status(INV_EECN_ERR) \ +- ib_wc_status(INV_EEC_STATE_ERR) \ +- ib_wc_status(FATAL_ERR) \ +- ib_wc_status(RESP_TIMEOUT_ERR) \ +- ib_wc_status_end(GENERAL_ERR) +- +-#undef ib_wc_status +-#undef ib_wc_status_end +- +-#define ib_wc_status(x) TRACE_DEFINE_ENUM(IB_WC_##x); +-#define ib_wc_status_end(x) TRACE_DEFINE_ENUM(IB_WC_##x); +- +-IB_WC_STATUS_LIST +- +-#undef ib_wc_status +-#undef ib_wc_status_end +- +-#define ib_wc_status(x) { IB_WC_##x, #x }, +-#define ib_wc_status_end(x) { IB_WC_##x, #x } +- +-#define rdma_show_wc_status(x) \ +- __print_symbolic(x, IB_WC_STATUS_LIST) +- +-/* +- * enum ib_cm_event_type, from include/rdma/ib_cm.h +- */ +-#define IB_CM_EVENT_LIST \ +- ib_cm_event(REQ_ERROR) \ +- ib_cm_event(REQ_RECEIVED) \ +- ib_cm_event(REP_ERROR) \ +- ib_cm_event(REP_RECEIVED) \ +- ib_cm_event(RTU_RECEIVED) \ +- ib_cm_event(USER_ESTABLISHED) \ +- ib_cm_event(DREQ_ERROR) \ +- ib_cm_event(DREQ_RECEIVED) \ +- ib_cm_event(DREP_RECEIVED) \ +- ib_cm_event(TIMEWAIT_EXIT) \ +- ib_cm_event(MRA_RECEIVED) \ +- ib_cm_event(REJ_RECEIVED) \ +- ib_cm_event(LAP_ERROR) \ +- ib_cm_event(LAP_RECEIVED) \ +- ib_cm_event(APR_RECEIVED) \ +- ib_cm_event(SIDR_REQ_ERROR) \ +- ib_cm_event(SIDR_REQ_RECEIVED) \ +- ib_cm_event_end(SIDR_REP_RECEIVED) +- +-#undef ib_cm_event +-#undef ib_cm_event_end +- +-#define ib_cm_event(x) TRACE_DEFINE_ENUM(IB_CM_##x); +-#define ib_cm_event_end(x) TRACE_DEFINE_ENUM(IB_CM_##x); +- +-IB_CM_EVENT_LIST +- +-#undef ib_cm_event +-#undef ib_cm_event_end +- +-#define ib_cm_event(x) { IB_CM_##x, #x }, +-#define ib_cm_event_end(x) { IB_CM_##x, #x } +- +-#define rdma_show_ib_cm_event(x) \ +- __print_symbolic(x, IB_CM_EVENT_LIST) +- +-/* +- * enum rdma_cm_event_type, from include/rdma/rdma_cm.h +- */ +-#define RDMA_CM_EVENT_LIST \ +- rdma_cm_event(ADDR_RESOLVED) \ +- rdma_cm_event(ADDR_ERROR) \ +- rdma_cm_event(ROUTE_RESOLVED) \ +- rdma_cm_event(ROUTE_ERROR) \ +- rdma_cm_event(CONNECT_REQUEST) \ +- rdma_cm_event(CONNECT_RESPONSE) \ +- rdma_cm_event(CONNECT_ERROR) \ +- rdma_cm_event(UNREACHABLE) \ +- rdma_cm_event(REJECTED) \ +- rdma_cm_event(ESTABLISHED) \ +- rdma_cm_event(DISCONNECTED) \ +- rdma_cm_event(DEVICE_REMOVAL) \ +- rdma_cm_event(MULTICAST_JOIN) \ +- rdma_cm_event(MULTICAST_ERROR) \ +- rdma_cm_event(ADDR_CHANGE) \ +- rdma_cm_event_end(TIMEWAIT_EXIT) +- +-#undef rdma_cm_event +-#undef rdma_cm_event_end +- +-#define rdma_cm_event(x) TRACE_DEFINE_ENUM(RDMA_CM_EVENT_##x); +-#define rdma_cm_event_end(x) TRACE_DEFINE_ENUM(RDMA_CM_EVENT_##x); +- +-RDMA_CM_EVENT_LIST +- +-#undef rdma_cm_event +-#undef rdma_cm_event_end +- +-#define rdma_cm_event(x) { RDMA_CM_EVENT_##x, #x }, +-#define rdma_cm_event_end(x) { RDMA_CM_EVENT_##x, #x } +- +-#define rdma_show_cm_event(x) \ +- __print_symbolic(x, RDMA_CM_EVENT_LIST) +--- a/include/trace/events/rpcgss.h ++++ b/include/trace/events/rpcgss.h +@@ -13,7 +13,7 @@ + + #include + +-#include ++#include + + /** + ** GSS-API related trace events +--- a/include/trace/events/rpcrdma.h ++++ b/include/trace/events/rpcrdma.h +@@ -15,8 +15,8 @@ + #include + #include + +-#include +-#include ++#include ++#include + + /** + ** Event classes +--- a/include/trace/events/sunrpc.h ++++ b/include/trace/events/sunrpc.h +@@ -14,7 +14,7 @@ + #include + #include + +-#include ++#include + + TRACE_DEFINE_ENUM(SOCK_STREAM); + TRACE_DEFINE_ENUM(SOCK_DGRAM); +--- a/include/trace/events/sunrpc_base.h ++++ /dev/null +@@ -1,18 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Copyright (c) 2021 Oracle and/or its affiliates. +- * +- * Common types and format specifiers for sunrpc. +- */ +- +-#if !defined(_TRACE_SUNRPC_BASE_H) +-#define _TRACE_SUNRPC_BASE_H +- +-#include +- +-#define SUNRPC_TRACE_PID_SPECIFIER "%08x" +-#define SUNRPC_TRACE_CLID_SPECIFIER "%08x" +-#define SUNRPC_TRACE_TASK_SPECIFIER \ +- "task:" SUNRPC_TRACE_PID_SPECIFIER "@" SUNRPC_TRACE_CLID_SPECIFIER +- +-#endif /* _TRACE_SUNRPC_BASE_H */ +--- /dev/null ++++ b/include/trace/misc/fs.h +@@ -0,0 +1,122 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Display helpers for generic filesystem items ++ * ++ * Author: Chuck Lever ++ * ++ * Copyright (c) 2020, Oracle and/or its affiliates. ++ */ ++ ++#include ++ ++#define show_fs_dirent_type(x) \ ++ __print_symbolic(x, \ ++ { DT_UNKNOWN, "UNKNOWN" }, \ ++ { DT_FIFO, "FIFO" }, \ ++ { DT_CHR, "CHR" }, \ ++ { DT_DIR, "DIR" }, \ ++ { DT_BLK, "BLK" }, \ ++ { DT_REG, "REG" }, \ ++ { DT_LNK, "LNK" }, \ ++ { DT_SOCK, "SOCK" }, \ ++ { DT_WHT, "WHT" }) ++ ++#define show_fs_fcntl_open_flags(x) \ ++ __print_flags(x, "|", \ ++ { O_WRONLY, "O_WRONLY" }, \ ++ { O_RDWR, "O_RDWR" }, \ ++ { O_CREAT, "O_CREAT" }, \ ++ { O_EXCL, "O_EXCL" }, \ ++ { O_NOCTTY, "O_NOCTTY" }, \ ++ { O_TRUNC, "O_TRUNC" }, \ ++ { O_APPEND, "O_APPEND" }, \ ++ { O_NONBLOCK, "O_NONBLOCK" }, \ ++ { O_DSYNC, "O_DSYNC" }, \ ++ { O_DIRECT, "O_DIRECT" }, \ ++ { O_LARGEFILE, "O_LARGEFILE" }, \ ++ { O_DIRECTORY, "O_DIRECTORY" }, \ ++ { O_NOFOLLOW, "O_NOFOLLOW" }, \ ++ { O_NOATIME, "O_NOATIME" }, \ ++ { O_CLOEXEC, "O_CLOEXEC" }) ++ ++#define __fmode_flag(x) { (__force unsigned long)FMODE_##x, #x } ++#define show_fs_fmode_flags(x) \ ++ __print_flags(x, "|", \ ++ __fmode_flag(READ), \ ++ __fmode_flag(WRITE), \ ++ __fmode_flag(EXEC)) ++ ++#ifdef CONFIG_64BIT ++#define show_fs_fcntl_cmd(x) \ ++ __print_symbolic(x, \ ++ { F_DUPFD, "DUPFD" }, \ ++ { F_GETFD, "GETFD" }, \ ++ { F_SETFD, "SETFD" }, \ ++ { F_GETFL, "GETFL" }, \ ++ { F_SETFL, "SETFL" }, \ ++ { F_GETLK, "GETLK" }, \ ++ { F_SETLK, "SETLK" }, \ ++ { F_SETLKW, "SETLKW" }, \ ++ { F_SETOWN, "SETOWN" }, \ ++ { F_GETOWN, "GETOWN" }, \ ++ { F_SETSIG, "SETSIG" }, \ ++ { F_GETSIG, "GETSIG" }, \ ++ { F_SETOWN_EX, "SETOWN_EX" }, \ ++ { F_GETOWN_EX, "GETOWN_EX" }, \ ++ { F_GETOWNER_UIDS, "GETOWNER_UIDS" }, \ ++ { F_OFD_GETLK, "OFD_GETLK" }, \ ++ { F_OFD_SETLK, "OFD_SETLK" }, \ ++ { F_OFD_SETLKW, "OFD_SETLKW" }) ++#else /* CONFIG_64BIT */ ++#define show_fs_fcntl_cmd(x) \ ++ __print_symbolic(x, \ ++ { F_DUPFD, "DUPFD" }, \ ++ { F_GETFD, "GETFD" }, \ ++ { F_SETFD, "SETFD" }, \ ++ { F_GETFL, "GETFL" }, \ ++ { F_SETFL, "SETFL" }, \ ++ { F_GETLK, "GETLK" }, \ ++ { F_SETLK, "SETLK" }, \ ++ { F_SETLKW, "SETLKW" }, \ ++ { F_SETOWN, "SETOWN" }, \ ++ { F_GETOWN, "GETOWN" }, \ ++ { F_SETSIG, "SETSIG" }, \ ++ { F_GETSIG, "GETSIG" }, \ ++ { F_GETLK64, "GETLK64" }, \ ++ { F_SETLK64, "SETLK64" }, \ ++ { F_SETLKW64, "SETLKW64" }, \ ++ { F_SETOWN_EX, "SETOWN_EX" }, \ ++ { F_GETOWN_EX, "GETOWN_EX" }, \ ++ { F_GETOWNER_UIDS, "GETOWNER_UIDS" }, \ ++ { F_OFD_GETLK, "OFD_GETLK" }, \ ++ { F_OFD_SETLK, "OFD_SETLK" }, \ ++ { F_OFD_SETLKW, "OFD_SETLKW" }) ++#endif /* CONFIG_64BIT */ ++ ++#define show_fs_fcntl_lock_type(x) \ ++ __print_symbolic(x, \ ++ { F_RDLCK, "RDLCK" }, \ ++ { F_WRLCK, "WRLCK" }, \ ++ { F_UNLCK, "UNLCK" }) ++ ++#define show_fs_lookup_flags(flags) \ ++ __print_flags(flags, "|", \ ++ { LOOKUP_FOLLOW, "FOLLOW" }, \ ++ { LOOKUP_DIRECTORY, "DIRECTORY" }, \ ++ { LOOKUP_AUTOMOUNT, "AUTOMOUNT" }, \ ++ { LOOKUP_EMPTY, "EMPTY" }, \ ++ { LOOKUP_DOWN, "DOWN" }, \ ++ { LOOKUP_MOUNTPOINT, "MOUNTPOINT" }, \ ++ { LOOKUP_REVAL, "REVAL" }, \ ++ { LOOKUP_RCU, "RCU" }, \ ++ { LOOKUP_OPEN, "OPEN" }, \ ++ { LOOKUP_CREATE, "CREATE" }, \ ++ { LOOKUP_EXCL, "EXCL" }, \ ++ { LOOKUP_RENAME_TARGET, "RENAME_TARGET" }, \ ++ { LOOKUP_PARENT, "PARENT" }, \ ++ { LOOKUP_NO_SYMLINKS, "NO_SYMLINKS" }, \ ++ { LOOKUP_NO_MAGICLINKS, "NO_MAGICLINKS" }, \ ++ { LOOKUP_NO_XDEV, "NO_XDEV" }, \ ++ { LOOKUP_BENEATH, "BENEATH" }, \ ++ { LOOKUP_IN_ROOT, "IN_ROOT" }, \ ++ { LOOKUP_CACHED, "CACHED" }) +--- /dev/null ++++ b/include/trace/misc/nfs.h +@@ -0,0 +1,375 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Display helpers for NFS protocol elements ++ * ++ * Author: Chuck Lever ++ * ++ * Copyright (c) 2020, Oracle and/or its affiliates. ++ */ ++ ++#include ++#include ++#include ++ ++TRACE_DEFINE_ENUM(NFS_OK); ++TRACE_DEFINE_ENUM(NFSERR_PERM); ++TRACE_DEFINE_ENUM(NFSERR_NOENT); ++TRACE_DEFINE_ENUM(NFSERR_IO); ++TRACE_DEFINE_ENUM(NFSERR_NXIO); ++TRACE_DEFINE_ENUM(NFSERR_EAGAIN); ++TRACE_DEFINE_ENUM(NFSERR_ACCES); ++TRACE_DEFINE_ENUM(NFSERR_EXIST); ++TRACE_DEFINE_ENUM(NFSERR_XDEV); ++TRACE_DEFINE_ENUM(NFSERR_NODEV); ++TRACE_DEFINE_ENUM(NFSERR_NOTDIR); ++TRACE_DEFINE_ENUM(NFSERR_ISDIR); ++TRACE_DEFINE_ENUM(NFSERR_INVAL); ++TRACE_DEFINE_ENUM(NFSERR_FBIG); ++TRACE_DEFINE_ENUM(NFSERR_NOSPC); ++TRACE_DEFINE_ENUM(NFSERR_ROFS); ++TRACE_DEFINE_ENUM(NFSERR_MLINK); ++TRACE_DEFINE_ENUM(NFSERR_OPNOTSUPP); ++TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG); ++TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY); ++TRACE_DEFINE_ENUM(NFSERR_DQUOT); ++TRACE_DEFINE_ENUM(NFSERR_STALE); ++TRACE_DEFINE_ENUM(NFSERR_REMOTE); ++TRACE_DEFINE_ENUM(NFSERR_WFLUSH); ++TRACE_DEFINE_ENUM(NFSERR_BADHANDLE); ++TRACE_DEFINE_ENUM(NFSERR_NOT_SYNC); ++TRACE_DEFINE_ENUM(NFSERR_BAD_COOKIE); ++TRACE_DEFINE_ENUM(NFSERR_NOTSUPP); ++TRACE_DEFINE_ENUM(NFSERR_TOOSMALL); ++TRACE_DEFINE_ENUM(NFSERR_SERVERFAULT); ++TRACE_DEFINE_ENUM(NFSERR_BADTYPE); ++TRACE_DEFINE_ENUM(NFSERR_JUKEBOX); ++ ++#define show_nfs_status(x) \ ++ __print_symbolic(x, \ ++ { NFS_OK, "OK" }, \ ++ { NFSERR_PERM, "PERM" }, \ ++ { NFSERR_NOENT, "NOENT" }, \ ++ { NFSERR_IO, "IO" }, \ ++ { NFSERR_NXIO, "NXIO" }, \ ++ { ECHILD, "CHILD" }, \ ++ { NFSERR_EAGAIN, "AGAIN" }, \ ++ { NFSERR_ACCES, "ACCES" }, \ ++ { NFSERR_EXIST, "EXIST" }, \ ++ { NFSERR_XDEV, "XDEV" }, \ ++ { NFSERR_NODEV, "NODEV" }, \ ++ { NFSERR_NOTDIR, "NOTDIR" }, \ ++ { NFSERR_ISDIR, "ISDIR" }, \ ++ { NFSERR_INVAL, "INVAL" }, \ ++ { NFSERR_FBIG, "FBIG" }, \ ++ { NFSERR_NOSPC, "NOSPC" }, \ ++ { NFSERR_ROFS, "ROFS" }, \ ++ { NFSERR_MLINK, "MLINK" }, \ ++ { NFSERR_OPNOTSUPP, "OPNOTSUPP" }, \ ++ { NFSERR_NAMETOOLONG, "NAMETOOLONG" }, \ ++ { NFSERR_NOTEMPTY, "NOTEMPTY" }, \ ++ { NFSERR_DQUOT, "DQUOT" }, \ ++ { NFSERR_STALE, "STALE" }, \ ++ { NFSERR_REMOTE, "REMOTE" }, \ ++ { NFSERR_WFLUSH, "WFLUSH" }, \ ++ { NFSERR_BADHANDLE, "BADHANDLE" }, \ ++ { NFSERR_NOT_SYNC, "NOTSYNC" }, \ ++ { NFSERR_BAD_COOKIE, "BADCOOKIE" }, \ ++ { NFSERR_NOTSUPP, "NOTSUPP" }, \ ++ { NFSERR_TOOSMALL, "TOOSMALL" }, \ ++ { NFSERR_SERVERFAULT, "REMOTEIO" }, \ ++ { NFSERR_BADTYPE, "BADTYPE" }, \ ++ { NFSERR_JUKEBOX, "JUKEBOX" }) ++ ++TRACE_DEFINE_ENUM(NFS_UNSTABLE); ++TRACE_DEFINE_ENUM(NFS_DATA_SYNC); ++TRACE_DEFINE_ENUM(NFS_FILE_SYNC); ++ ++#define show_nfs_stable_how(x) \ ++ __print_symbolic(x, \ ++ { NFS_UNSTABLE, "UNSTABLE" }, \ ++ { NFS_DATA_SYNC, "DATA_SYNC" }, \ ++ { NFS_FILE_SYNC, "FILE_SYNC" }) ++ ++TRACE_DEFINE_ENUM(NFS4_OK); ++TRACE_DEFINE_ENUM(NFS4ERR_ACCESS); ++TRACE_DEFINE_ENUM(NFS4ERR_ATTRNOTSUPP); ++TRACE_DEFINE_ENUM(NFS4ERR_ADMIN_REVOKED); ++TRACE_DEFINE_ENUM(NFS4ERR_BACK_CHAN_BUSY); ++TRACE_DEFINE_ENUM(NFS4ERR_BADCHAR); ++TRACE_DEFINE_ENUM(NFS4ERR_BADHANDLE); ++TRACE_DEFINE_ENUM(NFS4ERR_BADIOMODE); ++TRACE_DEFINE_ENUM(NFS4ERR_BADLAYOUT); ++TRACE_DEFINE_ENUM(NFS4ERR_BADLABEL); ++TRACE_DEFINE_ENUM(NFS4ERR_BADNAME); ++TRACE_DEFINE_ENUM(NFS4ERR_BADOWNER); ++TRACE_DEFINE_ENUM(NFS4ERR_BADSESSION); ++TRACE_DEFINE_ENUM(NFS4ERR_BADSLOT); ++TRACE_DEFINE_ENUM(NFS4ERR_BADTYPE); ++TRACE_DEFINE_ENUM(NFS4ERR_BADXDR); ++TRACE_DEFINE_ENUM(NFS4ERR_BAD_COOKIE); ++TRACE_DEFINE_ENUM(NFS4ERR_BAD_HIGH_SLOT); ++TRACE_DEFINE_ENUM(NFS4ERR_BAD_RANGE); ++TRACE_DEFINE_ENUM(NFS4ERR_BAD_SEQID); ++TRACE_DEFINE_ENUM(NFS4ERR_BAD_SESSION_DIGEST); ++TRACE_DEFINE_ENUM(NFS4ERR_BAD_STATEID); ++TRACE_DEFINE_ENUM(NFS4ERR_CB_PATH_DOWN); ++TRACE_DEFINE_ENUM(NFS4ERR_CLID_INUSE); ++TRACE_DEFINE_ENUM(NFS4ERR_CLIENTID_BUSY); ++TRACE_DEFINE_ENUM(NFS4ERR_COMPLETE_ALREADY); ++TRACE_DEFINE_ENUM(NFS4ERR_CONN_NOT_BOUND_TO_SESSION); ++TRACE_DEFINE_ENUM(NFS4ERR_DEADLOCK); ++TRACE_DEFINE_ENUM(NFS4ERR_DEADSESSION); ++TRACE_DEFINE_ENUM(NFS4ERR_DELAY); ++TRACE_DEFINE_ENUM(NFS4ERR_DELEG_ALREADY_WANTED); ++TRACE_DEFINE_ENUM(NFS4ERR_DELEG_REVOKED); ++TRACE_DEFINE_ENUM(NFS4ERR_DENIED); ++TRACE_DEFINE_ENUM(NFS4ERR_DIRDELEG_UNAVAIL); ++TRACE_DEFINE_ENUM(NFS4ERR_DQUOT); ++TRACE_DEFINE_ENUM(NFS4ERR_ENCR_ALG_UNSUPP); ++TRACE_DEFINE_ENUM(NFS4ERR_EXIST); ++TRACE_DEFINE_ENUM(NFS4ERR_EXPIRED); ++TRACE_DEFINE_ENUM(NFS4ERR_FBIG); ++TRACE_DEFINE_ENUM(NFS4ERR_FHEXPIRED); ++TRACE_DEFINE_ENUM(NFS4ERR_FILE_OPEN); ++TRACE_DEFINE_ENUM(NFS4ERR_GRACE); ++TRACE_DEFINE_ENUM(NFS4ERR_HASH_ALG_UNSUPP); ++TRACE_DEFINE_ENUM(NFS4ERR_INVAL); ++TRACE_DEFINE_ENUM(NFS4ERR_IO); ++TRACE_DEFINE_ENUM(NFS4ERR_ISDIR); ++TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTTRYLATER); ++TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTUNAVAILABLE); ++TRACE_DEFINE_ENUM(NFS4ERR_LEASE_MOVED); ++TRACE_DEFINE_ENUM(NFS4ERR_LOCKED); ++TRACE_DEFINE_ENUM(NFS4ERR_LOCKS_HELD); ++TRACE_DEFINE_ENUM(NFS4ERR_LOCK_RANGE); ++TRACE_DEFINE_ENUM(NFS4ERR_MINOR_VERS_MISMATCH); ++TRACE_DEFINE_ENUM(NFS4ERR_MLINK); ++TRACE_DEFINE_ENUM(NFS4ERR_MOVED); ++TRACE_DEFINE_ENUM(NFS4ERR_NAMETOOLONG); ++TRACE_DEFINE_ENUM(NFS4ERR_NOENT); ++TRACE_DEFINE_ENUM(NFS4ERR_NOFILEHANDLE); ++TRACE_DEFINE_ENUM(NFS4ERR_NOMATCHING_LAYOUT); ++TRACE_DEFINE_ENUM(NFS4ERR_NOSPC); ++TRACE_DEFINE_ENUM(NFS4ERR_NOTDIR); ++TRACE_DEFINE_ENUM(NFS4ERR_NOTEMPTY); ++TRACE_DEFINE_ENUM(NFS4ERR_NOTSUPP); ++TRACE_DEFINE_ENUM(NFS4ERR_NOT_ONLY_OP); ++TRACE_DEFINE_ENUM(NFS4ERR_NOT_SAME); ++TRACE_DEFINE_ENUM(NFS4ERR_NO_GRACE); ++TRACE_DEFINE_ENUM(NFS4ERR_NXIO); ++TRACE_DEFINE_ENUM(NFS4ERR_OLD_STATEID); ++TRACE_DEFINE_ENUM(NFS4ERR_OPENMODE); ++TRACE_DEFINE_ENUM(NFS4ERR_OP_ILLEGAL); ++TRACE_DEFINE_ENUM(NFS4ERR_OP_NOT_IN_SESSION); ++TRACE_DEFINE_ENUM(NFS4ERR_PERM); ++TRACE_DEFINE_ENUM(NFS4ERR_PNFS_IO_HOLE); ++TRACE_DEFINE_ENUM(NFS4ERR_PNFS_NO_LAYOUT); ++TRACE_DEFINE_ENUM(NFS4ERR_RECALLCONFLICT); ++TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_BAD); ++TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_CONFLICT); ++TRACE_DEFINE_ENUM(NFS4ERR_REJECT_DELEG); ++TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG); ++TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG_TO_CACHE); ++TRACE_DEFINE_ENUM(NFS4ERR_REQ_TOO_BIG); ++TRACE_DEFINE_ENUM(NFS4ERR_RESOURCE); ++TRACE_DEFINE_ENUM(NFS4ERR_RESTOREFH); ++TRACE_DEFINE_ENUM(NFS4ERR_RETRY_UNCACHED_REP); ++TRACE_DEFINE_ENUM(NFS4ERR_RETURNCONFLICT); ++TRACE_DEFINE_ENUM(NFS4ERR_ROFS); ++TRACE_DEFINE_ENUM(NFS4ERR_SAME); ++TRACE_DEFINE_ENUM(NFS4ERR_SHARE_DENIED); ++TRACE_DEFINE_ENUM(NFS4ERR_SEQUENCE_POS); ++TRACE_DEFINE_ENUM(NFS4ERR_SEQ_FALSE_RETRY); ++TRACE_DEFINE_ENUM(NFS4ERR_SEQ_MISORDERED); ++TRACE_DEFINE_ENUM(NFS4ERR_SERVERFAULT); ++TRACE_DEFINE_ENUM(NFS4ERR_STALE); ++TRACE_DEFINE_ENUM(NFS4ERR_STALE_CLIENTID); ++TRACE_DEFINE_ENUM(NFS4ERR_STALE_STATEID); ++TRACE_DEFINE_ENUM(NFS4ERR_SYMLINK); ++TRACE_DEFINE_ENUM(NFS4ERR_TOOSMALL); ++TRACE_DEFINE_ENUM(NFS4ERR_TOO_MANY_OPS); ++TRACE_DEFINE_ENUM(NFS4ERR_UNKNOWN_LAYOUTTYPE); ++TRACE_DEFINE_ENUM(NFS4ERR_UNSAFE_COMPOUND); ++TRACE_DEFINE_ENUM(NFS4ERR_WRONGSEC); ++TRACE_DEFINE_ENUM(NFS4ERR_WRONG_CRED); ++TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE); ++TRACE_DEFINE_ENUM(NFS4ERR_XDEV); ++ ++TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_MDS); ++TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS); ++ ++#define show_nfs4_status(x) \ ++ __print_symbolic(x, \ ++ { NFS4_OK, "OK" }, \ ++ { EPERM, "EPERM" }, \ ++ { ENOENT, "ENOENT" }, \ ++ { EIO, "EIO" }, \ ++ { ENXIO, "ENXIO" }, \ ++ { EACCES, "EACCES" }, \ ++ { EEXIST, "EEXIST" }, \ ++ { EXDEV, "EXDEV" }, \ ++ { ENOTDIR, "ENOTDIR" }, \ ++ { EISDIR, "EISDIR" }, \ ++ { EFBIG, "EFBIG" }, \ ++ { ENOSPC, "ENOSPC" }, \ ++ { EROFS, "EROFS" }, \ ++ { EMLINK, "EMLINK" }, \ ++ { ENAMETOOLONG, "ENAMETOOLONG" }, \ ++ { ENOTEMPTY, "ENOTEMPTY" }, \ ++ { EDQUOT, "EDQUOT" }, \ ++ { ESTALE, "ESTALE" }, \ ++ { EBADHANDLE, "EBADHANDLE" }, \ ++ { EBADCOOKIE, "EBADCOOKIE" }, \ ++ { ENOTSUPP, "ENOTSUPP" }, \ ++ { ETOOSMALL, "ETOOSMALL" }, \ ++ { EREMOTEIO, "EREMOTEIO" }, \ ++ { EBADTYPE, "EBADTYPE" }, \ ++ { EAGAIN, "EAGAIN" }, \ ++ { ELOOP, "ELOOP" }, \ ++ { EOPNOTSUPP, "EOPNOTSUPP" }, \ ++ { EDEADLK, "EDEADLK" }, \ ++ { ENOMEM, "ENOMEM" }, \ ++ { EKEYEXPIRED, "EKEYEXPIRED" }, \ ++ { ETIMEDOUT, "ETIMEDOUT" }, \ ++ { ERESTARTSYS, "ERESTARTSYS" }, \ ++ { ECONNREFUSED, "ECONNREFUSED" }, \ ++ { ECONNRESET, "ECONNRESET" }, \ ++ { ENETUNREACH, "ENETUNREACH" }, \ ++ { EHOSTUNREACH, "EHOSTUNREACH" }, \ ++ { EHOSTDOWN, "EHOSTDOWN" }, \ ++ { EPIPE, "EPIPE" }, \ ++ { EPFNOSUPPORT, "EPFNOSUPPORT" }, \ ++ { EPROTONOSUPPORT, "EPROTONOSUPPORT" }, \ ++ { NFS4ERR_ACCESS, "ACCESS" }, \ ++ { NFS4ERR_ATTRNOTSUPP, "ATTRNOTSUPP" }, \ ++ { NFS4ERR_ADMIN_REVOKED, "ADMIN_REVOKED" }, \ ++ { NFS4ERR_BACK_CHAN_BUSY, "BACK_CHAN_BUSY" }, \ ++ { NFS4ERR_BADCHAR, "BADCHAR" }, \ ++ { NFS4ERR_BADHANDLE, "BADHANDLE" }, \ ++ { NFS4ERR_BADIOMODE, "BADIOMODE" }, \ ++ { NFS4ERR_BADLAYOUT, "BADLAYOUT" }, \ ++ { NFS4ERR_BADLABEL, "BADLABEL" }, \ ++ { NFS4ERR_BADNAME, "BADNAME" }, \ ++ { NFS4ERR_BADOWNER, "BADOWNER" }, \ ++ { NFS4ERR_BADSESSION, "BADSESSION" }, \ ++ { NFS4ERR_BADSLOT, "BADSLOT" }, \ ++ { NFS4ERR_BADTYPE, "BADTYPE" }, \ ++ { NFS4ERR_BADXDR, "BADXDR" }, \ ++ { NFS4ERR_BAD_COOKIE, "BAD_COOKIE" }, \ ++ { NFS4ERR_BAD_HIGH_SLOT, "BAD_HIGH_SLOT" }, \ ++ { NFS4ERR_BAD_RANGE, "BAD_RANGE" }, \ ++ { NFS4ERR_BAD_SEQID, "BAD_SEQID" }, \ ++ { NFS4ERR_BAD_SESSION_DIGEST, "BAD_SESSION_DIGEST" }, \ ++ { NFS4ERR_BAD_STATEID, "BAD_STATEID" }, \ ++ { NFS4ERR_CB_PATH_DOWN, "CB_PATH_DOWN" }, \ ++ { NFS4ERR_CLID_INUSE, "CLID_INUSE" }, \ ++ { NFS4ERR_CLIENTID_BUSY, "CLIENTID_BUSY" }, \ ++ { NFS4ERR_COMPLETE_ALREADY, "COMPLETE_ALREADY" }, \ ++ { NFS4ERR_CONN_NOT_BOUND_TO_SESSION, "CONN_NOT_BOUND_TO_SESSION" }, \ ++ { NFS4ERR_DEADLOCK, "DEADLOCK" }, \ ++ { NFS4ERR_DEADSESSION, "DEAD_SESSION" }, \ ++ { NFS4ERR_DELAY, "DELAY" }, \ ++ { NFS4ERR_DELEG_ALREADY_WANTED, "DELEG_ALREADY_WANTED" }, \ ++ { NFS4ERR_DELEG_REVOKED, "DELEG_REVOKED" }, \ ++ { NFS4ERR_DENIED, "DENIED" }, \ ++ { NFS4ERR_DIRDELEG_UNAVAIL, "DIRDELEG_UNAVAIL" }, \ ++ { NFS4ERR_DQUOT, "DQUOT" }, \ ++ { NFS4ERR_ENCR_ALG_UNSUPP, "ENCR_ALG_UNSUPP" }, \ ++ { NFS4ERR_EXIST, "EXIST" }, \ ++ { NFS4ERR_EXPIRED, "EXPIRED" }, \ ++ { NFS4ERR_FBIG, "FBIG" }, \ ++ { NFS4ERR_FHEXPIRED, "FHEXPIRED" }, \ ++ { NFS4ERR_FILE_OPEN, "FILE_OPEN" }, \ ++ { NFS4ERR_GRACE, "GRACE" }, \ ++ { NFS4ERR_HASH_ALG_UNSUPP, "HASH_ALG_UNSUPP" }, \ ++ { NFS4ERR_INVAL, "INVAL" }, \ ++ { NFS4ERR_IO, "IO" }, \ ++ { NFS4ERR_ISDIR, "ISDIR" }, \ ++ { NFS4ERR_LAYOUTTRYLATER, "LAYOUTTRYLATER" }, \ ++ { NFS4ERR_LAYOUTUNAVAILABLE, "LAYOUTUNAVAILABLE" }, \ ++ { NFS4ERR_LEASE_MOVED, "LEASE_MOVED" }, \ ++ { NFS4ERR_LOCKED, "LOCKED" }, \ ++ { NFS4ERR_LOCKS_HELD, "LOCKS_HELD" }, \ ++ { NFS4ERR_LOCK_RANGE, "LOCK_RANGE" }, \ ++ { NFS4ERR_MINOR_VERS_MISMATCH, "MINOR_VERS_MISMATCH" }, \ ++ { NFS4ERR_MLINK, "MLINK" }, \ ++ { NFS4ERR_MOVED, "MOVED" }, \ ++ { NFS4ERR_NAMETOOLONG, "NAMETOOLONG" }, \ ++ { NFS4ERR_NOENT, "NOENT" }, \ ++ { NFS4ERR_NOFILEHANDLE, "NOFILEHANDLE" }, \ ++ { NFS4ERR_NOMATCHING_LAYOUT, "NOMATCHING_LAYOUT" }, \ ++ { NFS4ERR_NOSPC, "NOSPC" }, \ ++ { NFS4ERR_NOTDIR, "NOTDIR" }, \ ++ { NFS4ERR_NOTEMPTY, "NOTEMPTY" }, \ ++ { NFS4ERR_NOTSUPP, "NOTSUPP" }, \ ++ { NFS4ERR_NOT_ONLY_OP, "NOT_ONLY_OP" }, \ ++ { NFS4ERR_NOT_SAME, "NOT_SAME" }, \ ++ { NFS4ERR_NO_GRACE, "NO_GRACE" }, \ ++ { NFS4ERR_NXIO, "NXIO" }, \ ++ { NFS4ERR_OLD_STATEID, "OLD_STATEID" }, \ ++ { NFS4ERR_OPENMODE, "OPENMODE" }, \ ++ { NFS4ERR_OP_ILLEGAL, "OP_ILLEGAL" }, \ ++ { NFS4ERR_OP_NOT_IN_SESSION, "OP_NOT_IN_SESSION" }, \ ++ { NFS4ERR_PERM, "PERM" }, \ ++ { NFS4ERR_PNFS_IO_HOLE, "PNFS_IO_HOLE" }, \ ++ { NFS4ERR_PNFS_NO_LAYOUT, "PNFS_NO_LAYOUT" }, \ ++ { NFS4ERR_RECALLCONFLICT, "RECALLCONFLICT" }, \ ++ { NFS4ERR_RECLAIM_BAD, "RECLAIM_BAD" }, \ ++ { NFS4ERR_RECLAIM_CONFLICT, "RECLAIM_CONFLICT" }, \ ++ { NFS4ERR_REJECT_DELEG, "REJECT_DELEG" }, \ ++ { NFS4ERR_REP_TOO_BIG, "REP_TOO_BIG" }, \ ++ { NFS4ERR_REP_TOO_BIG_TO_CACHE, "REP_TOO_BIG_TO_CACHE" }, \ ++ { NFS4ERR_REQ_TOO_BIG, "REQ_TOO_BIG" }, \ ++ { NFS4ERR_RESOURCE, "RESOURCE" }, \ ++ { NFS4ERR_RESTOREFH, "RESTOREFH" }, \ ++ { NFS4ERR_RETRY_UNCACHED_REP, "RETRY_UNCACHED_REP" }, \ ++ { NFS4ERR_RETURNCONFLICT, "RETURNCONFLICT" }, \ ++ { NFS4ERR_ROFS, "ROFS" }, \ ++ { NFS4ERR_SAME, "SAME" }, \ ++ { NFS4ERR_SHARE_DENIED, "SHARE_DENIED" }, \ ++ { NFS4ERR_SEQUENCE_POS, "SEQUENCE_POS" }, \ ++ { NFS4ERR_SEQ_FALSE_RETRY, "SEQ_FALSE_RETRY" }, \ ++ { NFS4ERR_SEQ_MISORDERED, "SEQ_MISORDERED" }, \ ++ { NFS4ERR_SERVERFAULT, "SERVERFAULT" }, \ ++ { NFS4ERR_STALE, "STALE" }, \ ++ { NFS4ERR_STALE_CLIENTID, "STALE_CLIENTID" }, \ ++ { NFS4ERR_STALE_STATEID, "STALE_STATEID" }, \ ++ { NFS4ERR_SYMLINK, "SYMLINK" }, \ ++ { NFS4ERR_TOOSMALL, "TOOSMALL" }, \ ++ { NFS4ERR_TOO_MANY_OPS, "TOO_MANY_OPS" }, \ ++ { NFS4ERR_UNKNOWN_LAYOUTTYPE, "UNKNOWN_LAYOUTTYPE" }, \ ++ { NFS4ERR_UNSAFE_COMPOUND, "UNSAFE_COMPOUND" }, \ ++ { NFS4ERR_WRONGSEC, "WRONGSEC" }, \ ++ { NFS4ERR_WRONG_CRED, "WRONG_CRED" }, \ ++ { NFS4ERR_WRONG_TYPE, "WRONG_TYPE" }, \ ++ { NFS4ERR_XDEV, "XDEV" }, \ ++ /* ***** Internal to Linux NFS client ***** */ \ ++ { NFS4ERR_RESET_TO_MDS, "RESET_TO_MDS" }, \ ++ { NFS4ERR_RESET_TO_PNFS, "RESET_TO_PNFS" }) ++ ++#define show_nfs4_verifier(x) \ ++ __print_hex_str(x, NFS4_VERIFIER_SIZE) ++ ++TRACE_DEFINE_ENUM(IOMODE_READ); ++TRACE_DEFINE_ENUM(IOMODE_RW); ++TRACE_DEFINE_ENUM(IOMODE_ANY); ++ ++#define show_pnfs_layout_iomode(x) \ ++ __print_symbolic(x, \ ++ { IOMODE_READ, "READ" }, \ ++ { IOMODE_RW, "RW" }, \ ++ { IOMODE_ANY, "ANY" }) ++ ++#define show_nfs4_seq4_status(x) \ ++ __print_flags(x, "|", \ ++ { SEQ4_STATUS_CB_PATH_DOWN, "CB_PATH_DOWN" }, \ ++ { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING, "CB_GSS_CONTEXTS_EXPIRING" }, \ ++ { SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED, "CB_GSS_CONTEXTS_EXPIRED" }, \ ++ { SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, "EXPIRED_ALL_STATE_REVOKED" }, \ ++ { SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, "EXPIRED_SOME_STATE_REVOKED" }, \ ++ { SEQ4_STATUS_ADMIN_STATE_REVOKED, "ADMIN_STATE_REVOKED" }, \ ++ { SEQ4_STATUS_RECALLABLE_STATE_REVOKED, "RECALLABLE_STATE_REVOKED" }, \ ++ { SEQ4_STATUS_LEASE_MOVED, "LEASE_MOVED" }, \ ++ { SEQ4_STATUS_RESTART_RECLAIM_NEEDED, "RESTART_RECLAIM_NEEDED" }, \ ++ { SEQ4_STATUS_CB_PATH_DOWN_SESSION, "CB_PATH_DOWN_SESSION" }, \ ++ { SEQ4_STATUS_BACKCHANNEL_FAULT, "BACKCHANNEL_FAULT" }) +--- /dev/null ++++ b/include/trace/misc/rdma.h +@@ -0,0 +1,168 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (c) 2017 Oracle. All rights reserved. ++ */ ++ ++/* ++ * enum ib_event_type, from include/rdma/ib_verbs.h ++ */ ++#define IB_EVENT_LIST \ ++ ib_event(CQ_ERR) \ ++ ib_event(QP_FATAL) \ ++ ib_event(QP_REQ_ERR) \ ++ ib_event(QP_ACCESS_ERR) \ ++ ib_event(COMM_EST) \ ++ ib_event(SQ_DRAINED) \ ++ ib_event(PATH_MIG) \ ++ ib_event(PATH_MIG_ERR) \ ++ ib_event(DEVICE_FATAL) \ ++ ib_event(PORT_ACTIVE) \ ++ ib_event(PORT_ERR) \ ++ ib_event(LID_CHANGE) \ ++ ib_event(PKEY_CHANGE) \ ++ ib_event(SM_CHANGE) \ ++ ib_event(SRQ_ERR) \ ++ ib_event(SRQ_LIMIT_REACHED) \ ++ ib_event(QP_LAST_WQE_REACHED) \ ++ ib_event(CLIENT_REREGISTER) \ ++ ib_event(GID_CHANGE) \ ++ ib_event_end(WQ_FATAL) ++ ++#undef ib_event ++#undef ib_event_end ++ ++#define ib_event(x) TRACE_DEFINE_ENUM(IB_EVENT_##x); ++#define ib_event_end(x) TRACE_DEFINE_ENUM(IB_EVENT_##x); ++ ++IB_EVENT_LIST ++ ++#undef ib_event ++#undef ib_event_end ++ ++#define ib_event(x) { IB_EVENT_##x, #x }, ++#define ib_event_end(x) { IB_EVENT_##x, #x } ++ ++#define rdma_show_ib_event(x) \ ++ __print_symbolic(x, IB_EVENT_LIST) ++ ++/* ++ * enum ib_wc_status type, from include/rdma/ib_verbs.h ++ */ ++#define IB_WC_STATUS_LIST \ ++ ib_wc_status(SUCCESS) \ ++ ib_wc_status(LOC_LEN_ERR) \ ++ ib_wc_status(LOC_QP_OP_ERR) \ ++ ib_wc_status(LOC_EEC_OP_ERR) \ ++ ib_wc_status(LOC_PROT_ERR) \ ++ ib_wc_status(WR_FLUSH_ERR) \ ++ ib_wc_status(MW_BIND_ERR) \ ++ ib_wc_status(BAD_RESP_ERR) \ ++ ib_wc_status(LOC_ACCESS_ERR) \ ++ ib_wc_status(REM_INV_REQ_ERR) \ ++ ib_wc_status(REM_ACCESS_ERR) \ ++ ib_wc_status(REM_OP_ERR) \ ++ ib_wc_status(RETRY_EXC_ERR) \ ++ ib_wc_status(RNR_RETRY_EXC_ERR) \ ++ ib_wc_status(LOC_RDD_VIOL_ERR) \ ++ ib_wc_status(REM_INV_RD_REQ_ERR) \ ++ ib_wc_status(REM_ABORT_ERR) \ ++ ib_wc_status(INV_EECN_ERR) \ ++ ib_wc_status(INV_EEC_STATE_ERR) \ ++ ib_wc_status(FATAL_ERR) \ ++ ib_wc_status(RESP_TIMEOUT_ERR) \ ++ ib_wc_status_end(GENERAL_ERR) ++ ++#undef ib_wc_status ++#undef ib_wc_status_end ++ ++#define ib_wc_status(x) TRACE_DEFINE_ENUM(IB_WC_##x); ++#define ib_wc_status_end(x) TRACE_DEFINE_ENUM(IB_WC_##x); ++ ++IB_WC_STATUS_LIST ++ ++#undef ib_wc_status ++#undef ib_wc_status_end ++ ++#define ib_wc_status(x) { IB_WC_##x, #x }, ++#define ib_wc_status_end(x) { IB_WC_##x, #x } ++ ++#define rdma_show_wc_status(x) \ ++ __print_symbolic(x, IB_WC_STATUS_LIST) ++ ++/* ++ * enum ib_cm_event_type, from include/rdma/ib_cm.h ++ */ ++#define IB_CM_EVENT_LIST \ ++ ib_cm_event(REQ_ERROR) \ ++ ib_cm_event(REQ_RECEIVED) \ ++ ib_cm_event(REP_ERROR) \ ++ ib_cm_event(REP_RECEIVED) \ ++ ib_cm_event(RTU_RECEIVED) \ ++ ib_cm_event(USER_ESTABLISHED) \ ++ ib_cm_event(DREQ_ERROR) \ ++ ib_cm_event(DREQ_RECEIVED) \ ++ ib_cm_event(DREP_RECEIVED) \ ++ ib_cm_event(TIMEWAIT_EXIT) \ ++ ib_cm_event(MRA_RECEIVED) \ ++ ib_cm_event(REJ_RECEIVED) \ ++ ib_cm_event(LAP_ERROR) \ ++ ib_cm_event(LAP_RECEIVED) \ ++ ib_cm_event(APR_RECEIVED) \ ++ ib_cm_event(SIDR_REQ_ERROR) \ ++ ib_cm_event(SIDR_REQ_RECEIVED) \ ++ ib_cm_event_end(SIDR_REP_RECEIVED) ++ ++#undef ib_cm_event ++#undef ib_cm_event_end ++ ++#define ib_cm_event(x) TRACE_DEFINE_ENUM(IB_CM_##x); ++#define ib_cm_event_end(x) TRACE_DEFINE_ENUM(IB_CM_##x); ++ ++IB_CM_EVENT_LIST ++ ++#undef ib_cm_event ++#undef ib_cm_event_end ++ ++#define ib_cm_event(x) { IB_CM_##x, #x }, ++#define ib_cm_event_end(x) { IB_CM_##x, #x } ++ ++#define rdma_show_ib_cm_event(x) \ ++ __print_symbolic(x, IB_CM_EVENT_LIST) ++ ++/* ++ * enum rdma_cm_event_type, from include/rdma/rdma_cm.h ++ */ ++#define RDMA_CM_EVENT_LIST \ ++ rdma_cm_event(ADDR_RESOLVED) \ ++ rdma_cm_event(ADDR_ERROR) \ ++ rdma_cm_event(ROUTE_RESOLVED) \ ++ rdma_cm_event(ROUTE_ERROR) \ ++ rdma_cm_event(CONNECT_REQUEST) \ ++ rdma_cm_event(CONNECT_RESPONSE) \ ++ rdma_cm_event(CONNECT_ERROR) \ ++ rdma_cm_event(UNREACHABLE) \ ++ rdma_cm_event(REJECTED) \ ++ rdma_cm_event(ESTABLISHED) \ ++ rdma_cm_event(DISCONNECTED) \ ++ rdma_cm_event(DEVICE_REMOVAL) \ ++ rdma_cm_event(MULTICAST_JOIN) \ ++ rdma_cm_event(MULTICAST_ERROR) \ ++ rdma_cm_event(ADDR_CHANGE) \ ++ rdma_cm_event_end(TIMEWAIT_EXIT) ++ ++#undef rdma_cm_event ++#undef rdma_cm_event_end ++ ++#define rdma_cm_event(x) TRACE_DEFINE_ENUM(RDMA_CM_EVENT_##x); ++#define rdma_cm_event_end(x) TRACE_DEFINE_ENUM(RDMA_CM_EVENT_##x); ++ ++RDMA_CM_EVENT_LIST ++ ++#undef rdma_cm_event ++#undef rdma_cm_event_end ++ ++#define rdma_cm_event(x) { RDMA_CM_EVENT_##x, #x }, ++#define rdma_cm_event_end(x) { RDMA_CM_EVENT_##x, #x } ++ ++#define rdma_show_cm_event(x) \ ++ __print_symbolic(x, RDMA_CM_EVENT_LIST) +--- /dev/null ++++ b/include/trace/misc/sunrpc.h +@@ -0,0 +1,18 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (c) 2021 Oracle and/or its affiliates. ++ * ++ * Common types and format specifiers for sunrpc. ++ */ ++ ++#if !defined(_TRACE_SUNRPC_BASE_H) ++#define _TRACE_SUNRPC_BASE_H ++ ++#include ++ ++#define SUNRPC_TRACE_PID_SPECIFIER "%08x" ++#define SUNRPC_TRACE_CLID_SPECIFIER "%08x" ++#define SUNRPC_TRACE_TASK_SPECIFIER \ ++ "task:" SUNRPC_TRACE_PID_SPECIFIER "@" SUNRPC_TRACE_CLID_SPECIFIER ++ ++#endif /* _TRACE_SUNRPC_BASE_H */ -- 2.47.3