5.10.220-rc1 review
Subsystems (7)
Greg Kroah-Hartman
maintainerPATCH 119/770 proc/fd: In tid_fd_mode use task_lookup_fd_rcu
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
[ Upstream commit 64eb661fda0269276b4c46965832938e3f268268 ]
When discussing[1] exec and posix file locks it was realized that none of the callers of get_files_struct fundamentally needed to call get_files_struct, and that by switching them to helper functions instead it will both simplify their code and remove unnecessary increments of files_struct.count. Those unnecessary increments can result in exec unnecessarily unsharing files_struct which breaking posix locks, and it can result in fget_light having to fallback to fget reducing system performance.
Instead of manually coding finding the files struct for a task and then calling files_lookup_fd_rcu, use the helper task_lookup_fd_rcu
that combines those to steps. Making the code simpler and removing
the need to get a reference on a files_struct.
[1] https://lkml.kernel.org/r/[email protected]
v1: https://lkml.kernel.org/r/[email protected]
--- fs/proc/fd.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
fs/proc/fd.c +1 -6
@@ -83,18 +83,13 @@ static const struct file_operations proc_fdinfo_file_operations = {static bool tid_fd_mode (struct task_struct *task,unsigned fd,fmode_t *mode) { -struct files_struct *files =get_files_struct (task);struct file *file; -if (!files) -return false; -rcu_read_lock (); - file =files_lookup_fd_rcu (files, fd); + file =task_lookup_fd_rcu (task, fd);if (file) *mode = file->f_mode;rcu_read_unlock (); -put_files_struct (files);return !!file; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 120/770 kcmp: In get_file_raw_ptr use task_lookup_fd_rcu
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
[ Upstream commit ed77e80e14a3cd55c73848b9e8043020e717ce12 ]
Modify get_file_raw_ptr to use task_lookup_fd_rcu. The helper task_lookup_fd_rcu does the work of taking the task lock and verifying that task->files != NULL and then calls files_lookup_fd_rcu. So let use the helper to make a simpler implementation of get_file_raw_ptr.
--- kernel/kcmp.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
kernel/kcmp.c +2 -7
@@ -61,16 +61,11 @@ static int kcmp_ptr(void *v1, void *v2, enum kcmp_type type)static struct file *get_file_raw_ptr (struct task_struct *task,unsigned int idx) { -struct file *file =NULL ; +struct file *file; -task_lock (task);rcu_read_lock (); - -if (task->files) - file =files_lookup_fd_rcu (task->files, idx); - + file =task_lookup_fd_rcu (task, idx);rcu_read_unlock (); -task_unlock (task);return file; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 121/770 file: Implement task_lookup_next_fd_rcu
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
[ Upstream commit e9a53aeb5e0a838f10fcea74235664e7ad5e6e1a ]
As a companion to fget_task and task_lookup_fd_rcu implement task_lookup_next_fd_rcu that will return the struct file for the first file descriptor number that is equal or greater than the fd argument value, or NULL if there is no such struct file.
This allows file descriptors of foreign processes to be iterated through safely, without needed to increment the count on files_struct.
Some concern[1] has been expressed that this function takes the task_lock for each iteration and thus for each file descriptor. This place where this function will be called in a commonly used code path is for listing /proc/<pid>/fd. I did some small benchmarks and did not see any measurable performance differences. For ordinary users ls is likely to stat each of the directory entries and tid_fd_mode called from tid_fd_revalidae has always taken the task lock for each file descriptor. So this does not look like it will be a big change in practice.
At some point is will probably be worth changing put_files_struct to free files_struct after an rcu grace period so that task_lock won't be needed at all.
[1] https://lkml.kernel.org/r/[email protected]
v1: https://lkml.kernel.org/r/[email protected]
--- fs/file.c | 21 +++++++++++++++++++++ include/linux/fdtable.h | 1 + 2 files changed, 22 insertions(+)
fs/file.c +21 -0
@@ -926,6 +926,27 @@ struct file *task_lookup_fd_rcu(struct task_struct *task, unsigned int fd)return file; } +struct file *task_lookup_next_fd_rcu (struct task_struct *task,unsigned int *ret_fd) +{ +/* Must be called with rcu_read_lock held */ +struct files_struct *files; +unsigned int fd = *ret_fd; +struct file *file =NULL ; + +task_lock (task); + files = task->files; +if (files) { +for (; fd <files_fdtable (files)->max_fds; fd++) { + file =files_lookup_fd_rcu (files, fd); +if (file) +break ; + } + } +task_unlock (task); + *ret_fd = fd; +return file; +} +/* * Lightweight file lookup - no refcnt increment if fd table isn't shared. *
include/linux/fdtable.h +1 -0
@@ -111,6 +111,7 @@ static inline struct file *lookup_fd_rcu(unsigned int fd) }struct file *task_lookup_fd_rcu (struct task_struct *task,unsigned int fd); +struct file *task_lookup_next_fd_rcu (struct task_struct *task,unsigned int *fd);struct task_struct ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 122/770 proc/fd: In proc_readfd_common use task_lookup_next_fd_rcu
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
[ Upstream commit 5b17b61870e2f4b0a4fdc5c6039fbdb4ffb796df ]
When discussing[1] exec and posix file locks it was realized that none of the callers of get_files_struct fundamentally needed to call get_files_struct, and that by switching them to helper functions instead it will both simplify their code and remove unnecessary increments of files_struct.count. Those unnecessary increments can result in exec unnecessarily unsharing files_struct which breaking posix locks, and it can result in fget_light having to fallback to fget reducing system performance.
Using task_lookup_next_fd_rcu simplifies proc_readfd_common, by moving the checking for the maximum file descritor into the generic code, and by remvoing the need for capturing and releasing a reference on files_struct.
As task_lookup_fd_rcu may update the fd ctx->pos has been changed to be the fd +2 after task_lookup_fd_rcu returns.
[1] https://lkml.kernel.org/r/[email protected]
v1: https://lkml.kernel.org/r/[email protected]
--- fs/proc/fd.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-)
fs/proc/fd.c +5 -12
@@ -217,7 +217,6 @@ static int proc_readfd_common(struct file *file, struct dir_context *ctx, instantiate_t instantiate) {struct task_struct *p =get_proc_task (file_inode (file)); -struct files_struct *files;unsigned int fd;if (!p)
@@ -225,22 +224,18 @@ static int proc_readfd_common(struct file *file, struct dir_context *ctx,if (!dir_emit_dots (file, ctx)) goto out; - files =get_files_struct (p); -if (!files) - goto out;rcu_read_lock (); -for (fd = ctx->pos -2 ; - fd <files_fdtable (files)->max_fds; - fd++, ctx->pos++) { +for (fd = ctx->pos -2 ;; fd++) {struct file *f;struct fd_data data;char name[10 +1 ];unsigned int len; - f =files_lookup_fd_rcu (files, fd); + f =task_lookup_next_fd_rcu (p, &fd); + ctx->pos = fd +2LL ;if (!f) -continue ; +break ; data.mode = f->f_mode;rcu_read_unlock (); data.fd = fd;
@@ -249,13 +244,11 @@ static int proc_readfd_common(struct file *file, struct dir_context *ctx,if (!proc_fill_cache (file, ctx, name, len, instantiate, p, &data)) - goto out_fd_loop; + goto out;cond_resched ();rcu_read_lock (); }rcu_read_unlock (); -out_fd_loop: -put_files_struct (files); out:put_task_struct (p);return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 123/770 proc/fd: In fdinfo seq_show dont use get_files_struct
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
[ Upstream commit 775e0656b27210ae668e33af00bece858f44576f ]
When discussing[1] exec and posix file locks it was realized that none of the callers of get_files_struct fundamentally needed to call get_files_struct, and that by switching them to helper functions instead it will both simplify their code and remove unnecessary increments of files_struct.count. Those unnecessary increments can result in exec unnecessarily unsharing files_struct which breaking posix locks, and it can result in fget_light having to fallback to fget reducing system performance.
Instead hold task_lock for the duration that task->files needs to be stable in seq_show. The task_lock was already taken in get_files_struct, and so skipping get_files_struct performs less work overall, and avoids the problems with the files_struct reference count.
[1] https://lkml.kernel.org/r/[email protected]
v1: https://lkml.kernel.org/r/[email protected]
--- fs/proc/fd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
fs/proc/fd.c +5 -4
@@ -28,9 +28,8 @@ static int seq_show(struct seq_file *m, void *v)if (!task)return -ENOENT ; - files =get_files_struct (task); -put_task_struct (task); - +task_lock (task); + files = task->files;if (files) {unsigned int fd =proc_fd (m->private);
@@ -47,8 +46,9 @@ static int seq_show(struct seq_file *m, void *v) ret =0 ; }spin_unlock (&files->file_lock); -put_files_struct (files); } +task_unlock (task); +put_task_struct (task);if (ret)return ret;
@@ -57,6 +57,7 @@ static int seq_show(struct seq_file *m, void *v) (long long )file->f_pos, f_flags, real_mount(file->f_path.mnt)->mnt_id); +/* show_fd_locks() never deferences files so a stale value is safe */ show_fd_locks (m, file, files);if (seq_has_overflowed (m)) goto out;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 124/770 file: Merge __fd_install into fd_install
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
[ Upstream commit d74ba04d919ebe30bf47406819c18c6b50003d92 ]
The function __fd_install was added to support binder[1]. With binder fixed[2] there are no more users.
As fd_install just calls __fd_install with "files=current->files", merge them together by transforming the files parameter into a local variable initialized to current->files.
[1] f869e8a7f753 ("expose a low-level variant of fd_install() for binder")
[2] 44d8047f1d87 ("binder: use standard functions to allocate fds")
v1: https://lkml.kernel.org/r/[email protected]
--- fs/file.c | 25 ++++++------------------- include/linux/fdtable.h | 2 -- 2 files changed, 6 insertions(+), 21 deletions(-)
fs/file.c +6 -19
@@ -175,7 +175,7 @@ static int expand_fdtable(struct files_struct *files, unsigned int nr)spin_unlock (&files->file_lock); new_fdt =alloc_fdtable (nr); -/* make sure all __fd_install() have seen resize_in_progress +/* make sure all fd_install() have seen resize_in_progress * or have finished their rcu_read_lock_sched() section. */ if (atomic_read (&files->count) >1 )
@@ -198,7 +198,7 @@ static int expand_fdtable(struct files_struct *files, unsigned int nr)rcu_assign_pointer (files->fdt, new_fdt);if (cur_fdt != &files->fdtab)call_rcu (&cur_fdt->rcu, free_fdtable_rcu); -/* coupled with smp_rmb() in __fd_install() */ +/* coupled with smp_rmb() in fd_install() */ smp_wmb ();return 1 ; }
@@ -613,17 +613,13 @@ EXPORT_SYMBOL(put_unused_fd);* It should never happen - if we allow dup2() do it, _really_ bad things * will follow. * -* NOTE: __fd_install() variant is really, really low-level; don't -* use it unless you are forced to by truly lousy API shoved down -* your throat. 'files' *MUST* be either current->files or obtained -* by get_files_struct(current) done by whoever had given it to you, -* or really bad things will happen. Normally you want to use -* fd_install() instead. +* This consumes the "file" refcount, so callers should treat it +* as if they had called fput(file). */ -void __fd_install (struct files_struct *files,unsigned int fd, -struct file *file) +void fd_install (unsigned int fd,struct file *file) { +struct files_struct *files = current->files;struct fdtable *fdt;rcu_read_lock_sched ();
@@ -645,15 +641,6 @@ void __fd_install(struct files_struct *files, unsigned int fd,rcu_read_unlock_sched (); } -/* -* This consumes the "file" refcount, so callers should treat it -* as if they had called fput(file). -*/ -void fd_install (unsigned int fd,struct file *file) -{ -__fd_install (current->files, fd, file); -} -EXPORT_SYMBOL (fd_install);static struct file *pick_file (struct files_struct *files,unsigned fd)
include/linux/fdtable.h +0 -2
@@ -126,8 +126,6 @@ int iterate_fd(struct files_struct *, unsigned,extern int __alloc_fd (struct files_struct *files,unsigned start,unsigned end,unsigned flags); -extern void __fd_install (struct files_struct *files, -unsigned int fd,struct file *file);extern int __close_fd (struct files_struct *files,unsigned int fd);extern int __close_range (unsigned int fd,unsigned int max_fd,unsigned int flags);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 125/770 file: In f_dupfd read RLIMIT_NOFILE once.
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
Simplify the code, and remove the chance of races by reading RLIMIT_NOFILE only once in f_dupfd.
Pass the read value of RLIMIT_NOFILE into alloc_fd which is the other location the rlimit was read in f_dupfd. As f_dupfd is the only caller of alloc_fd this changing alloc_fd is trivially safe.
Further this causes alloc_fd to take all of the same arguments as __alloc_fd except for the files_struct argument.
v1: https://lkml.kernel.org/r/[email protected]
--- fs/file.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
fs/file.c +5 -4
@@ -567,9 +567,9 @@ int __alloc_fd(struct files_struct *files,return error; } -static int alloc_fd (unsigned start,unsigned flags) +static int alloc_fd (unsigned start,unsigned end,unsigned flags) { -return __alloc_fd (current->files, start,rlimit (RLIMIT_NOFILE ), flags); +return __alloc_fd (current->files, start, end, flags); }int __get_unused_fd_flags (unsigned flags,unsigned long nofile)
@@ -1235,10 +1235,11 @@ SYSCALL_DEFINE1(dup, unsigned int, fildes)int f_dupfd (unsigned int from,struct file *file,unsigned flags) { +unsigned long nofile =rlimit (RLIMIT_NOFILE );int err; -if (from >=rlimit (RLIMIT_NOFILE )) +if (from >= nofile)return -EINVAL ; - err =alloc_fd (from, flags); + err =alloc_fd (from, nofile, flags);if (err >=0 ) {get_file (file);fd_install (err, file);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 126/770 file: Merge __alloc_fd into alloc_fd
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
[ Upstream commit aa384d10f3d06d4b85597ff5df41551262220e16 ]
The function __alloc_fd was added to support binder[1]. With binder fixed[2] there are no more users.
As alloc_fd just calls __alloc_fd with "files=current->files", merge them together by transforming the files parameter into a local variable initialized to current->files.
[1] dcfadfa4ec5a ("new helper: __alloc_fd()")
[2] 44d8047f1d87 ("binder: use standard functions to allocate fds")
v1: https://lkml.kernel.org/r/[email protected]
--- fs/file.c | 11 +++-------- include/linux/fdtable.h | 2 -- 2 files changed, 3 insertions(+), 10 deletions(-)
fs/file.c +3 -8
@@ -509,9 +509,9 @@ static unsigned int find_next_fd(struct fdtable *fdt, unsigned int start)/* * allocate a file descriptor, mark it busy. */ -int __alloc_fd (struct files_struct *files, -unsigned start,unsigned end,unsigned flags) +static int alloc_fd (unsigned start,unsigned end,unsigned flags) { +struct files_struct *files = current->files;unsigned int fd;int error;struct fdtable *fdt;
@@ -567,14 +567,9 @@ int __alloc_fd(struct files_struct *files,return error; } -static int alloc_fd (unsigned start,unsigned end,unsigned flags) -{ -return __alloc_fd (current->files, start, end, flags); -} -int __get_unused_fd_flags (unsigned flags,unsigned long nofile) { -return __alloc_fd (current->files,0 , nofile, flags); +return alloc_fd (0 , nofile, flags); }int get_unused_fd_flags (unsigned flags)
include/linux/fdtable.h +0 -2
@@ -124,8 +124,6 @@ int iterate_fd(struct files_struct *, unsigned, int (*)(const void *, struct file *, unsigned), const void *); -extern int __alloc_fd (struct files_struct *files, -unsigned start,unsigned end,unsigned flags);extern int __close_fd (struct files_struct *files,unsigned int fd);extern int __close_range (unsigned int fd,unsigned int max_fd,unsigned int flags);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 127/770 file: Rename __close_fd to close_fd and remove the files parameter
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
[ Upstream commit 8760c909f54a82aaa6e76da19afe798a0c77c3c3 ]
The function __close_fd was added to support binder[1]. Now that binder has been fixed to no longer need __close_fd[2] all calls to __close_fd pass current->files.
Therefore transform the files parameter into a local variable initialized to current->files, and rename __close_fd to close_fd to reflect this change, and keep it in sync with the similar changes to __alloc_fd, and __fd_install.
This removes the need for callers to care about the extra care that needs to be take if anything except current->files is passed, by limiting the callers to only operation on current->files.
[1] 483ce1d4b8c3 ("take descriptor-related part of close() to file.c")
[2] 44d8047f1d87 ("binder: use standard functions to allocate fds")
v1: https://lkml.kernel.org/r/[email protected]
--- fs/file.c | 10 ++++------ fs/open.c | 2 +- include/linux/fdtable.h | 3 +-- include/linux/syscalls.h | 6 +++--- 4 files changed, 9 insertions(+), 12 deletions(-)
fs/file.c +4 -6
@@ -659,11 +659,9 @@ static struct file *pick_file(struct files_struct *files, unsigned fd)return file; } -/* -* The same warnings as for __alloc_fd()/__fd_install() apply here... -*/ -int __close_fd (struct files_struct *files,unsigned fd) +int close_fd (unsigned fd) { +struct files_struct *files = current->files;struct file *file; file =pick_file (files, fd);
@@ -672,7 +670,7 @@ int __close_fd(struct files_struct *files, unsigned fd)return filp_close (file, files); } -EXPORT_SYMBOL (__close_fd);/* for ksys_close() */ +EXPORT_SYMBOL (close_fd);/* for ksys_close() */ /** * __close_range() - Close all file descriptors in a given range.
@@ -1087,7 +1085,7 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags)struct files_struct *files = current->files;if (!file) -return __close_fd (files, fd); +return close_fd (fd);if (fd >=rlimit (RLIMIT_NOFILE ))return -EBADF ;
fs/open.c +1 -1
@@ -1310,7 +1310,7 @@ EXPORT_SYMBOL(filp_close);*/ SYSCALL_DEFINE1(close, unsigned int, fd) { -int retval =__close_fd (current->files, fd); +int retval =close_fd (fd);/* can't restart close syscall because file table entry was cleared */ if (unlikely(retval == -ERESTARTSYS ||
include/linux/fdtable.h +1 -2
@@ -124,8 +124,7 @@ int iterate_fd(struct files_struct *, unsigned, int (*)(const void *, struct file *, unsigned), const void *); -extern int __close_fd (struct files_struct *files, -unsigned int fd); +extern int close_fd (unsigned int fd);extern int __close_range (unsigned int fd,unsigned int max_fd,unsigned int flags);extern int close_fd_get_file (unsigned int fd,struct file **res); extern int unshare_fd(unsigned long unshare_flags, unsigned int max_fds,
include/linux/syscalls.h +3 -3
@@ -1320,16 +1320,16 @@ static inline long ksys_ftruncate(unsigned int fd, loff_t length)return do_sys_ftruncate (fd, length,1 ); } -extern int __close_fd (struct files_struct *files,unsigned int fd); +extern int close_fd (unsigned int fd);/* * In contrast to sys_close(), this stub does not check whether the syscall * should or should not be restarted, but returns the raw error codes from -* __close_fd(). +* close_fd(). */ static inline int ksys_close (unsigned int fd) { -return __close_fd (current->files, fd); +return close_fd (fd); }extern long do_sys_truncate (const char __user *pathname,loff_t length);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 128/770 file: Replace ksys_close with close_fd
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric W. Biederman <[email protected]>
[ Upstream commit 1572bfdf21d4d50e51941498ffe0b56c2289f783 ]
Now that ksys_close is exactly identical to close_fd replace the one caller of ksys_close with close_fd.
[1] https://lkml.kernel.org/r/[email protected]
--- fs/autofs/dev-ioctl.c | 5 +++-- include/linux/syscalls.h | 12 ------------ 2 files changed, 3 insertions(+), 14 deletions(-)
fs/autofs/dev-ioctl.c +3 -2
@@ -4,9 +4,10 @@* Copyright 2008 Ian Kent <[email protected]> */ +#include <linux/module.h> #include <linux/miscdevice.h> #include <linux/compat.h> -#include <linux/syscalls.h> +#include <linux/fdtable.h> #include <linux/magic.h> #include <linux/nospec.h>
@@ -289,7 +290,7 @@ static int autofs_dev_ioctl_closemount(struct file *fp,struct autofs_sb_info *sbi, struct autofs_dev_ioctl *param) { - return ksys_close(param->ioctlfd); + return close_fd(param->ioctlfd); }/*
include/linux/syscalls.h +0 -12
@@ -1320,18 +1320,6 @@ static inline long ksys_ftruncate(unsigned int fd, loff_t length)return do_sys_ftruncate (fd, length,1 ); } -extern int close_fd (unsigned int fd); - -/* -* In contrast to sys_close(), this stub does not check whether the syscall -* should or should not be restarted, but returns the raw error codes from -* close_fd(). -*/ -static inline int ksys_close (unsigned int fd) -{ -return close_fd (fd); -} -extern long do_sys_truncate (const char __user *pathname,loff_t length);static inline long ksys_truncate (const char __user *pathname,loff_t length)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 129/770 inotify: Increase default inotify.max_user_watches limit to 1048576
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <[email protected]>
[ Upstream commit 92890123749bafc317bbfacbe0a62ce08d78efb7 ]
The default value of inotify.max_user_watches sysctl parameter was set to 8192 since the introduction of the inotify feature in 2005 by commit 0eeca28300df ("[PATCH] inotify"). Today this value is just too small for many modern usage. As a result, users have to explicitly set it to a larger value to make it work.
After some searching around the web, these are the inotify.max_user_watches values used by some projects:
- vscode: 524288
- dropbox support: 100000
- users on stackexchange: 12228
- lsyncd user: 2000000
- code42 support: 1048576
- monodevelop: 16384
- tectonic: 524288
- openshift origin: 65536
Each watch point adds an inotify_inode_mark structure to an inode to be watched. It also pins the watched inode.
Modeled after the epoll.max_user_watches behavior to adjust the default value according to the amount of addressable memory available, make inotify.max_user_watches behave in a similar way to make it use no more than 1% of addressable memory within the range [8192, 1048576].
We estimate the amount of memory used by inotify mark to size of inotify_inode_mark plus two times the size of struct inode (we double the inode size to cover the additional filesystem private inode part). That means that a 64-bit system with 128GB or more memory will likely have the maximum value of 1048576 for inotify.max_user_watches. This default should be big enough for most use cases.
--- fs/notify/inotify/inotify_user.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
fs/notify/inotify/inotify_user.c +22 -1
@@ -37,6 +37,15 @@#include <asm/ioctls.h> +/* +* An inotify watch requires allocating an inotify_inode_mark structure as +* well as pinning the watched inode. Doubling the size of a VFS inode +* should be more than enough to cover the additional filesystem inode +* size increase. +*/ +#define INOTIFY_WATCH_COST (sizeof(struct inotify_inode_mark) + \ + 2 * sizeof(struct inode)) +/* configurable via /proc/sys/fs/inotify/ */ static int inotify_max_queued_events__read_mostly ;
@@ -797,6 +806,18 @@ SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd)*/ static int __init inotify_user_setup (void ) { +unsigned long watches_max; +struct sysinfo si; + +si_meminfo (&si); +/* +* Allow up to 1% of addressable memory to be allocated for inotify +* watches (per user) limited to the range [8192, 1048576]. +*/ + watches_max = (((si.totalram - si.totalhigh) /100 ) <<PAGE_SHIFT ) / +INOTIFY_WATCH_COST ; + watches_max =clamp (watches_max,8192UL ,1048576UL ); +BUILD_BUG_ON (IN_ACCESS !=FS_ACCESS );BUILD_BUG_ON (IN_MODIFY !=FS_MODIFY );BUILD_BUG_ON (IN_ATTRIB !=FS_ATTRIB );
@@ -823,7 +844,7 @@ static int __init inotify_user_setup(void) inotify_max_queued_events =16384 ; init_user_ns.ucount_max[UCOUNT_INOTIFY_INSTANCES ] =128 ; - init_user_ns.ucount_max[UCOUNT_INOTIFY_WATCHES ] =8192 ; + init_user_ns.ucount_max[UCOUNT_INOTIFY_WATCHES ] = watches_max;return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 130/770 fs/lockd: convert comma to semicolon
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zheng Yongjun <[email protected]>
[ Upstream commit 3316fb80a0b4c1fef03a3eb1a7f0651e2133c429 ]
Replace a comma between expression statements by a semicolon.
--- fs/lockd/host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/lockd/host.c +1 -1
@@ -163,7 +163,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni, host->h_nsmhandle = nsm; host->h_addrbuf = nsm->sm_addrbuf; host->net = ni->net; - host->h_cred =get_cred (ni->cred), + host->h_cred =get_cred (ni->cred);strlcpy (host->nodename,utsname ()->nodename,sizeof (host->nodename)); out:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 131/770 NFSD: Fix sparse warning in nfssvc.c
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit d6c9e4368cc6a61bf25c9c72437ced509c854563 ]
fs/nfsd/nfssvc.c:36:6: warning: symbol 'inter_copy_offload_enable' was not declared. Should it be static?
The parameter was added by commit ce0887ac96d3 ("NFSD add nfs4 inter ssc to nfsd4_copy"). Relocate it into the source file that uses it, and make it static. This approach is similar to the nfs4_disable_idmapping, cltrack_prog, and cltrack_legacy_disable module parameters.
--- fs/nfsd/nfs4proc.c | 5 +++++ fs/nfsd/nfssvc.c | 6 ------ fs/nfsd/xdr4.h | 1 - 3 files changed, 5 insertions(+), 7 deletions(-)
fs/nfsd/nfs4proc.c +5 -0
@@ -50,6 +50,11 @@#include "pnfs.h" #include "trace.h" +static bool inter_copy_offload_enable; +module_param (inter_copy_offload_enable, bool,0644 ); +MODULE_PARM_DESC (inter_copy_offload_enable, +"Enable inter server to server copy offload. Default: false" ); +#ifdef CONFIG_NFSD_V4_SECURITY_LABEL #include <linux/security.h>
fs/nfsd/nfssvc.c +0 -6
@@ -33,12 +33,6 @@#define NFSDDBG_FACILITY NFSDDBG_SVC -bool inter_copy_offload_enable; -EXPORT_SYMBOL_GPL (inter_copy_offload_enable); -module_param (inter_copy_offload_enable, bool,0644 ); -MODULE_PARM_DESC (inter_copy_offload_enable, -"Enable inter server to server copy offload. Default: false" ); -extern struct svc_program nfsd_program;static int nfsd (void *vrqstp);#if defined(CONFIG_NFSD_V2_ACL ) || defined(CONFIG_NFSD_V3_ACL )
fs/nfsd/xdr4.h +0 -1
@@ -568,7 +568,6 @@ struct nfsd4_copy {struct nfs_fh c_fh;nfs4_stateid stateid; }; -extern bool inter_copy_offload_enable;struct nfsd4_seek {/* request */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 132/770 NFSD: Restore NFSv4 decodings SAVEMEM functionality
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 7b723008f9c95624c848fad661c01b06e47b20da ]
While converting the NFSv4 decoder to use xdr_stream-based XDR processing, I removed the old SAVEMEM() macro. This macro wrapped a bit of logic that avoided a memory allocation by recognizing when the decoded item resides in a linear section of the Receive buffer. In that case, it returned a pointer into that buffer instead of allocating a bounce buffer.
The bounce buffer is necessary only when xdr_inline_decode() has placed the decoded item in the xdr_stream's scratch buffer, which disappears the next time xdr_inline_decode() is called with that xdr_stream. That happens only if the data item crosses a page boundary in the receive buffer, an exceedingly rare occurrence.
Allocating a bounce buffer every time results in a minor performance regression that was introduced by the recent NFSv4 decoder overhaul. Let's restore the previous behavior. On average, it saves about 1.5 kmalloc() calls per COMPOUND.
--- fs/nfsd/nfs4xdr.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-)
fs/nfsd/nfs4xdr.c +26 -16
@@ -147,6 +147,25 @@ svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)return p; } +static void * +svcxdr_savemem (struct nfsd4_compoundargs *argp,__be32 *p,u32 len) +{ +__be32 *tmp; + +/* +* The location of the decoded data item is stable, +* so @p is OK to use. This is the common case. +*/ +if (p != argp->xdr->scratch.iov_base) +return p; + + tmp =svcxdr_tmpalloc (argp, len); +if (!tmp) +return NULL ; +memcpy (tmp, p, len); +return tmp; +} +/* * NFSv4 basic data type decoders */
@@ -183,11 +202,10 @@ nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o) p =xdr_inline_decode (argp->xdr, len);if (!p)return nfserr_bad_xdr; - o->data =svcxdr_tmpalloc (argp, len); + o->data =svcxdr_savemem (argp, p, len);if (!o->data)return nfserr_jukebox; o->len = len; -memcpy (o->data, p, len);return nfs_ok; }
@@ -205,10 +223,9 @@ nfsd4_decode_component4(struct nfsd4_compoundargs *argp, char **namp, u32 *lenp) status =check_filename ((char *)p, *lenp);if (status)return status; - *namp =svcxdr_tmpalloc (argp, *lenp); + *namp =svcxdr_savemem (argp, p, *lenp);if (!*namp)return nfserr_jukebox; -memcpy (*namp, p, *lenp);return nfs_ok; }
@@ -1200,10 +1217,9 @@ nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) p =xdr_inline_decode (argp->xdr, putfh->pf_fhlen);if (!p)return nfserr_bad_xdr; - putfh->pf_fhval =svcxdr_tmpalloc (argp, putfh->pf_fhlen); + putfh->pf_fhval =svcxdr_savemem (argp, p, putfh->pf_fhlen);if (!putfh->pf_fhval)return nfserr_jukebox; -memcpy (putfh->pf_fhval, p, putfh->pf_fhlen);return nfs_ok; }
@@ -1318,24 +1334,20 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient p =xdr_inline_decode (argp->xdr, setclientid->se_callback_netid_len);if (!p)return nfserr_bad_xdr; - setclientid->se_callback_netid_val =svcxdr_tmpalloc (argp, + setclientid->se_callback_netid_val =svcxdr_savemem (argp, p, setclientid->se_callback_netid_len);if (!setclientid->se_callback_netid_val)return nfserr_jukebox; -memcpy (setclientid->se_callback_netid_val, p, - setclientid->se_callback_netid_len);if (xdr_stream_decode_u32 (argp->xdr, &setclientid->se_callback_addr_len) <0 )return nfserr_bad_xdr; p =xdr_inline_decode (argp->xdr, setclientid->se_callback_addr_len);if (!p)return nfserr_bad_xdr; - setclientid->se_callback_addr_val =svcxdr_tmpalloc (argp, + setclientid->se_callback_addr_val =svcxdr_savemem (argp, p, setclientid->se_callback_addr_len);if (!setclientid->se_callback_addr_val)return nfserr_jukebox; -memcpy (setclientid->se_callback_addr_val, p, - setclientid->se_callback_addr_len);if (xdr_stream_decode_u32 (argp->xdr, &setclientid->se_callback_ident) <0 )return nfserr_bad_xdr;
@@ -1375,10 +1387,9 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify p =xdr_inline_decode (argp->xdr, verify->ve_attrlen);if (!p)return nfserr_bad_xdr; - verify->ve_attrval =svcxdr_tmpalloc (argp, verify->ve_attrlen); + verify->ve_attrval =svcxdr_savemem (argp, p, verify->ve_attrlen);if (!verify->ve_attrval)return nfserr_jukebox; -memcpy (verify->ve_attrval, p, verify->ve_attrlen);return nfs_ok; }
@@ -2333,10 +2344,9 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) p =xdr_inline_decode (argp->xdr, argp->taglen);if (!p)return 0 ; - argp->tag =svcxdr_tmpalloc (argp, argp->taglen); + argp->tag =svcxdr_savemem (argp, p, argp->taglen);if (!argp->tag)return 0 ; -memcpy (argp->tag, p, argp->taglen); max_reply +=xdr_align_size (argp->taglen); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 133/770 SUNRPC: Make trace_svc_process() display the RPC procedure symbolically
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 2289e87b5951f97783f07fc895e6c5e804b53668 ]
The next few patches will employ these strings to help make server- side trace logs more human-readable. A similar technique is already in use in kernel RPC client code.
--- fs/lockd/svc4proc.c | 24 ++++++++++++++++++++++++ fs/lockd/svcproc.c | 24 ++++++++++++++++++++++++ fs/nfs/callback_xdr.c | 2 ++ fs/nfsd/nfs2acl.c | 5 +++++ fs/nfsd/nfs3acl.c | 3 +++ fs/nfsd/nfs3proc.c | 22 ++++++++++++++++++++++ fs/nfsd/nfs4proc.c | 2 ++ fs/nfsd/nfsproc.c | 18 ++++++++++++++++++ include/linux/sunrpc/svc.h | 1 + 9 files changed, 101 insertions(+)
fs/lockd/svc4proc.c +24 -0
@@ -512,6 +512,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_void), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "NULL", }, [NLMPROC_TEST] = { .pc_func = nlm4svc_proc_test,
@@ -520,6 +521,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St+2+No+Rg, + .pc_name = "TEST", }, [NLMPROC_LOCK] = { .pc_func = nlm4svc_proc_lock,
@@ -528,6 +530,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St, + .pc_name = "LOCK", }, [NLMPROC_CANCEL] = { .pc_func = nlm4svc_proc_cancel,
@@ -536,6 +539,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St, + .pc_name = "CANCEL", }, [NLMPROC_UNLOCK] = { .pc_func = nlm4svc_proc_unlock,
@@ -544,6 +548,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St, + .pc_name = "UNLOCK", }, [NLMPROC_GRANTED] = { .pc_func = nlm4svc_proc_granted,
@@ -552,6 +557,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St, + .pc_name = "GRANTED", }, [NLMPROC_TEST_MSG] = { .pc_func = nlm4svc_proc_test_msg,
@@ -560,6 +566,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "TEST_MSG", }, [NLMPROC_LOCK_MSG] = { .pc_func = nlm4svc_proc_lock_msg,
@@ -568,6 +575,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "LOCK_MSG", }, [NLMPROC_CANCEL_MSG] = { .pc_func = nlm4svc_proc_cancel_msg,
@@ -576,6 +584,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "CANCEL_MSG", }, [NLMPROC_UNLOCK_MSG] = { .pc_func = nlm4svc_proc_unlock_msg,
@@ -584,6 +593,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "UNLOCK_MSG", }, [NLMPROC_GRANTED_MSG] = { .pc_func = nlm4svc_proc_granted_msg,
@@ -592,6 +602,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "GRANTED_MSG", }, [NLMPROC_TEST_RES] = { .pc_func = nlm4svc_proc_null,
@@ -600,6 +611,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_res), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "TEST_RES", }, [NLMPROC_LOCK_RES] = { .pc_func = nlm4svc_proc_null,
@@ -608,6 +620,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_res), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "LOCK_RES", }, [NLMPROC_CANCEL_RES] = { .pc_func = nlm4svc_proc_null,
@@ -616,6 +629,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_res), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "CANCEL_RES", }, [NLMPROC_UNLOCK_RES] = { .pc_func = nlm4svc_proc_null,
@@ -624,6 +638,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_res), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "UNLOCK_RES", }, [NLMPROC_GRANTED_RES] = { .pc_func = nlm4svc_proc_granted_res,
@@ -632,6 +647,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_res), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "GRANTED_RES", }, [NLMPROC_NSM_NOTIFY] = { .pc_func = nlm4svc_proc_sm_notify,
@@ -640,6 +656,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_reboot), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "SM_NOTIFY", }, [17] = { .pc_func = nlm4svc_proc_unused,
@@ -648,6 +665,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_void), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = 0, + .pc_name = "UNUSED", }, [18] = { .pc_func = nlm4svc_proc_unused,
@@ -656,6 +674,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_void), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = 0, + .pc_name = "UNUSED", }, [19] = { .pc_func = nlm4svc_proc_unused,
@@ -664,6 +683,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_void), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = 0, + .pc_name = "UNUSED", }, [NLMPROC_SHARE] = { .pc_func = nlm4svc_proc_share,
@@ -672,6 +692,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St+1, + .pc_name = "SHARE", }, [NLMPROC_UNSHARE] = { .pc_func = nlm4svc_proc_unshare,
@@ -680,6 +701,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St+1, + .pc_name = "UNSHARE", }, [NLMPROC_NM_LOCK] = { .pc_func = nlm4svc_proc_nm_lock,
@@ -688,6 +710,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St, + .pc_name = "NM_LOCK", }, [NLMPROC_FREE_ALL] = { .pc_func = nlm4svc_proc_free_all,
@@ -696,5 +719,6 @@ const struct svc_procedure nlmsvc_procedures4[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "FREE_ALL", }, };
fs/lockd/svcproc.c +24 -0
@@ -554,6 +554,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_void), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "NULL", }, [NLMPROC_TEST] = { .pc_func = nlmsvc_proc_test,
@@ -562,6 +563,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St+2+No+Rg, + .pc_name = "TEST", }, [NLMPROC_LOCK] = { .pc_func = nlmsvc_proc_lock,
@@ -570,6 +572,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St, + .pc_name = "LOCK", }, [NLMPROC_CANCEL] = { .pc_func = nlmsvc_proc_cancel,
@@ -578,6 +581,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St, + .pc_name = "CANCEL", }, [NLMPROC_UNLOCK] = { .pc_func = nlmsvc_proc_unlock,
@@ -586,6 +590,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St, + .pc_name = "UNLOCK", }, [NLMPROC_GRANTED] = { .pc_func = nlmsvc_proc_granted,
@@ -594,6 +599,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St, + .pc_name = "GRANTED", }, [NLMPROC_TEST_MSG] = { .pc_func = nlmsvc_proc_test_msg,
@@ -602,6 +608,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "TEST_MSG", }, [NLMPROC_LOCK_MSG] = { .pc_func = nlmsvc_proc_lock_msg,
@@ -610,6 +617,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "LOCK_MSG", }, [NLMPROC_CANCEL_MSG] = { .pc_func = nlmsvc_proc_cancel_msg,
@@ -618,6 +626,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "CANCEL_MSG", }, [NLMPROC_UNLOCK_MSG] = { .pc_func = nlmsvc_proc_unlock_msg,
@@ -626,6 +635,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "UNLOCK_MSG", }, [NLMPROC_GRANTED_MSG] = { .pc_func = nlmsvc_proc_granted_msg,
@@ -634,6 +644,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "GRANTED_MSG", }, [NLMPROC_TEST_RES] = { .pc_func = nlmsvc_proc_null,
@@ -642,6 +653,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_res), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "TEST_RES", }, [NLMPROC_LOCK_RES] = { .pc_func = nlmsvc_proc_null,
@@ -650,6 +662,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_res), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "LOCK_RES", }, [NLMPROC_CANCEL_RES] = { .pc_func = nlmsvc_proc_null,
@@ -658,6 +671,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_res), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "CANCEL_RES", }, [NLMPROC_UNLOCK_RES] = { .pc_func = nlmsvc_proc_null,
@@ -666,6 +680,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_res), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "UNLOCK_RES", }, [NLMPROC_GRANTED_RES] = { .pc_func = nlmsvc_proc_granted_res,
@@ -674,6 +689,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_res), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "GRANTED_RES", }, [NLMPROC_NSM_NOTIFY] = { .pc_func = nlmsvc_proc_sm_notify,
@@ -682,6 +698,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_reboot), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "SM_NOTIFY", }, [17] = { .pc_func = nlmsvc_proc_unused,
@@ -690,6 +707,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_void), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "UNUSED", }, [18] = { .pc_func = nlmsvc_proc_unused,
@@ -698,6 +716,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_void), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "UNUSED", }, [19] = { .pc_func = nlmsvc_proc_unused,
@@ -706,6 +725,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_void), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = St, + .pc_name = "UNUSED", }, [NLMPROC_SHARE] = { .pc_func = nlmsvc_proc_share,
@@ -714,6 +734,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St+1, + .pc_name = "SHARE", }, [NLMPROC_UNSHARE] = { .pc_func = nlmsvc_proc_unshare,
@@ -722,6 +743,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St+1, + .pc_name = "UNSHARE", }, [NLMPROC_NM_LOCK] = { .pc_func = nlmsvc_proc_nm_lock,
@@ -730,6 +752,7 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_res), .pc_xdrressize = Ck+St, + .pc_name = "NM_LOCK", }, [NLMPROC_FREE_ALL] = { .pc_func = nlmsvc_proc_free_all,
@@ -738,5 +761,6 @@ const struct svc_procedure nlmsvc_procedures[24] = { .pc_argsize = sizeof(struct nlm_args), .pc_ressize = sizeof(struct nlm_void), .pc_xdrressize = 0, + .pc_name = "FREE_ALL", }, };
fs/nfs/callback_xdr.c +2 -0
@@ -1056,6 +1056,7 @@ static const struct svc_procedure nfs4_callback_procedures1[] = { .pc_decode = nfs4_decode_void, .pc_encode = nfs4_encode_void, .pc_xdrressize = 1, + .pc_name = "NULL", }, [CB_COMPOUND] = { .pc_func = nfs4_callback_compound,
@@ -1063,6 +1064,7 @@ static const struct svc_procedure nfs4_callback_procedures1[] = { .pc_argsize = 256, .pc_ressize = 256, .pc_xdrressize = NFS4_CALLBACK_BUFSIZE, + .pc_name = "COMPOUND", } };
fs/nfsd/nfs2acl.c +5 -0
@@ -371,6 +371,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = { .pc_ressize = sizeof(struct nfsd_voidres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST, + .pc_name = "NULL", }, [ACLPROC2_GETACL] = { .pc_func = nfsacld_proc_getacl,
@@ -381,6 +382,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = { .pc_ressize = sizeof(struct nfsd3_getaclres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+1+2*(1+ACL), + .pc_name = "GETACL", }, [ACLPROC2_SETACL] = { .pc_func = nfsacld_proc_setacl,
@@ -391,6 +393,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = { .pc_ressize = sizeof(struct nfsd_attrstat), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+AT, + .pc_name = "SETACL", }, [ACLPROC2_GETATTR] = { .pc_func = nfsacld_proc_getattr,
@@ -401,6 +404,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = { .pc_ressize = sizeof(struct nfsd_attrstat), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+AT, + .pc_name = "GETATTR", }, [ACLPROC2_ACCESS] = { .pc_func = nfsacld_proc_access,
@@ -411,6 +415,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = { .pc_ressize = sizeof(struct nfsd3_accessres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+AT+1, + .pc_name = "SETATTR", }, };
fs/nfsd/nfs3acl.c +3 -0
@@ -251,6 +251,7 @@ static const struct svc_procedure nfsd_acl_procedures3[3] = { .pc_ressize = sizeof(struct nfsd_voidres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST, + .pc_name = "NULL", }, [ACLPROC3_GETACL] = { .pc_func = nfsd3_proc_getacl,
@@ -261,6 +262,7 @@ static const struct svc_procedure nfsd_acl_procedures3[3] = { .pc_ressize = sizeof(struct nfsd3_getaclres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+1+2*(1+ACL), + .pc_name = "GETACL", }, [ACLPROC3_SETACL] = { .pc_func = nfsd3_proc_setacl,
@@ -271,6 +273,7 @@ static const struct svc_procedure nfsd_acl_procedures3[3] = { .pc_ressize = sizeof(struct nfsd3_attrstat), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT, + .pc_name = "SETACL", }, };
fs/nfsd/nfs3proc.c +22 -0
@@ -713,6 +713,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd_voidres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST, + .pc_name = "NULL", }, [NFS3PROC_GETATTR] = { .pc_func = nfsd3_proc_getattr,
@@ -723,6 +724,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_attrstatres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+AT, + .pc_name = "GETATTR", }, [NFS3PROC_SETATTR] = { .pc_func = nfsd3_proc_setattr,
@@ -733,6 +735,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_wccstatres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+WC, + .pc_name = "SETATTR", }, [NFS3PROC_LOOKUP] = { .pc_func = nfsd3_proc_lookup,
@@ -743,6 +746,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_diropres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+FH+pAT+pAT, + .pc_name = "LOOKUP", }, [NFS3PROC_ACCESS] = { .pc_func = nfsd3_proc_access,
@@ -753,6 +757,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_accessres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+1, + .pc_name = "ACCESS", }, [NFS3PROC_READLINK] = { .pc_func = nfsd3_proc_readlink,
@@ -763,6 +768,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_readlinkres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+1+NFS3_MAXPATHLEN/4, + .pc_name = "READLINK", }, [NFS3PROC_READ] = { .pc_func = nfsd3_proc_read,
@@ -773,6 +779,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_readres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+4+NFSSVC_MAXBLKSIZE/4, + .pc_name = "READ", }, [NFS3PROC_WRITE] = { .pc_func = nfsd3_proc_write,
@@ -783,6 +790,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_writeres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+WC+4, + .pc_name = "WRITE", }, [NFS3PROC_CREATE] = { .pc_func = nfsd3_proc_create,
@@ -793,6 +801,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_createres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+(1+FH+pAT)+WC, + .pc_name = "CREATE", }, [NFS3PROC_MKDIR] = { .pc_func = nfsd3_proc_mkdir,
@@ -803,6 +812,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_createres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+(1+FH+pAT)+WC, + .pc_name = "MKDIR", }, [NFS3PROC_SYMLINK] = { .pc_func = nfsd3_proc_symlink,
@@ -813,6 +823,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_createres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+(1+FH+pAT)+WC, + .pc_name = "SYMLINK", }, [NFS3PROC_MKNOD] = { .pc_func = nfsd3_proc_mknod,
@@ -823,6 +834,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_createres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+(1+FH+pAT)+WC, + .pc_name = "MKNOD", }, [NFS3PROC_REMOVE] = { .pc_func = nfsd3_proc_remove,
@@ -833,6 +845,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_wccstatres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+WC, + .pc_name = "REMOVE", }, [NFS3PROC_RMDIR] = { .pc_func = nfsd3_proc_rmdir,
@@ -843,6 +856,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_wccstatres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+WC, + .pc_name = "RMDIR", }, [NFS3PROC_RENAME] = { .pc_func = nfsd3_proc_rename,
@@ -853,6 +867,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_renameres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+WC+WC, + .pc_name = "RENAME", }, [NFS3PROC_LINK] = { .pc_func = nfsd3_proc_link,
@@ -863,6 +878,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_linkres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+pAT+WC, + .pc_name = "LINK", }, [NFS3PROC_READDIR] = { .pc_func = nfsd3_proc_readdir,
@@ -872,6 +888,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_argsize = sizeof(struct nfsd3_readdirargs), .pc_ressize = sizeof(struct nfsd3_readdirres), .pc_cachetype = RC_NOCACHE, + .pc_name = "READDIR", }, [NFS3PROC_READDIRPLUS] = { .pc_func = nfsd3_proc_readdirplus,
@@ -881,6 +898,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_argsize = sizeof(struct nfsd3_readdirplusargs), .pc_ressize = sizeof(struct nfsd3_readdirres), .pc_cachetype = RC_NOCACHE, + .pc_name = "READDIRPLUS", }, [NFS3PROC_FSSTAT] = { .pc_func = nfsd3_proc_fsstat,
@@ -890,6 +908,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_fsstatres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+2*6+1, + .pc_name = "FSSTAT", }, [NFS3PROC_FSINFO] = { .pc_func = nfsd3_proc_fsinfo,
@@ -899,6 +918,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_fsinfores), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+12, + .pc_name = "FSINFO", }, [NFS3PROC_PATHCONF] = { .pc_func = nfsd3_proc_pathconf,
@@ -908,6 +928,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_pathconfres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+6, + .pc_name = "PATHCONF", }, [NFS3PROC_COMMIT] = { .pc_func = nfsd3_proc_commit,
@@ -918,6 +939,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_ressize = sizeof(struct nfsd3_commitres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+WC+2, + .pc_name = "COMMIT", }, };
fs/nfsd/nfs4proc.c +2 -0
@@ -3299,6 +3299,7 @@ static const struct svc_procedure nfsd_procedures4[2] = { .pc_ressize = sizeof(struct nfsd_voidres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = 1, + .pc_name = "NULL", }, [NFSPROC4_COMPOUND] = { .pc_func = nfsd4_proc_compound,
@@ -3309,6 +3310,7 @@ static const struct svc_procedure nfsd_procedures4[2] = { .pc_release = nfsd4_release_compoundargs, .pc_cachetype = RC_NOCACHE, .pc_xdrressize = NFSD_BUFSIZE/4, + .pc_name = "COMPOUND", }, };
fs/nfsd/nfsproc.c +18 -0
@@ -623,6 +623,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_voidres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = 0, + .pc_name = "NULL", }, [NFSPROC_GETATTR] = { .pc_func = nfsd_proc_getattr,
@@ -633,6 +634,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_attrstat), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+AT, + .pc_name = "GETATTR", }, [NFSPROC_SETATTR] = { .pc_func = nfsd_proc_setattr,
@@ -643,6 +645,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_attrstat), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+AT, + .pc_name = "SETATTR", }, [NFSPROC_ROOT] = { .pc_func = nfsd_proc_root,
@@ -652,6 +655,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_voidres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = 0, + .pc_name = "ROOT", }, [NFSPROC_LOOKUP] = { .pc_func = nfsd_proc_lookup,
@@ -662,6 +666,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_diropres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+FH+AT, + .pc_name = "LOOKUP", }, [NFSPROC_READLINK] = { .pc_func = nfsd_proc_readlink,
@@ -671,6 +676,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_readlinkres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+1+NFS_MAXPATHLEN/4, + .pc_name = "READLINK", }, [NFSPROC_READ] = { .pc_func = nfsd_proc_read,
@@ -681,6 +687,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_readres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+AT+1+NFSSVC_MAXBLKSIZE_V2/4, + .pc_name = "READ", }, [NFSPROC_WRITECACHE] = { .pc_func = nfsd_proc_writecache,
@@ -690,6 +697,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_voidres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = 0, + .pc_name = "WRITECACHE", }, [NFSPROC_WRITE] = { .pc_func = nfsd_proc_write,
@@ -700,6 +708,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_attrstat), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+AT, + .pc_name = "WRITE", }, [NFSPROC_CREATE] = { .pc_func = nfsd_proc_create,
@@ -710,6 +719,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_diropres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+FH+AT, + .pc_name = "CREATE", }, [NFSPROC_REMOVE] = { .pc_func = nfsd_proc_remove,
@@ -719,6 +729,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_stat), .pc_cachetype = RC_REPLSTAT, .pc_xdrressize = ST, + .pc_name = "REMOVE", }, [NFSPROC_RENAME] = { .pc_func = nfsd_proc_rename,
@@ -728,6 +739,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_stat), .pc_cachetype = RC_REPLSTAT, .pc_xdrressize = ST, + .pc_name = "RENAME", }, [NFSPROC_LINK] = { .pc_func = nfsd_proc_link,
@@ -737,6 +749,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_stat), .pc_cachetype = RC_REPLSTAT, .pc_xdrressize = ST, + .pc_name = "LINK", }, [NFSPROC_SYMLINK] = { .pc_func = nfsd_proc_symlink,
@@ -746,6 +759,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_stat), .pc_cachetype = RC_REPLSTAT, .pc_xdrressize = ST, + .pc_name = "SYMLINK", }, [NFSPROC_MKDIR] = { .pc_func = nfsd_proc_mkdir,
@@ -756,6 +770,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_diropres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+FH+AT, + .pc_name = "MKDIR", }, [NFSPROC_RMDIR] = { .pc_func = nfsd_proc_rmdir,
@@ -765,6 +780,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_stat), .pc_cachetype = RC_REPLSTAT, .pc_xdrressize = ST, + .pc_name = "RMDIR", }, [NFSPROC_READDIR] = { .pc_func = nfsd_proc_readdir,
@@ -773,6 +789,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_argsize = sizeof(struct nfsd_readdirargs), .pc_ressize = sizeof(struct nfsd_readdirres), .pc_cachetype = RC_NOCACHE, + .pc_name = "READDIR", }, [NFSPROC_STATFS] = { .pc_func = nfsd_proc_statfs,
@@ -782,6 +799,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { .pc_ressize = sizeof(struct nfsd_statfsres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+5, + .pc_name = "STATFS", }, };
include/linux/sunrpc/svc.h +1 -0
@@ -463,6 +463,7 @@ struct svc_procedure {unsigned int pc_ressize;/* result struct size */ unsigned int pc_cachetype;/* cache info (NFS) */ unsigned int pc_xdrressize;/* maximum size of XDR reply */ +const char * pc_name;/* for display */ };/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 134/770 SUNRPC: Display RPC procedure names instead of proc numbers
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 89ff87494c6e4b32ea7960d0c644efdbb2fe6ef5 ]
Make the sunrpc trace subsystem trace events easier to use.
--- include/trace/events/sunrpc.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
include/trace/events/sunrpc.h +11 -4
@@ -1578,6 +1578,7 @@ TRACE_EVENT(svc_process, __field(u32, vers) __field(u32, proc) __string(service, name) + __string(procedure, rqst->rq_procinfo->pc_name)__string (addr, rqst->rq_xprt ? rqst->rq_xprt->xpt_remotebuf :"(null)" ) ),
@@ -1587,13 +1588,16 @@ TRACE_EVENT(svc_process, __entry->vers = rqst->rq_vers; __entry->proc = rqst->rq_proc;__assign_str (service, name); +__assign_str (procedure, rqst->rq_procinfo->pc_name);__assign_str (addr, rqst->rq_xprt ? rqst->rq_xprt->xpt_remotebuf :"(null)" ); ), -TP_printk ("addr=%s xid=0x%08x service=%s vers=%u proc=%u" , +TP_printk ("addr=%s xid=0x%08x service=%s vers=%u proc=%s" ,__get_str (addr), __entry->xid, -__get_str (service), __entry->vers, __entry->proc) +__get_str (service), __entry->vers, +__get_str (procedure) + ) ); DECLARE_EVENT_CLASS(svc_rqst_event,
@@ -1849,6 +1853,7 @@ TRACE_EVENT(svc_stats_latency,TP_STRUCT__entry (__field (u32 ,xid ) __field(unsigned long, execute) + __string(procedure, rqst->rq_procinfo->pc_name) __string(addr, rqst->rq_xprt->xpt_remotebuf) ),
@@ -1856,11 +1861,13 @@ TRACE_EVENT(svc_stats_latency, __entry->xid =be32_to_cpu (rqst->rq_xid); __entry->execute =ktime_to_us (ktime_sub (ktime_get (), rqst->rq_stime)); +__assign_str (procedure, rqst->rq_procinfo->pc_name);__assign_str (addr, rqst->rq_xprt->xpt_remotebuf); ), -TP_printk ("addr=%s xid=0x%08x execute-us=%lu" , -__get_str (addr), __entry->xid, __entry->execute) +TP_printk ("addr=%s xid=0x%08x proc=%s execute-us=%lu" , +__get_str (addr), __entry->xid,__get_str (procedure), + __entry->execute) ); DECLARE_EVENT_CLASS(svc_deferred_event,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 135/770 SUNRPC: Move definition of XDR_UNIT
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 81d217474326b25d7f14274b02fe3da1e85ad934 ]
Clean up: The unit of XDR alignment is defined by RFC 4506, not as part of the RPC message header. Thus it belongs in include/linux/sunrpc/xdr.h.
--- include/linux/sunrpc/msg_prot.h | 3 --- include/linux/sunrpc/xdr.h | 13 ++++++++++--- 2 files changed, 10 insertions(+), 6 deletions(-)
include/linux/sunrpc/msg_prot.h +0 -3
@@ -10,9 +10,6 @@#define RPC_VERSION 2 -/* size of an XDR encoding unit in bytes, i.e. 32bit */ -#define XDR_UNIT (4) -/* spec defines authentication flavor as an unsigned 32 bit integer */ typedef u32 rpc_authflavor_t ;
include/linux/sunrpc/xdr.h +10 -3
@@ -19,6 +19,13 @@struct bio_vec ;struct rpc_rqst ; +/* +* Size of an XDR encoding unit in bytes, i.e. 32 bits, +* as defined in Section 3 of RFC 4506. All encoded +* XDR data items are aligned on a boundary of 32 bits. +*/ +#define XDR_UNIT sizeof(__be32) +/* * Buffer adjustment */
@@ -329,7 +336,7 @@ ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,static inline size_t xdr_align_size (size_t n) { -const size_t mask =sizeof (__u32) -1 ; +const size_t mask =XDR_UNIT -1 ;return (n + mask) & ~mask; }
@@ -359,7 +366,7 @@ static inline size_t xdr_pad_size(size_t n)*/ static inline ssize_t xdr_stream_encode_item_present (struct xdr_stream *xdr) { -const size_t len =sizeof (__be32); +const size_t len =XDR_UNIT ;__be32 *p =xdr_reserve_space (xdr, len);if (unlikely (!p))
@@ -378,7 +385,7 @@ static inline ssize_t xdr_stream_encode_item_present(struct xdr_stream *xdr)*/ static inline int xdr_stream_encode_item_absent (struct xdr_stream *xdr) { -const size_t len =sizeof (__be32); +const size_t len =XDR_UNIT ;__be32 *p =xdr_reserve_space (xdr, len);if (unlikely (!p))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 136/770 NFSD: Update GETATTR3args decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 9575363a9e4c8d7e2f9ba5e79884d623fff0be6f ]
--- fs/nfsd/nfs3proc.c | 3 +-- fs/nfsd/nfs3xdr.c | 31 +++++++++++++++++++++++++------ fs/nfsd/xdr3.h | 2 +- 3 files changed, 27 insertions(+), 9 deletions(-)
fs/nfsd/nfs3proc.c +1 -2
@@ -688,7 +688,6 @@ nfsd3_proc_commit(struct svc_rqst *rqstp)* NFSv3 Server procedures. * Only the results of non-idempotent operations are cached. */ -#define nfs3svc_decode_fhandleargs nfs3svc_decode_fhandle#define nfs3svc_encode_attrstatres nfs3svc_encode_attrstat#define nfs3svc_encode_wccstatres nfs3svc_encode_wccstat#define nfsd3_mkdirargs nfsd3_createargs
@@ -720,7 +719,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { .pc_decode = nfs3svc_decode_fhandleargs, .pc_encode = nfs3svc_encode_attrstatres, .pc_release = nfs3svc_release_fhandle, - .pc_argsize = sizeof(struct nfsd3_fhandleargs), + .pc_argsize = sizeof(struct nfsd_fhandle), .pc_ressize = sizeof(struct nfsd3_attrstatres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+AT,
fs/nfsd/nfs3xdr.c +25 -6
@@ -29,8 +29,9 @@ static u32 nfs3_ftypes[] = {/* -* XDR functions for basic NFS types +* Basic NFSv3 data types (RFC 1813 Sections 2.5 and 2.6) */ +static __be32 *encode_time3 (__be32 *p,struct timespec64 *time) {
@@ -46,6 +47,26 @@ decode_time3(__be32 *p, struct timespec64 *time)return p; } +static bool +svcxdr_decode_nfs_fh3 (struct xdr_stream *xdr,struct svc_fh *fhp) +{ +__be32 *p; +u32 size; + +if (xdr_stream_decode_u32 (xdr, &size) <0 ) +return false; +if (size ==0 || size >NFS3_FHSIZE ) +return false; + p =xdr_inline_decode (xdr, size); +if (!p) +return false; +fh_init (fhp,NFS3_FHSIZE ); + fhp->fh_handle.fh_size = size; +memcpy (&fhp->fh_handle.fh_base, p, size); + +return true; +} +static __be32 *decode_fh (__be32 *p,struct svc_fh *fhp) {
@@ -312,14 +333,12 @@ void fill_post_wcc(struct svc_fh *fhp)*/ int -nfs3svc_decode_fhandle (struct svc_rqst *rqstp,__be32 *p) +nfs3svc_decode_fhandleargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd_fhandle *args = rqstp->rq_argp; - p =decode_fh (p, &args->fh); -if (!p) -return 0 ; -return xdr_argsize_check (rqstp, p); +return svcxdr_decode_nfs_fh3 (xdr, &args->fh); }int
fs/nfsd/xdr3.h +1 -1
@@ -273,7 +273,7 @@ union nfsd3_xdrstore {#define NFS3_SVC_XDRSIZE sizeof(union nfsd3_xdrstore) -int nfs3svc_decode_fhandle (struct svc_rqst *,__be32 *); +int nfs3svc_decode_fhandleargs (struct svc_rqst *,__be32 *);int nfs3svc_decode_sattrargs (struct svc_rqst *,__be32 *);int nfs3svc_decode_diropargs (struct svc_rqst *,__be32 *);int nfs3svc_decode_accessargs (struct svc_rqst *,__be32 *);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 137/770 NFSD: Update ACCESS3arg decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 3b921a2b14251e9e203f1e8af76e8ade79f50e50 ]
--- fs/nfsd/nfs3xdr.c | 9 +++++---- fs/nfsd/xdr3.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-)
fs/nfsd/nfs3xdr.c +5 -4
@@ -375,14 +375,15 @@ nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_accessargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_accessargs *args = rqstp->rq_argp; - p =decode_fh (p, &args->fh); -if (!p) +if (!svcxdr_decode_nfs_fh3 (xdr, &args->fh)) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->access) <0 )return 0 ; - args->access =ntohl (*p++); -return xdr_argsize_check (rqstp, p); +return 1 ; }int
fs/nfsd/xdr3.h +1 -1
@@ -25,7 +25,7 @@ struct nfsd3_diropargs {struct nfsd3_accessargs {struct svc_fh fh; -unsigned int access; +__u32 access; };struct nfsd3_readargs {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 138/770 NFSD: Update READ3arg decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit be63bd2ac6bbf8c065a0ef6dfbea76934326c352 ]
The code that sets up rq_vec is refactored so that it is now adjacent to the nfsd_read() call site where it is used.
--- fs/nfsd/nfs3proc.c | 23 ++++++++++++++++++----- fs/nfsd/nfs3xdr.c | 28 +++++++--------------------- fs/nfsd/xdr3.h | 1 - 3 files changed, 25 insertions(+), 27 deletions(-)
fs/nfsd/nfs3proc.c +18 -5
@@ -144,25 +144,38 @@ nfsd3_proc_read(struct svc_rqst *rqstp) {struct nfsd3_readargs *argp = rqstp->rq_argp;struct nfsd3_readres *resp = rqstp->rq_resp; -u32 max_blocksize =svc_max_payload (rqstp); -unsigned long cnt =min (argp->count, max_blocksize); +u32 max_blocksize =svc_max_payload (rqstp); +unsigned int len; +int v; + + argp->count =min_t (u32, argp->count, max_blocksize);dprintk ("nfsd: READ(3) %s %lu bytes at %Lu\n" ,SVCFH_fmt (&argp->fh), (unsigned long ) argp->count, (unsigned long long ) argp->offset); + v =0 ; + len = argp->count; +while (len >0 ) { +struct page *page = *(rqstp->rq_next_page++); + + rqstp->rq_vec[v].iov_base =page_address (page); + rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE); + len -= rqstp->rq_vec[v].iov_len; + v++; + } +/* Obtain buffer pointer for payload. * 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof) * + 1 (xdr opaque byte count) = 26 */ - resp->count = cnt; + resp->count = argp->count;svc_reserve_auth (rqstp, ((1 +NFS3_POST_OP_ATTR_WORDS +3 )<<2 ) + resp->count +4 );fh_copy (&resp->fh, &argp->fh); resp->status =nfsd_read (rqstp, &resp->fh, argp->offset, - rqstp->rq_vec, argp->vlen, &resp->count, - &resp->eof); + rqstp->rq_vec, v, &resp->count, &resp->eof);return rpc_success; }
fs/nfsd/nfs3xdr.c +7 -21
@@ -389,31 +389,17 @@ nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_readargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_readargs *args = rqstp->rq_argp; -unsigned int len; -int v; -u32 max_blocksize =svc_max_payload (rqstp); - p =decode_fh (p, &args->fh); -if (!p) +if (!svcxdr_decode_nfs_fh3 (xdr, &args->fh)) +return 0 ; +if (xdr_stream_decode_u64 (xdr, &args->offset) <0 ) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->count) <0 )return 0 ; - p =xdr_decode_hyper (p, &args->offset); - - args->count =ntohl (*p++); - len =min (args->count, max_blocksize); - -/* set up the kvec */ - v=0 ; -while (len >0 ) { -struct page *p = *(rqstp->rq_next_page++); - rqstp->rq_vec[v].iov_base =page_address (p); - rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE); - len -= rqstp->rq_vec[v].iov_len; - v++; - } - args->vlen = v; -return xdr_argsize_check (rqstp, p); +return 1 ; }int
fs/nfsd/xdr3.h +0 -1
@@ -32,7 +32,6 @@ struct nfsd3_readargs {struct svc_fh fh;__u64 offset;__u32 count; -int vlen; };struct nfsd3_writeargs {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 139/770 NFSD: Update WRITE3arg decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit c43b2f229a01969a7ccf94b033c5085e0ec2040c ]
As part of the update, open code that sanity-checks the size of the data payload against the length of the RPC Call message has to be re-implemented to use xdr_stream infrastructure.
--- fs/nfsd/nfs3xdr.c | 51 +++++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 31 deletions(-)
fs/nfsd/nfs3xdr.c +20 -31
@@ -405,52 +405,41 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_writeargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_writeargs *args = rqstp->rq_argp; -unsigned int len, hdr, dlen;u32 max_blocksize =svc_max_payload (rqstp);struct kvec *head = rqstp->rq_arg.head;struct kvec *tail = rqstp->rq_arg.tail; +size_t remaining; - p =decode_fh (p, &args->fh); -if (!p) +if (!svcxdr_decode_nfs_fh3 (xdr, &args->fh))return 0 ; - p =xdr_decode_hyper (p, &args->offset); - - args->count =ntohl (*p++); - args->stable =ntohl (*p++); - len = args->len =ntohl (*p++); -if ((void *)p > head->iov_base + head->iov_len) +if (xdr_stream_decode_u64 (xdr, &args->offset) <0 )return 0 ; -/* -* The count must equal the amount of data passed. -*/ -if (args->count != args->len) +if (xdr_stream_decode_u32 (xdr, &args->count) <0 ) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->stable) <0 )return 0 ; -/* -* Check to make sure that we got the right number of -* bytes. -*/ - hdr = (void *)p - head->iov_base; - dlen = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len - hdr; -/* -* Round the length of the data which was specified up to -* the next multiple of XDR units and then compare that -* against the length which was actually received. -* Note that when RPCSEC/GSS (for example) is used, the -* data buffer can be padded so dlen might be larger -* than required. It must never be smaller. -*/ -if (dlen <XDR_QUADLEN (len)*4 ) +/* opaque data */ +if (xdr_stream_decode_u32 (xdr, &args->len) <0 )return 0 ; +/* request sanity */ +if (args->count != args->len) +return 0 ; + remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len; + remaining -=xdr_stream_pos (xdr); +if (remaining <xdr_align_size (args->len)) +return 0 ;if (args->count > max_blocksize) { args->count = max_blocksize; - len = args->len = max_blocksize; + args->len = max_blocksize; } - args->first.iov_base = (void *)p; - args->first.iov_len = head->iov_len - hdr; + args->first.iov_base = xdr->p; + args->first.iov_len = head->iov_len -xdr_stream_pos (xdr); +return 1 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 140/770 NFSD: Update READLINK3arg decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 224c1c894e48cd72e4dd9fb6311be80cbe1369b0 ]
The NFSv3 READLINK request takes a single filehandle, so it can re-use GETATTR's decoder.
--- fs/nfsd/nfs3proc.c | 9 +++++---- fs/nfsd/nfs3xdr.c | 13 ------------- fs/nfsd/xdr3.h | 6 ------ 3 files changed, 5 insertions(+), 23 deletions(-)
fs/nfsd/nfs3proc.c +5 -4
@@ -124,15 +124,16 @@ nfsd3_proc_access(struct svc_rqst *rqstp)static __be32 nfsd3_proc_readlink (struct svc_rqst *rqstp) { -struct nfsd3_readlinkargs *argp = rqstp->rq_argp; +struct nfsd_fhandle *argp = rqstp->rq_argp;struct nfsd3_readlinkres *resp = rqstp->rq_resp; +char *buffer =page_address (*(rqstp->rq_next_page++));dprintk ("nfsd: READLINK(3) %s\n" ,SVCFH_fmt (&argp->fh));/* Read the symlink. */ fh_copy (&resp->fh, &argp->fh); resp->len =NFS3_MAXPATHLEN ; - resp->status =nfsd_readlink (rqstp, &resp->fh, argp->buffer, &resp->len); + resp->status =nfsd_readlink (rqstp, &resp->fh, buffer, &resp->len);return rpc_success; }
@@ -773,10 +774,10 @@ static const struct svc_procedure nfsd_procedures3[22] = { }, [NFS3PROC_READLINK] = { .pc_func = nfsd3_proc_readlink, - .pc_decode = nfs3svc_decode_readlinkargs, + .pc_decode = nfs3svc_decode_fhandleargs, .pc_encode = nfs3svc_encode_readlinkres, .pc_release = nfs3svc_release_fhandle, - .pc_argsize = sizeof(struct nfsd3_readlinkargs), + .pc_argsize = sizeof(struct nfsd_fhandle), .pc_ressize = sizeof(struct nfsd3_readlinkres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+1+NFS3_MAXPATHLEN/4,
fs/nfsd/nfs3xdr.c +0 -13
@@ -543,19 +543,6 @@ nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)return xdr_argsize_check (rqstp, p); } -int -nfs3svc_decode_readlinkargs (struct svc_rqst *rqstp,__be32 *p) -{ -struct nfsd3_readlinkargs *args = rqstp->rq_argp; - - p =decode_fh (p, &args->fh); -if (!p) -return 0 ; - args->buffer =page_address (*(rqstp->rq_next_page++)); - -return xdr_argsize_check (rqstp, p); -} -int nfs3svc_decode_linkargs (struct svc_rqst *rqstp,__be32 *p) {
fs/nfsd/xdr3.h +0 -6
@@ -70,11 +70,6 @@ struct nfsd3_renameargs {unsigned int tlen; }; -struct nfsd3_readlinkargs { -struct svc_fh fh; -char * buffer; -}; -struct nfsd3_linkargs {struct svc_fh ffh;struct svc_fh tfh;
@@ -282,7 +277,6 @@ int nfs3svc_decode_createargs(struct svc_rqst *, __be32 *);int nfs3svc_decode_mkdirargs (struct svc_rqst *,__be32 *);int nfs3svc_decode_mknodargs (struct svc_rqst *,__be32 *);int nfs3svc_decode_renameargs (struct svc_rqst *,__be32 *); -int nfs3svc_decode_readlinkargs (struct svc_rqst *,__be32 *);int nfs3svc_decode_linkargs (struct svc_rqst *,__be32 *);int nfs3svc_decode_symlinkargs (struct svc_rqst *,__be32 *);int nfs3svc_decode_readdirargs (struct svc_rqst *,__be32 *);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 141/770 NFSD: Fix returned READDIR offset cookie
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 0a8f37fb34a96267c656f7254e69bb9a2fc89fe4 ]
Code inspection shows that the server's NFSv3 READDIR implementation handles offset cookies slightly differently than the NFSv2 READDIR, NFSv3 READDIRPLUS, and NFSv4 READDIR implementations,
and there doesn't seem to be any need for this difference.
As a clean up, I copied the logic from nfsd3_proc_readdirplus().
--- fs/nfsd/nfs3proc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/nfsd/nfs3proc.c +4 -3
@@ -449,6 +449,7 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)struct nfsd3_readdirargs *argp = rqstp->rq_argp;struct nfsd3_readdirres *resp = rqstp->rq_resp;int count =0 ; +loff_t offset;struct page **p;caddr_t page_addr =NULL ;
@@ -467,7 +468,9 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp) resp->common.err = nfs_ok; resp->buffer = argp->buffer; resp->rqstp = rqstp; - resp->status =nfsd_readdir (rqstp, &resp->fh, (loff_t *)&argp->cookie, + offset = argp->cookie; + + resp->status =nfsd_readdir (rqstp, &resp->fh, &offset, &resp->common, nfs3svc_encode_entry);memcpy (resp->verf, argp->verf,8 ); count =0 ;
@@ -483,8 +486,6 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp) } resp->count = count >>2 ;if (resp->offset) { -loff_t offset = argp->cookie; -if (unlikely (resp->offset1)) {/* we ended up with offset on a page boundary */ *resp->offset =htonl (offset >>32 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 142/770 NFSD: Add helper to set up the pages where the dirlist is encoded
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 40116ebd0934cca7e46423bdb3397d3d27eb9fb9 ]
De-duplicate some code that is used by both READDIR and READDIRPLUS to build the dirlist in the Reply. Because this code is not related to decoding READ arguments, it is moved to a more appropriate spot.
--- fs/nfsd/nfs3proc.c | 29 +++++++++++++++++++---------- fs/nfsd/nfs3xdr.c | 20 -------------------- fs/nfsd/xdr3.h | 1 - 3 files changed, 19 insertions(+), 31 deletions(-)
fs/nfsd/nfs3proc.c +19 -10
@@ -440,6 +440,23 @@ nfsd3_proc_link(struct svc_rqst *rqstp)return rpc_success; } +static void nfsd3_init_dirlist_pages (struct svc_rqst *rqstp, +struct nfsd3_readdirres *resp, +int count) +{ + count =min_t (u32, count,svc_max_payload (rqstp)); + +/* Convert byte count to number of words (i.e. >> 2), +* and reserve room for the NULL ptr & eof flag (-2 words) */ + resp->buflen = (count >>2 ) -2 ; + + resp->buffer =page_address (*rqstp->rq_next_page); +while (count >0 ) { + rqstp->rq_next_page++; + count -=PAGE_SIZE ; + } +} +/* * Read a portion of a directory. */
@@ -457,16 +474,12 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)SVCFH_fmt (&argp->fh), argp->count, (u32) argp->cookie); -/* Make sure we've room for the NULL ptr & eof flag, and shrink to -* client read size */ - count = (argp->count >>2 ) -2 ; +nfsd3_init_dirlist_pages (rqstp, resp, argp->count);/* Read directory and encode entries on the fly */ fh_copy (&resp->fh, &argp->fh); - resp->buflen = count; resp->common.err = nfs_ok; - resp->buffer = argp->buffer; resp->rqstp = rqstp; offset = argp->cookie;
@@ -518,16 +531,12 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp)SVCFH_fmt (&argp->fh), argp->count, (u32) argp->cookie); -/* Convert byte count to number of words (i.e. >> 2), -* and reserve room for the NULL ptr & eof flag (-2 words) */ - resp->count = (argp->count >>2 ) -2 ; +nfsd3_init_dirlist_pages (rqstp, resp, argp->count);/* Read directory and encode entries on the fly */ fh_copy (&resp->fh, &argp->fh); resp->common.err = nfs_ok; - resp->buffer = argp->buffer; - resp->buflen = resp->count; resp->rqstp = rqstp; offset = argp->cookie;
fs/nfsd/nfs3xdr.c +0 -20
@@ -560,8 +560,6 @@ int nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p) { struct nfsd3_readdirargs *args = rqstp->rq_argp; -int len; -u32 max_blocksize =svc_max_payload (rqstp); p =decode_fh (p, &args->fh);if (!p)
@@ -570,14 +568,6 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p) args->verf = p; p +=2 ; args->dircount = ~0 ; args->count =ntohl (*p++); - len = args->count =min_t (u32, args->count, max_blocksize); - -while (len >0 ) { -struct page *p = *(rqstp->rq_next_page++); -if (!args->buffer) - args->buffer =page_address (p); - len -=PAGE_SIZE ; - }return xdr_argsize_check (rqstp, p); }
@@ -586,8 +576,6 @@ int nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p) { struct nfsd3_readdirargs *args = rqstp->rq_argp; -int len; -u32 max_blocksize =svc_max_payload (rqstp); p =decode_fh (p, &args->fh);if (!p)
@@ -597,14 +585,6 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p) args->dircount =ntohl (*p++); args->count =ntohl (*p++); - len = args->count =min (args->count, max_blocksize); -while (len >0 ) { -struct page *p = *(rqstp->rq_next_page++); -if (!args->buffer) - args->buffer =page_address (p); - len -=PAGE_SIZE ; - } -return xdr_argsize_check (rqstp, p); }
fs/nfsd/xdr3.h +0 -1
@@ -93,7 +93,6 @@ struct nfsd3_readdirargs {__u32 dircount;__u32 count;__be32 * verf; -__be32 * buffer; };struct nfsd3_commitargs {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 143/770 NFSD: Update READDIR3args decoders to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 9cedc2e64c296efb3bebe93a0ceeb5e71e8d722d ]
As an additional clean up, neither nfsd3_proc_readdir() nor nfsd3_proc_readdirplus() make use of the dircount argument, so remove it from struct nfsd3_readdirargs.
--- fs/nfsd/nfs3xdr.c | 38 ++++++++++++++++++++++++-------------- fs/nfsd/xdr3.h | 1 - 2 files changed, 24 insertions(+), 15 deletions(-)
fs/nfsd/nfs3xdr.c +24 -14
@@ -559,33 +559,43 @@ nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_readdirargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_readdirargs *args = rqstp->rq_argp; - p =decode_fh (p, &args->fh); -if (!p) +if (!svcxdr_decode_nfs_fh3 (xdr, &args->fh)) +return 0 ; +if (xdr_stream_decode_u64 (xdr, &args->cookie) <0 ) +return 0 ; + args->verf =xdr_inline_decode (xdr,NFS3_COOKIEVERFSIZE ); +if (!args->verf) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->count) <0 )return 0 ; - p =xdr_decode_hyper (p, &args->cookie); - args->verf = p; p +=2 ; - args->dircount = ~0 ; - args->count =ntohl (*p++); -return xdr_argsize_check (rqstp, p); +return 1 ; }int nfs3svc_decode_readdirplusargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_readdirargs *args = rqstp->rq_argp; +u32 dircount; - p =decode_fh (p, &args->fh); -if (!p) +if (!svcxdr_decode_nfs_fh3 (xdr, &args->fh)) +return 0 ; +if (xdr_stream_decode_u64 (xdr, &args->cookie) <0 ) +return 0 ; + args->verf =xdr_inline_decode (xdr,NFS3_COOKIEVERFSIZE ); +if (!args->verf) +return 0 ; +/* dircount is ignored */ +if (xdr_stream_decode_u32 (xdr, &dircount) <0 ) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->count) <0 )return 0 ; - p =xdr_decode_hyper (p, &args->cookie); - args->verf = p; p +=2 ; - args->dircount =ntohl (*p++); - args->count =ntohl (*p++); -return xdr_argsize_check (rqstp, p); +return 1 ; }int
fs/nfsd/xdr3.h +0 -1
@@ -90,7 +90,6 @@ struct nfsd3_symlinkargs {struct nfsd3_readdirargs {struct svc_fh fh;__u64 cookie; -__u32 dircount;__u32 count;__be32 * verf; };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 144/770 NFSD: Update COMMIT3arg decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit c8d26a0acfe77f0880e0acfe77e4209cf8f3a38b ]
--- fs/nfsd/nfs3xdr.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
fs/nfsd/nfs3xdr.c +8 -5
@@ -601,14 +601,17 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_commitargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_commitargs *args = rqstp->rq_argp; - p =decode_fh (p, &args->fh); -if (!p) + +if (!svcxdr_decode_nfs_fh3 (xdr, &args->fh)) +return 0 ; +if (xdr_stream_decode_u64 (xdr, &args->offset) <0 ) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->count) <0 )return 0 ; - p =xdr_decode_hyper (p, &args->offset); - args->count =ntohl (*p++); -return xdr_argsize_check (rqstp, p); +return 1 ; }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 145/770 NFSD: Update the NFSv3 DIROPargs decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 54d1d43dc709f58be38d278bfc38e9bfb38d35fc ]
--- fs/nfsd/nfs3xdr.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-)
fs/nfsd/nfs3xdr.c +35 -5
@@ -117,6 +117,39 @@ decode_filename(__be32 *p, char **namp, unsigned int *lenp)return p; } +static bool +svcxdr_decode_filename3 (struct xdr_stream *xdr,char **name,unsigned int *len) +{ +u32 size, i; +__be32 *p; +char *c; + +if (xdr_stream_decode_u32 (xdr, &size) <0 ) +return false; +if (size ==0 || size >NFS3_MAXNAMLEN ) +return false; + p =xdr_inline_decode (xdr, size); +if (!p) +return false; + + *len = size; + *name = (char *)p; +for (i =0 , c = *name; i < size; i++, c++) { +if (*c =='\0' || *c =='/' ) +return false; + } + +return true; +} + +static bool +svcxdr_decode_diropargs3 (struct xdr_stream *xdr,struct svc_fh *fhp, +char **name,unsigned int *len) +{ +return svcxdr_decode_nfs_fh3 (xdr, fhp) && +svcxdr_decode_filename3 (xdr, name, len); +} +static __be32 *decode_sattr3 (__be32 *p,struct iattr *iap,struct user_namespace *userns) {
@@ -363,13 +396,10 @@ nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_diropargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_diropargs *args = rqstp->rq_argp; -if (!(p =decode_fh (p, &args->fh)) - || !(p =decode_filename (p, &args->name, &args->len))) -return 0 ; - -return xdr_argsize_check (rqstp, p); +return svcxdr_decode_diropargs3 (xdr, &args->fh, &args->name, &args->len); }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 146/770 NFSD: Update the RENAME3args decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit d181e0a4bef36ee74d1338e5b5c2561d7463a5d0 ]
--- fs/nfsd/nfs3xdr.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
fs/nfsd/nfs3xdr.c +5 -7
@@ -562,15 +562,13 @@ nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_renameargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_renameargs *args = rqstp->rq_argp; -if (!(p =decode_fh (p, &args->ffh)) - || !(p =decode_filename (p, &args->fname, &args->flen)) - || !(p =decode_fh (p, &args->tfh)) - || !(p =decode_filename (p, &args->tname, &args->tlen))) -return 0 ; - -return xdr_argsize_check (rqstp, p); +return svcxdr_decode_diropargs3 (xdr, &args->ffh, + &args->fname, &args->flen) && +svcxdr_decode_diropargs3 (xdr, &args->tfh, + &args->tname, &args->tlen); }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 147/770 NFSD: Update the LINK3args decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit efaa1e7c2c7475f0a9bbeb904d9aba09b73dd52a ]
--- fs/nfsd/nfs3xdr.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
fs/nfsd/nfs3xdr.c +4 -6
@@ -574,14 +574,12 @@ nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_linkargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_linkargs *args = rqstp->rq_argp; -if (!(p =decode_fh (p, &args->ffh)) - || !(p =decode_fh (p, &args->tfh)) - || !(p =decode_filename (p, &args->tname, &args->tlen))) -return 0 ; - -return xdr_argsize_check (rqstp, p); +return svcxdr_decode_nfs_fh3 (xdr, &args->ffh) && +svcxdr_decode_diropargs3 (xdr, &args->tfh, + &args->tname, &args->tlen); }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 148/770 NFSD: Update the SETATTR3args decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 9cde9360d18d8b352b737d10f90f2aecccf93dbe ]
--- fs/nfsd/nfs3xdr.c | 138 +++++++++++++++++++++++++++++++++----- include/uapi/linux/nfs3.h | 6 ++ 2 files changed, 127 insertions(+), 17 deletions(-)
fs/nfsd/nfs3xdr.c +121 -17
@@ -39,12 +39,18 @@ encode_time3(__be32 *p, struct timespec64 *time)return p; } -static __be32 * -decode_time3 (__be32 *p,struct timespec64 *time) +static bool +svcxdr_decode_nfstime3 (struct xdr_stream *xdr,struct timespec64 *timep) { - time->tv_sec =ntohl (*p++); - time->tv_nsec =ntohl (*p++); -return p; +__be32 *p; + + p =xdr_inline_decode (xdr,XDR_UNIT *2 ); +if (!p) +return false; + timep->tv_sec =be32_to_cpup (p++); + timep->tv_nsec =be32_to_cpup (p); + +return true; } static bool
@@ -150,6 +156,112 @@ svcxdr_decode_diropargs3(struct xdr_stream *xdr, struct svc_fh *fhp,svcxdr_decode_filename3 (xdr, name, len); } +static bool +svcxdr_decode_sattr3 (struct svc_rqst *rqstp,struct xdr_stream *xdr, +struct iattr *iap) +{ +u32 set_it; + + iap->ia_valid =0 ; + +if (xdr_stream_decode_bool (xdr, &set_it) <0 ) +return false; +if (set_it) { +u32 mode; + +if (xdr_stream_decode_u32 (xdr, &mode) <0 ) +return false; + iap->ia_valid |=ATTR_MODE ; + iap->ia_mode = mode; + } +if (xdr_stream_decode_bool (xdr, &set_it) <0 ) +return false; +if (set_it) { +u32 uid; + +if (xdr_stream_decode_u32 (xdr, &uid) <0 ) +return false; + iap->ia_uid =make_kuid (nfsd_user_namespace (rqstp), uid); +if (uid_valid (iap->ia_uid)) + iap->ia_valid |=ATTR_UID ; + } +if (xdr_stream_decode_bool (xdr, &set_it) <0 ) +return false; +if (set_it) { +u32 gid; + +if (xdr_stream_decode_u32 (xdr, &gid) <0 ) +return false; + iap->ia_gid =make_kgid (nfsd_user_namespace (rqstp), gid); +if (gid_valid (iap->ia_gid)) + iap->ia_valid |=ATTR_GID ; + } +if (xdr_stream_decode_bool (xdr, &set_it) <0 ) +return false; +if (set_it) { +u64 newsize; + +if (xdr_stream_decode_u64 (xdr, &newsize) <0 ) +return false; + iap->ia_valid |=ATTR_SIZE ; + iap->ia_size =min_t (u64, newsize,NFS_OFFSET_MAX ); + } +if (xdr_stream_decode_u32 (xdr, &set_it) <0 ) +return false; +switch (set_it) { +case DONT_CHANGE : +break ; +case SET_TO_SERVER_TIME : + iap->ia_valid |=ATTR_ATIME ; +break ; +case SET_TO_CLIENT_TIME : +if (!svcxdr_decode_nfstime3 (xdr, &iap->ia_atime)) +return false; + iap->ia_valid |=ATTR_ATIME |ATTR_ATIME_SET ; +break ; +default : +return false; + } +if (xdr_stream_decode_u32 (xdr, &set_it) <0 ) +return false; +switch (set_it) { +case DONT_CHANGE : +break ; +case SET_TO_SERVER_TIME : + iap->ia_valid |=ATTR_MTIME ; +break ; +case SET_TO_CLIENT_TIME : +if (!svcxdr_decode_nfstime3 (xdr, &iap->ia_mtime)) +return false; + iap->ia_valid |=ATTR_MTIME |ATTR_MTIME_SET ; +break ; +default : +return false; + } + +return true; +} + +static bool +svcxdr_decode_sattrguard3 (struct xdr_stream *xdr,struct nfsd3_sattrargs *args) +{ +__be32 *p; +u32 check; + +if (xdr_stream_decode_bool (xdr, &check) <0 ) +return false; +if (check) { + p =xdr_inline_decode (xdr,XDR_UNIT *2 ); +if (!p) +return false; + args->check_guard =1 ; + args->guardtime =be32_to_cpup (p); + }else + args->check_guard =0 ; + +return true; +} +static __be32 *decode_sattr3 (__be32 *p,struct iattr *iap,struct user_namespace *userns) {
@@ -377,20 +489,12 @@ nfs3svc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_sattrargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_sattrargs *args = rqstp->rq_argp; - p =decode_fh (p, &args->fh); -if (!p) -return 0 ; - p =decode_sattr3 (p, &args->attrs,nfsd_user_namespace (rqstp)); - -if ((args->check_guard =ntohl (*p++)) !=0 ) { -struct timespec64 time; - p =decode_time3 (p, &time); - args->guardtime = time.tv_sec; - } - -return xdr_argsize_check (rqstp, p); +return svcxdr_decode_nfs_fh3 (xdr, &args->fh) && +svcxdr_decode_sattr3 (rqstp, xdr, &args->attrs) && +svcxdr_decode_sattrguard3 (xdr, args); }int
include/uapi/linux/nfs3.h +6 -0
@@ -63,6 +63,12 @@ enum nfs3_ftype {NF3BAD =8 }; +enum nfs3_time_how { +DONT_CHANGE =0 , +SET_TO_SERVER_TIME =1 , +SET_TO_CLIENT_TIME =2 , +}; +struct nfs3_fh {unsigned short size;unsigned char data[NFS3_FHSIZE ];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 149/770 NFSD: Update the CREATE3args decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 6b3a11960d898b25a30103cc6a2ff0b24b90a83b ]
--- fs/nfsd/nfs3xdr.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
fs/nfsd/nfs3xdr.c +10 -10
@@ -580,26 +580,26 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_createargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_createargs *args = rqstp->rq_argp; -if (!(p =decode_fh (p, &args->fh)) - || !(p =decode_filename (p, &args->name, &args->len))) +if (!svcxdr_decode_diropargs3 (xdr, &args->fh, &args->name, &args->len))return 0 ; - -switch (args->createmode =ntohl (*p++)) { +if (xdr_stream_decode_u32 (xdr, &args->createmode) <0 ) +return 0 ; +switch (args->createmode) {case NFS3_CREATE_UNCHECKED :case NFS3_CREATE_GUARDED : - p =decode_sattr3 (p, &args->attrs,nfsd_user_namespace (rqstp)); -break ; +return svcxdr_decode_sattr3 (rqstp, xdr, &args->attrs);case NFS3_CREATE_EXCLUSIVE : - args->verf = p; - p +=2 ; + args->verf =xdr_inline_decode (xdr,NFS3_CREATEVERFSIZE ); +if (!args->verf) +return 0 ;break ;default :return 0 ; } - -return xdr_argsize_check (rqstp, p); +return 1 ; }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 150/770 NFSD: Update the MKDIR3args decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 83374c278db193f3e8b2608b45da1132b867a760 ]
--- fs/nfsd/nfs3xdr.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
fs/nfsd/nfs3xdr.c +4 -6
@@ -605,14 +605,12 @@ nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_mkdirargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_createargs *args = rqstp->rq_argp; -if (!(p =decode_fh (p, &args->fh)) || - !(p =decode_filename (p, &args->name, &args->len))) -return 0 ; - p =decode_sattr3 (p, &args->attrs,nfsd_user_namespace (rqstp)); - -return xdr_argsize_check (rqstp, p); +return svcxdr_decode_diropargs3 (xdr, &args->fh, + &args->name, &args->len) && +svcxdr_decode_sattr3 (rqstp, xdr, &args->attrs); }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 151/770 NFSD: Update the SYMLINK3args decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit da39201637297460c13134c29286a00f3a1c92fe ]
Similar to the WRITE decoder, code that checks the sanity of the payload size is re-wired to work with xdr_stream infrastructure.
--- fs/nfsd/nfs3xdr.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-)
fs/nfsd/nfs3xdr.c +16 -13
@@ -616,25 +616,28 @@ nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_symlinkargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_symlinkargs *args = rqstp->rq_argp; -char *base = (char *)p; -size_t dlen; +struct kvec *head = rqstp->rq_arg.head; +struct kvec *tail = rqstp->rq_arg.tail; +size_t remaining; -if (!(p =decode_fh (p, &args->ffh)) || - !(p =decode_filename (p, &args->fname, &args->flen))) +if (!svcxdr_decode_diropargs3 (xdr, &args->ffh, &args->fname, &args->flen)) +return 0 ; +if (!svcxdr_decode_sattr3 (rqstp, xdr, &args->attrs)) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->tlen) <0 )return 0 ; - p =decode_sattr3 (p, &args->attrs,nfsd_user_namespace (rqstp)); - args->tlen =ntohl (*p++); +/* request sanity */ + remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len; + remaining -=xdr_stream_pos (xdr); +if (remaining <xdr_align_size (args->tlen)) +return 0 ; - args->first.iov_base = p; - args->first.iov_len = rqstp->rq_arg.head[0 ].iov_len; - args->first.iov_len -= (char *)p - base; + args->first.iov_base = xdr->p; + args->first.iov_len = head->iov_len -xdr_stream_pos (xdr); - dlen = args->first.iov_len + rqstp->rq_arg.page_len + - rqstp->rq_arg.tail[0 ].iov_len; -if (dlen <XDR_QUADLEN (args->tlen) <<2 ) -return 0 ;return 1 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 152/770 NFSD: Update the MKNOD3args decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit f8a38e2d6c885f9d7cd03febc515d36293de4a5b ]
This commit removes the last usage of the original decode_sattr3(), so it is removed as a clean-up.
--- fs/nfsd/nfs3xdr.c | 107 +++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 72 deletions(-)
fs/nfsd/nfs3xdr.c +35 -72
@@ -103,26 +103,6 @@ encode_fh(__be32 *p, struct svc_fh *fhp)return p +XDR_QUADLEN (size); } -/* -* Decode a file name and make sure that the path contains -* no slashes or null bytes. -*/ -static __be32 * -decode_filename (__be32 *p,char **namp,unsigned int *lenp) -{ -char *name; -unsigned int i; - -if ((p =xdr_decode_string_inplace (p, namp, lenp,NFS3_MAXNAMLEN )) !=NULL ) { -for (i =0 , name = *namp; i < *lenp; i++, name++) { -if (*name =='\0' || *name =='/' ) -return NULL ; - } - } - -return p; -} -static bool svcxdr_decode_filename3 (struct xdr_stream *xdr,char **name,unsigned int *len) {
@@ -262,49 +242,26 @@ svcxdr_decode_sattrguard3(struct xdr_stream *xdr, struct nfsd3_sattrargs *args)return true; } -static __be32 * -decode_sattr3 (__be32 *p,struct iattr *iap,struct user_namespace *userns) +static bool +svcxdr_decode_specdata3 (struct xdr_stream *xdr,struct nfsd3_mknodargs *args) { -u32 tmp; +__be32 *p; - iap->ia_valid =0 ; + p =xdr_inline_decode (xdr,XDR_UNIT *2 ); +if (!p) +return false; + args->major =be32_to_cpup (p++); + args->minor =be32_to_cpup (p); -if (*p++) { - iap->ia_valid |=ATTR_MODE ; - iap->ia_mode =ntohl (*p++); - } -if (*p++) { - iap->ia_uid =make_kuid (userns,ntohl (*p++)); -if (uid_valid (iap->ia_uid)) - iap->ia_valid |=ATTR_UID ; - } -if (*p++) { - iap->ia_gid =make_kgid (userns,ntohl (*p++)); -if (gid_valid (iap->ia_gid)) - iap->ia_valid |=ATTR_GID ; - } -if (*p++) { -u64 newsize; +return true; +} - iap->ia_valid |=ATTR_SIZE ; - p =xdr_decode_hyper (p, &newsize); - iap->ia_size =min_t (u64, newsize,NFS_OFFSET_MAX ); - } -if ((tmp =ntohl (*p++)) ==1 ) {/* set to server time */ - iap->ia_valid |=ATTR_ATIME ; - }else if (tmp ==2 ) {/* set to client time */ - iap->ia_valid |=ATTR_ATIME |ATTR_ATIME_SET ; - iap->ia_atime.tv_sec =ntohl (*p++); - iap->ia_atime.tv_nsec =ntohl (*p++); - } -if ((tmp =ntohl (*p++)) ==1 ) {/* set to server time */ - iap->ia_valid |=ATTR_MTIME ; - }else if (tmp ==2 ) {/* set to client time */ - iap->ia_valid |=ATTR_MTIME |ATTR_MTIME_SET ; - iap->ia_mtime.tv_sec =ntohl (*p++); - iap->ia_mtime.tv_nsec =ntohl (*p++); - } -return p; +static bool +svcxdr_decode_devicedata3 (struct svc_rqst *rqstp,struct xdr_stream *xdr, +struct nfsd3_mknodargs *args) +{ +return svcxdr_decode_sattr3 (rqstp, xdr, &args->attrs) && +svcxdr_decode_specdata3 (xdr, args); }static __be32 *encode_fsid (__be32 *p,struct svc_fh *fhp)
@@ -644,24 +601,30 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_decode_mknodargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_mknodargs *args = rqstp->rq_argp; -if (!(p =decode_fh (p, &args->fh)) - || !(p =decode_filename (p, &args->name, &args->len))) +if (!svcxdr_decode_diropargs3 (xdr, &args->fh, &args->name, &args->len)) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->ftype) <0 ) +return 0 ; +switch (args->ftype) { +case NF3CHR : +case NF3BLK : +return svcxdr_decode_devicedata3 (rqstp, xdr, args); +case NF3SOCK : +case NF3FIFO : +return svcxdr_decode_sattr3 (rqstp, xdr, &args->attrs); +case NF3REG : +case NF3DIR : +case NF3LNK : +/* Valid XDR but illegal file types */ +break ; +default :return 0 ; - - args->ftype =ntohl (*p++); - -if (args->ftype ==NF3BLK || args->ftype ==NF3CHR - || args->ftype ==NF3SOCK || args->ftype ==NF3FIFO ) - p =decode_sattr3 (p, &args->attrs,nfsd_user_namespace (rqstp)); - -if (args->ftype ==NF3BLK || args->ftype ==NF3CHR ) { - args->major =ntohl (*p++); - args->minor =ntohl (*p++); } -return xdr_argsize_check (rqstp, p); +return 1 ; }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 153/770 NFSD: Update the NFSv2 GETATTR argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit ebcd8e8b28535b643a4c06685bd363b3b73a96af ]
--- fs/nfsd/nfsproc.c | 4 ++-- fs/nfsd/nfsxdr.c | 26 ++++++++++++++++++++------ fs/nfsd/xdr.h | 2 +- 3 files changed, 23 insertions(+), 9 deletions(-)
fs/nfsd/nfsproc.c +2 -2
@@ -627,7 +627,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { }, [NFSPROC_GETATTR] = { .pc_func = nfsd_proc_getattr, - .pc_decode = nfssvc_decode_fhandle, + .pc_decode = nfssvc_decode_fhandleargs, .pc_encode = nfssvc_encode_attrstat, .pc_release = nfssvc_release_attrstat, .pc_argsize = sizeof(struct nfsd_fhandle),
@@ -793,7 +793,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { }, [NFSPROC_STATFS] = { .pc_func = nfsd_proc_statfs, - .pc_decode = nfssvc_decode_fhandle, + .pc_decode = nfssvc_decode_fhandleargs, .pc_encode = nfssvc_encode_statfsres, .pc_argsize = sizeof(struct nfsd_fhandle), .pc_ressize = sizeof(struct nfsd_statfsres),
fs/nfsd/nfsxdr.c +20 -6
@@ -23,8 +23,9 @@ static u32 nfs_ftypes[] = {/* -* XDR functions for basic NFS types +* Basic NFSv2 data types (RFC 1094 Section 2.3) */ +static __be32 *decode_fh (__be32 *p,struct svc_fh *fhp) {
@@ -37,6 +38,21 @@ decode_fh(__be32 *p, struct svc_fh *fhp)return p + (NFS_FHSIZE >>2 ); } +static bool +svcxdr_decode_fhandle (struct xdr_stream *xdr,struct svc_fh *fhp) +{ +__be32 *p; + + p =xdr_inline_decode (xdr,NFS_FHSIZE ); +if (!p) +return false; +fh_init (fhp,NFS_FHSIZE ); +memcpy (&fhp->fh_handle.fh_base, p,NFS_FHSIZE ); + fhp->fh_handle.fh_size =NFS_FHSIZE ; + +return true; +} +/* Helper function for NFSv2 ACL code */ __be32 *nfs2svc_decode_fh (__be32 *p,struct svc_fh *fhp) {
@@ -194,14 +210,12 @@ __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *f*/ int -nfssvc_decode_fhandle (struct svc_rqst *rqstp,__be32 *p) +nfssvc_decode_fhandleargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd_fhandle *args = rqstp->rq_argp; - p =decode_fh (p, &args->fh); -if (!p) -return 0 ; -return xdr_argsize_check (rqstp, p); +return svcxdr_decode_fhandle (xdr, &args->fh); }int
fs/nfsd/xdr.h +1 -1
@@ -144,7 +144,7 @@ union nfsd_xdrstore {#define NFS2_SVC_XDRSIZE sizeof(union nfsd_xdrstore) -int nfssvc_decode_fhandle (struct svc_rqst *,__be32 *); +int nfssvc_decode_fhandleargs (struct svc_rqst *,__be32 *);int nfssvc_decode_sattrargs (struct svc_rqst *,__be32 *);int nfssvc_decode_diropargs (struct svc_rqst *,__be32 *);int nfssvc_decode_readargs (struct svc_rqst *,__be32 *);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 154/770 NFSD: Update the NFSv2 READ argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 8c293ef993c8df0b1bea9ecb0de6eb96dec3ac9d ]
The code that sets up rq_vec is refactored so that it is now adjacent to the nfsd_read() call site where it is used.
--- fs/nfsd/nfsproc.c | 32 ++++++++++++++++++-------------- fs/nfsd/nfsxdr.c | 36 ++++++++++++------------------------ fs/nfsd/xdr.h | 1 - 3 files changed, 30 insertions(+), 39 deletions(-)
fs/nfsd/nfsproc.c +18 -14
@@ -171,32 +171,36 @@ nfsd_proc_read(struct svc_rqst *rqstp) {struct nfsd_readargs *argp = rqstp->rq_argp;struct nfsd_readres *resp = rqstp->rq_resp; +unsigned int len;u32 eof; +int v;dprintk ("nfsd: READ %s %d bytes at %d\n" ,SVCFH_fmt (&argp->fh), argp->count, argp->offset); + argp->count =min_t (u32, argp->count,NFSSVC_MAXBLKSIZE_V2 ); + + v =0 ; + len = argp->count; +while (len >0 ) { +struct page *page = *(rqstp->rq_next_page++); + + rqstp->rq_vec[v].iov_base =page_address (page); + rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE); + len -= rqstp->rq_vec[v].iov_len; + v++; + } +/* Obtain buffer pointer for payload. 19 is 1 word for * status, 17 words for fattr, and 1 word for the byte count. */ - -if (NFSSVC_MAXBLKSIZE_V2 < argp->count) { -char buf[RPC_MAX_ADDRBUFLEN ]; -printk (KERN_NOTICE -"oversized read request from %s (%d bytes)\n" , -svc_print_addr (rqstp, buf,sizeof (buf)), - argp->count); - argp->count =NFSSVC_MAXBLKSIZE_V2 ; - }svc_reserve_auth (rqstp, (19 <<2 ) + argp->count +4 ); resp->count = argp->count; - resp->status =nfsd_read (rqstp,fh_copy (&resp->fh, &argp->fh), - argp->offset, - rqstp->rq_vec, argp->vlen, - &resp->count, - &eof); +fh_copy (&resp->fh, &argp->fh); + resp->status =nfsd_read (rqstp, &resp->fh, argp->offset, + rqstp->rq_vec, v, &resp->count, &eof);if (resp->status == nfs_ok) resp->status =fh_getattr (&resp->fh, &resp->stat);else if (resp->status == nfserr_jukebox)
fs/nfsd/nfsxdr.c +12 -24
@@ -246,33 +246,21 @@ nfssvc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p)int nfssvc_decode_readargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd_readargs *args = rqstp->rq_argp; -unsigned int len; -int v; - p =decode_fh (p, &args->fh); -if (!p) -return 0 ; +u32 totalcount; - args->offset =ntohl (*p++); - len = args->count =ntohl (*p++); - p++;/* totalcount - unused */ - - len = min_t(unsigned int, len, NFSSVC_MAXBLKSIZE_V2); +if (!svcxdr_decode_fhandle (xdr, &args->fh)) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->offset) <0 ) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->count) <0 ) +return 0 ; +/* totalcount is ignored */ +if (xdr_stream_decode_u32 (xdr, &totalcount) <0 ) +return 0 ; -/* set up somewhere to store response. -* We take pages, put them on reslist and include in iovec -*/ - v=0 ; -while (len >0 ) { -struct page *p = *(rqstp->rq_next_page++); - - rqstp->rq_vec[v].iov_base =page_address (p); - rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE); - len -= rqstp->rq_vec[v].iov_len; - v++; - } - args->vlen = v; -return xdr_argsize_check (rqstp, p); +return 1 ; }int
fs/nfsd/xdr.h +0 -1
@@ -27,7 +27,6 @@ struct nfsd_readargs {struct svc_fh fh;__u32 offset;__u32 count; -int vlen; };struct nfsd_writeargs {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 155/770 NFSD: Update the NFSv2 WRITE argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit a51b5b737a0be93fae6ea2a18df03ab2359a3f4b ]
--- fs/nfsd/nfsxdr.c | 52 +++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 31 deletions(-)
fs/nfsd/nfsxdr.c +21 -31
@@ -266,46 +266,36 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p)int nfssvc_decode_writeargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd_writeargs *args = rqstp->rq_argp; -unsigned int len, hdr, dlen;struct kvec *head = rqstp->rq_arg.head; +struct kvec *tail = rqstp->rq_arg.tail; +u32 beginoffset, totalcount; +size_t remaining; - p =decode_fh (p, &args->fh); -if (!p) +if (!svcxdr_decode_fhandle (xdr, &args->fh))return 0 ; - - p++;/* beginoffset */ - args->offset =ntohl (*p++);/* offset */ - p++;/* totalcount */ - len = args->len =ntohl (*p++); -/* -* The protocol specifies a maximum of 8192 bytes. -*/ -if (len >NFSSVC_MAXBLKSIZE_V2 ) +/* beginoffset is ignored */ +if (xdr_stream_decode_u32 (xdr, &beginoffset) <0 )return 0 ; - -/* -* Check to make sure that we got the right number of -* bytes. -*/ - hdr = (void *)p - head->iov_base; -if (hdr > head->iov_len) +if (xdr_stream_decode_u32 (xdr, &args->offset) <0 ) +return 0 ; +/* totalcount is ignored */ +if (xdr_stream_decode_u32 (xdr, &totalcount) <0 )return 0 ; - dlen = head->iov_len + rqstp->rq_arg.page_len - hdr; -/* -* Round the length of the data which was specified up to -* the next multiple of XDR units and then compare that -* against the length which was actually received. -* Note that when RPCSEC/GSS (for example) is used, the -* data buffer can be padded so dlen might be larger -* than required. It must never be smaller. -*/ -if (dlen <XDR_QUADLEN (len)*4 ) +/* opaque data */ +if (xdr_stream_decode_u32 (xdr, &args->len) <0 ) +return 0 ; +if (args->len >NFSSVC_MAXBLKSIZE_V2 ) +return 0 ; + remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len; + remaining -=xdr_stream_pos (xdr); +if (remaining <xdr_align_size (args->len))return 0 ; + args->first.iov_base = xdr->p; + args->first.iov_len = head->iov_len -xdr_stream_pos (xdr); - args->first.iov_base = (void *)p; - args->first.iov_len = head->iov_len - hdr;return 1 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 156/770 NFSD: Update the NFSv2 READLINK argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 1fcbd1c9456ba129d38420e345e91c4b6363db47 ]
If the code that sets up the sink buffer for nfsd_readlink() is moved adjacent to the nfsd_readlink() call site that uses it, then the only argument is a file handle, and the fhandle decoder can be used instead.
--- fs/nfsd/nfsproc.c | 9 +++++---- fs/nfsd/nfsxdr.c | 13 ------------- fs/nfsd/xdr.h | 6 ------ 3 files changed, 5 insertions(+), 23 deletions(-)
fs/nfsd/nfsproc.c +5 -4
@@ -149,14 +149,15 @@ nfsd_proc_lookup(struct svc_rqst *rqstp)static __be32 nfsd_proc_readlink (struct svc_rqst *rqstp) { -struct nfsd_readlinkargs *argp = rqstp->rq_argp; +struct nfsd_fhandle *argp = rqstp->rq_argp;struct nfsd_readlinkres *resp = rqstp->rq_resp; +char *buffer =page_address (*(rqstp->rq_next_page++));dprintk ("nfsd: READLINK %s\n" ,SVCFH_fmt (&argp->fh));/* Read the symlink. */ resp->len =NFS_MAXPATHLEN ; - resp->status =nfsd_readlink (rqstp, &argp->fh, argp->buffer, &resp->len); + resp->status =nfsd_readlink (rqstp, &argp->fh, buffer, &resp->len);fh_put (&argp->fh);return rpc_success;
@@ -674,9 +675,9 @@ static const struct svc_procedure nfsd_procedures2[18] = { }, [NFSPROC_READLINK] = { .pc_func = nfsd_proc_readlink, - .pc_decode = nfssvc_decode_readlinkargs, + .pc_decode = nfssvc_decode_fhandleargs, .pc_encode = nfssvc_encode_readlinkres, - .pc_argsize = sizeof(struct nfsd_readlinkargs), + .pc_argsize = sizeof(struct nfsd_fhandle), .pc_ressize = sizeof(struct nfsd_readlinkres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+1+NFS_MAXPATHLEN/4,
fs/nfsd/nfsxdr.c +0 -13
@@ -326,19 +326,6 @@ nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)return xdr_argsize_check (rqstp, p); } -int -nfssvc_decode_readlinkargs (struct svc_rqst *rqstp,__be32 *p) -{ -struct nfsd_readlinkargs *args = rqstp->rq_argp; - - p =decode_fh (p, &args->fh); -if (!p) -return 0 ; - args->buffer =page_address (*(rqstp->rq_next_page++)); - -return xdr_argsize_check (rqstp, p); -} -int nfssvc_decode_linkargs (struct svc_rqst *rqstp,__be32 *p) {
fs/nfsd/xdr.h +0 -6
@@ -52,11 +52,6 @@ struct nfsd_renameargs {unsigned int tlen; }; -struct nfsd_readlinkargs { -struct svc_fh fh; -char * buffer; -}; -struct nfsd_linkargs {struct svc_fh ffh;struct svc_fh tfh;
@@ -150,7 +145,6 @@ int nfssvc_decode_readargs(struct svc_rqst *, __be32 *);int nfssvc_decode_writeargs (struct svc_rqst *,__be32 *);int nfssvc_decode_createargs (struct svc_rqst *,__be32 *);int nfssvc_decode_renameargs (struct svc_rqst *,__be32 *); -int nfssvc_decode_readlinkargs (struct svc_rqst *,__be32 *);int nfssvc_decode_linkargs (struct svc_rqst *,__be32 *);int nfssvc_decode_symlinkargs (struct svc_rqst *,__be32 *);int nfssvc_decode_readdirargs (struct svc_rqst *,__be32 *);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 157/770 NFSD: Add helper to set up the pages where the dirlist is encoded, again
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 788cd46ecf83ee2d561cb4e754e276dc8089b787 ]
Add a helper similar to nfsd3_init_dirlist_pages().
--- fs/nfsd/nfsproc.c | 29 ++++++++++++++++++----------- fs/nfsd/nfsxdr.c | 2 -- fs/nfsd/xdr.h | 1 - 3 files changed, 18 insertions(+), 14 deletions(-)
fs/nfsd/nfsproc.c +18 -11
@@ -553,6 +553,20 @@ nfsd_proc_rmdir(struct svc_rqst *rqstp)return rpc_success; } +static void nfsd_init_dirlist_pages (struct svc_rqst *rqstp, +struct nfsd_readdirres *resp, +int count) +{ + count =min_t (u32, count,PAGE_SIZE ); + +/* Convert byte count to number of words (i.e. >> 2), +* and reserve room for the NULL ptr & eof flag (-2 words) */ + resp->buflen = (count >>2 ) -2 ; + + resp->buffer =page_address (*rqstp->rq_next_page); + rqstp->rq_next_page++; +} +/* * Read a portion of a directory. */
@@ -561,31 +575,24 @@ nfsd_proc_readdir(struct svc_rqst *rqstp) {struct nfsd_readdirargs *argp = rqstp->rq_argp;struct nfsd_readdirres *resp = rqstp->rq_resp; -int count;loff_t offset; +__be32 *buffer;dprintk ("nfsd: READDIR %s %d bytes at %d\n" ,SVCFH_fmt (&argp->fh), argp->count, argp->cookie); -/* Shrink to the client read size */ - count = (argp->count >>2 ) -2 ; - -/* Make sure we've room for the NULL ptr & eof flag */ - count -=2 ; -if (count <0 ) - count =0 ; +nfsd_init_dirlist_pages (rqstp, resp, argp->count); + buffer = resp->buffer; - resp->buffer = argp->buffer; resp->offset =NULL ; - resp->buflen = count; resp->common.err = nfs_ok;/* Read directory and encode entries on the fly */ offset = argp->cookie; resp->status =nfsd_readdir (rqstp, &argp->fh, &offset, &resp->common, nfssvc_encode_entry); - resp->count = resp->buffer - argp->buffer; + resp->count = resp->buffer - buffer;if (resp->offset) *resp->offset =htonl (offset);
fs/nfsd/nfsxdr.c +0 -2
@@ -388,8 +388,6 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)return 0 ; args->cookie =ntohl (*p++); args->count =ntohl (*p++); - args->count =min_t (u32, args->count,PAGE_SIZE ); - args->buffer =page_address (*(rqstp->rq_next_page++));return xdr_argsize_check (rqstp, p); }
fs/nfsd/xdr.h +0 -1
@@ -73,7 +73,6 @@ struct nfsd_readdirargs {struct svc_fh fh;__u32 cookie;__u32 count; -__be32 * buffer; };struct nfsd_stat {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 158/770 NFSD: Update the NFSv2 READDIR argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 8688361ae2edb8f7e61d926dc5000c9a44f29370 ]
As an additional clean up, move code not related to XDR decoding into readdir's .pc_func call out.
--- fs/nfsd/nfsxdr.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
fs/nfsd/nfsxdr.c +7 -5
@@ -381,15 +381,17 @@ nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)int nfssvc_decode_readdirargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd_readdirargs *args = rqstp->rq_argp; - p =decode_fh (p, &args->fh); -if (!p) +if (!svcxdr_decode_fhandle (xdr, &args->fh)) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->cookie) <0 ) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->count) <0 )return 0 ; - args->cookie =ntohl (*p++); - args->count =ntohl (*p++); -return xdr_argsize_check (rqstp, p); +return 1 ; }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 159/770 NFSD: Update NFSv2 diropargs decoding to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 6d742c1864c18f143ea2031f1ed66bcd8f4812de ]
--- fs/nfsd/nfsxdr.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-)
fs/nfsd/nfsxdr.c +34 -5
@@ -86,6 +86,38 @@ decode_filename(__be32 *p, char **namp, unsigned int *lenp)return p; } +static bool +svcxdr_decode_filename (struct xdr_stream *xdr,char **name,unsigned int *len) +{ +u32 size, i; +__be32 *p; +char *c; + +if (xdr_stream_decode_u32 (xdr, &size) <0 ) +return false; +if (size ==0 || size >NFS_MAXNAMLEN ) +return false; + p =xdr_inline_decode (xdr, size); +if (!p) +return false; + + *len = size; + *name = (char *)p; +for (i =0 , c = *name; i < size; i++, c++) +if (*c =='\0' || *c =='/' ) +return false; + +return true; +} + +static bool +svcxdr_decode_diropargs (struct xdr_stream *xdr,struct svc_fh *fhp, +char **name,unsigned int *len) +{ +return svcxdr_decode_fhandle (xdr, fhp) && +svcxdr_decode_filename (xdr, name, len); +} +static __be32 *decode_sattr (__be32 *p,struct iattr *iap,struct user_namespace *userns) {
@@ -234,13 +266,10 @@ nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)int nfssvc_decode_diropargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd_diropargs *args = rqstp->rq_argp; -if (!(p =decode_fh (p, &args->fh)) - || !(p =decode_filename (p, &args->name, &args->len))) -return 0 ; - -return xdr_argsize_check (rqstp, p); +return svcxdr_decode_diropargs (xdr, &args->fh, &args->name, &args->len); }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 160/770 NFSD: Update the NFSv2 RENAME argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 62aa557efb81ea3339fabe7f5b1a343e742bbbdf ]
--- fs/nfsd/nfsxdr.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
fs/nfsd/nfsxdr.c +5 -7
@@ -344,15 +344,13 @@ nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p)int nfssvc_decode_renameargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd_renameargs *args = rqstp->rq_argp; -if (!(p =decode_fh (p, &args->ffh)) - || !(p =decode_filename (p, &args->fname, &args->flen)) - || !(p =decode_fh (p, &args->tfh)) - || !(p =decode_filename (p, &args->tname, &args->tlen))) -return 0 ; - -return xdr_argsize_check (rqstp, p); +return svcxdr_decode_diropargs (xdr, &args->ffh, + &args->fname, &args->flen) && +svcxdr_decode_diropargs (xdr, &args->tfh, + &args->tname, &args->tlen); }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 161/770 NFSD: Update the NFSv2 LINK argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 77edcdf91f6245a9881b84e4e101738148bd039a ]
--- fs/nfsd/nfsxdr.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
fs/nfsd/nfsxdr.c +4 -6
@@ -356,14 +356,12 @@ nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)int nfssvc_decode_linkargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd_linkargs *args = rqstp->rq_argp; -if (!(p =decode_fh (p, &args->ffh)) - || !(p =decode_fh (p, &args->tfh)) - || !(p =decode_filename (p, &args->tname, &args->tlen))) -return 0 ; - -return xdr_argsize_check (rqstp, p); +return svcxdr_decode_fhandle (xdr, &args->ffh) && +svcxdr_decode_diropargs (xdr, &args->tfh, + &args->tname, &args->tlen); }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 162/770 NFSD: Update the NFSv2 SETATTR argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 2fdd6bd293b9e7dda61220538b2759fbf06f5af0 ]
--- fs/nfsd/nfsxdr.c | 82 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 6 deletions(-)
fs/nfsd/nfsxdr.c +76 -6
@@ -173,6 +173,79 @@ decode_sattr(__be32 *p, struct iattr *iap, struct user_namespace *userns)return p; } +static bool +svcxdr_decode_sattr (struct svc_rqst *rqstp,struct xdr_stream *xdr, +struct iattr *iap) +{ +u32 tmp1, tmp2; +__be32 *p; + + p =xdr_inline_decode (xdr,XDR_UNIT *8 ); +if (!p) +return false; + + iap->ia_valid =0 ; + +/* +* Some Sun clients put 0xffff in the mode field when they +* mean 0xffffffff. +*/ + tmp1 =be32_to_cpup (p++); +if (tmp1 != (u32)-1 && tmp1 !=0xffff ) { + iap->ia_valid |=ATTR_MODE ; + iap->ia_mode = tmp1; + } + + tmp1 =be32_to_cpup (p++); +if (tmp1 != (u32)-1 ) { + iap->ia_uid =make_kuid (nfsd_user_namespace (rqstp), tmp1); +if (uid_valid (iap->ia_uid)) + iap->ia_valid |=ATTR_UID ; + } + + tmp1 =be32_to_cpup (p++); +if (tmp1 != (u32)-1 ) { + iap->ia_gid =make_kgid (nfsd_user_namespace (rqstp), tmp1); +if (gid_valid (iap->ia_gid)) + iap->ia_valid |=ATTR_GID ; + } + + tmp1 =be32_to_cpup (p++); +if (tmp1 != (u32)-1 ) { + iap->ia_valid |=ATTR_SIZE ; + iap->ia_size = tmp1; + } + + tmp1 =be32_to_cpup (p++); + tmp2 =be32_to_cpup (p++); +if (tmp1 != (u32)-1 && tmp2 != (u32)-1 ) { + iap->ia_valid |=ATTR_ATIME |ATTR_ATIME_SET ; + iap->ia_atime.tv_sec = tmp1; + iap->ia_atime.tv_nsec = tmp2 *NSEC_PER_USEC ; + } + + tmp1 =be32_to_cpup (p++); + tmp2 =be32_to_cpup (p++); +if (tmp1 != (u32)-1 && tmp2 != (u32)-1 ) { + iap->ia_valid |=ATTR_MTIME |ATTR_MTIME_SET ; + iap->ia_mtime.tv_sec = tmp1; + iap->ia_mtime.tv_nsec = tmp2 *NSEC_PER_USEC ; +/* +* Passing the invalid value useconds=1000000 for mtime +* is a Sun convention for "set both mtime and atime to +* current server time". It's needed to make permissions +* checks for the "touch" program across v2 mounts to +* Solaris and Irix boxes work correctly. See description of +* sattr in section 6.1 of "NFS Illustrated" by +* Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5 +*/ +if (tmp2 ==1000000 ) + iap->ia_valid &= ~(ATTR_ATIME_SET |ATTR_MTIME_SET ); + } + +return true; +} +static __be32 *encode_fattr (struct svc_rqst *rqstp,__be32 *p,struct svc_fh *fhp,struct kstat *stat)
@@ -253,14 +326,11 @@ nfssvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p)int nfssvc_decode_sattrargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd_sattrargs *args = rqstp->rq_argp; - p =decode_fh (p, &args->fh); -if (!p) -return 0 ; - p =decode_sattr (p, &args->attrs,nfsd_user_namespace (rqstp)); - -return xdr_argsize_check (rqstp, p); +return svcxdr_decode_fhandle (xdr, &args->fh) && +svcxdr_decode_sattr (rqstp, xdr, &args->attrs); }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 163/770 NFSD: Update the NFSv2 CREATE argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 7dcf65b91ecaf60ce593e7859ae2b29b7c46ccbd ]
--- fs/nfsd/nfsxdr.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
fs/nfsd/nfsxdr.c +4 -6
@@ -401,14 +401,12 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)int nfssvc_decode_createargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd_createargs *args = rqstp->rq_argp; -if ( !(p =decode_fh (p, &args->fh)) - || !(p =decode_filename (p, &args->name, &args->len))) -return 0 ; - p =decode_sattr (p, &args->attrs,nfsd_user_namespace (rqstp)); - -return xdr_argsize_check (rqstp, p); +return svcxdr_decode_diropargs (xdr, &args->fh, + &args->name, &args->len) && +svcxdr_decode_sattr (rqstp, xdr, &args->attrs); }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 164/770 NFSD: Update the NFSv2 SYMLINK argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 09f75a5375ac61f4adb94da0accc1cfc60eb4f2b ]
--- fs/nfsd/nfsxdr.c | 113 +++++------------------------------------------ 1 file changed, 10 insertions(+), 103 deletions(-)
fs/nfsd/nfsxdr.c +10 -103
@@ -66,26 +66,6 @@ encode_fh(__be32 *p, struct svc_fh *fhp)return p + (NFS_FHSIZE >>2 ); } -/* -* Decode a file name and make sure that the path contains -* no slashes or null bytes. -*/ -static __be32 * -decode_filename (__be32 *p,char **namp,unsigned int *lenp) -{ -char *name; -unsigned int i; - -if ((p =xdr_decode_string_inplace (p, namp, lenp,NFS_MAXNAMLEN )) !=NULL ) { -for (i =0 , name = *namp; i < *lenp; i++, name++) { -if (*name =='\0' || *name =='/' ) -return NULL ; - } - } - -return p; -} -static bool svcxdr_decode_filename (struct xdr_stream *xdr,char **name,unsigned int *len) {
@@ -118,61 +98,6 @@ svcxdr_decode_diropargs(struct xdr_stream *xdr, struct svc_fh *fhp,svcxdr_decode_filename (xdr, name, len); } -static __be32 * -decode_sattr (__be32 *p,struct iattr *iap,struct user_namespace *userns) -{ -u32 tmp, tmp1; - - iap->ia_valid =0 ; - -/* Sun client bug compatibility check: some sun clients seem to -* put 0xffff in the mode field when they mean 0xffffffff. -* Quoting the 4.4BSD nfs server code: Nah nah nah nah na nah. -*/ -if ((tmp =ntohl (*p++)) != (u32)-1 && tmp !=0xffff ) { - iap->ia_valid |=ATTR_MODE ; - iap->ia_mode = tmp; - } -if ((tmp =ntohl (*p++)) != (u32)-1 ) { - iap->ia_uid =make_kuid (userns, tmp); -if (uid_valid (iap->ia_uid)) - iap->ia_valid |=ATTR_UID ; - } -if ((tmp =ntohl (*p++)) != (u32)-1 ) { - iap->ia_gid =make_kgid (userns, tmp); -if (gid_valid (iap->ia_gid)) - iap->ia_valid |=ATTR_GID ; - } -if ((tmp =ntohl (*p++)) != (u32)-1 ) { - iap->ia_valid |=ATTR_SIZE ; - iap->ia_size = tmp; - } - tmp =ntohl (*p++); tmp1 =ntohl (*p++); -if (tmp != (u32)-1 && tmp1 != (u32)-1 ) { - iap->ia_valid |=ATTR_ATIME |ATTR_ATIME_SET ; - iap->ia_atime.tv_sec = tmp; - iap->ia_atime.tv_nsec = tmp1 *1000 ; - } - tmp =ntohl (*p++); tmp1 =ntohl (*p++); -if (tmp != (u32)-1 && tmp1 != (u32)-1 ) { - iap->ia_valid |=ATTR_MTIME |ATTR_MTIME_SET ; - iap->ia_mtime.tv_sec = tmp; - iap->ia_mtime.tv_nsec = tmp1 *1000 ; -/* -* Passing the invalid value useconds=1000000 for mtime -* is a Sun convention for "set both mtime and atime to -* current server time". It's needed to make permissions -* checks for the "touch" program across v2 mounts to -* Solaris and Irix boxes work correctly. See description of -* sattr in section 6.1 of "NFS Illustrated" by -* Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5 -*/ -if (tmp1 ==1000000 ) - iap->ia_valid &= ~(ATTR_ATIME_SET |ATTR_MTIME_SET ); - } -return p; -} -static bool svcxdr_decode_sattr (struct svc_rqst *rqstp,struct xdr_stream *xdr,struct iattr *iap)
@@ -435,40 +360,22 @@ nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p)int nfssvc_decode_symlinkargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd_symlinkargs *args = rqstp->rq_argp; -char *base = (char *)p; -size_t xdrlen; +struct kvec *head = rqstp->rq_arg.head; -if ( !(p =decode_fh (p, &args->ffh)) - || !(p =decode_filename (p, &args->fname, &args->flen))) +if (!svcxdr_decode_diropargs (xdr, &args->ffh, &args->fname, &args->flen)) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->tlen) <0 )return 0 ; - - args->tlen =ntohl (*p++);if (args->tlen ==0 )return 0 ; - args->first.iov_base = p; - args->first.iov_len = rqstp->rq_arg.head[0 ].iov_len; - args->first.iov_len -= (char *)p - base; - -/* This request is never larger than a page. Therefore, -* transport will deliver either: -* 1. pathname in the pagelist -> sattr is in the tail. -* 2. everything in the head buffer -> sattr is in the head. -*/ -if (rqstp->rq_arg.page_len) { -if (args->tlen != rqstp->rq_arg.page_len) -return 0 ; - p = rqstp->rq_arg.tail[0 ].iov_base; - }else { - xdrlen =XDR_QUADLEN (args->tlen); -if (xdrlen > args->first.iov_len - (8 *sizeof (__be32))) -return 0 ; - p += xdrlen; - } -decode_sattr (p, &args->attrs,nfsd_user_namespace (rqstp)); - -return 1 ; + args->first.iov_len = head->iov_len -xdr_stream_pos (xdr); + args->first.iov_base =xdr_inline_decode (xdr, args->tlen); +if (!args->first.iov_base) +return 0 ; +return svcxdr_decode_sattr (rqstp, xdr, &args->attrs); }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 165/770 NFSD: Remove argument length checking in nfsd_dispatch()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 5650682e16f41722f735b7beeb2dbc3411dfbeb6 ]
Now that the argument decoders for NFSv2 and NFSv3 use the xdr_stream mechanism, the version-specific length checking logic in nfsd_dispatch() is no longer necessary.
--- fs/nfsd/nfssvc.c | 34 ---------------------------------- 1 file changed, 34 deletions(-)
fs/nfsd/nfssvc.c +0 -34
@@ -988,37 +988,6 @@ nfsd(void *vrqstp)return 0 ; } -/* -* A write procedure can have a large argument, and a read procedure can -* have a large reply, but no NFSv2 or NFSv3 procedure has argument and -* reply that can both be larger than a page. The xdr code has taken -* advantage of this assumption to be a sloppy about bounds checking in -* some cases. Pending a rewrite of the NFSv2/v3 xdr code to fix that -* problem, we enforce these assumptions here: -*/ -static bool nfs_request_too_big (struct svc_rqst *rqstp, -const struct svc_procedure *proc) -{ -/* -* The ACL code has more careful bounds-checking and is not -* susceptible to this problem: -*/ -if (rqstp->rq_prog !=NFS_PROGRAM ) -return false; -/* -* Ditto NFSv4 (which can in theory have argument and reply both -* more than a page): -*/ -if (rqstp->rq_vers >=4 ) -return false; -/* The reply will be small, we're OK: */ -if (proc->pc_xdrressize >0 && - proc->pc_xdrressize <XDR_QUADLEN (PAGE_SIZE )) -return false; - -return rqstp->rq_arg.len >PAGE_SIZE ; -} -/** * nfsd_dispatch - Process an NFS or NFSACL Request * @rqstp: incoming request
@@ -1037,9 +1006,6 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)struct kvec *resv = &rqstp->rq_res.head[0 ];__be32 *p; -if (nfs_request_too_big (rqstp, proc)) - goto out_decode_err; -/* * Give the xdr decoder a chance to change this if it wants * (necessary in the NFSv4.0 compound case)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 166/770 NFSD: Update the NFSv2 GETACL argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 635a45d34706400c59c3b18ca9fccba195147bda ]
--- fs/nfsd/nfs2acl.c | 10 +++++----- fs/nfsd/nfsxdr.c | 11 ++++++++++- fs/nfsd/xdr.h | 1 + fs/nfsd/xdr3.h | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-)
fs/nfsd/nfs2acl.c +5 -5
@@ -188,17 +188,17 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp)static int nfsaclsvc_decode_getaclargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_getaclargs *argp = rqstp->rq_argp; - p =nfs2svc_decode_fh (p, &argp->fh); -if (!p) +if (!svcxdr_decode_fhandle (xdr, &argp->fh)) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &argp->mask) <0 )return 0 ; - argp->mask =ntohl (*p); p++; -return xdr_argsize_check (rqstp, p); +return 1 ; } -static int nfsaclsvc_decode_setaclargs (struct svc_rqst *rqstp,__be32 *p) {struct nfsd3_setaclargs *argp = rqstp->rq_argp;
fs/nfsd/nfsxdr.c +10 -1
@@ -38,7 +38,16 @@ decode_fh(__be32 *p, struct svc_fh *fhp)return p + (NFS_FHSIZE >>2 ); } -static bool +/** +* svcxdr_decode_fhandle - Decode an NFSv2 file handle +* @xdr: XDR stream positioned at an encoded NFSv2 FH +* @fhp: OUT: filled-in server file handle +* +* Return values: +* %false: The encoded file handle was not valid +* %true: @fhp has been initialized +*/ +bool svcxdr_decode_fhandle (struct xdr_stream *xdr,struct svc_fh *fhp) {__be32 *p;
fs/nfsd/xdr.h +1 -0
@@ -165,5 +165,6 @@ void nfssvc_release_readres(struct svc_rqst *rqstp);/* Helper functions for NFSv2 ACL code */ __be32 *nfs2svc_encode_fattr (struct svc_rqst *rqstp,__be32 *p,struct svc_fh *fhp,struct kstat *stat);__be32 *nfs2svc_decode_fh (__be32 *p,struct svc_fh *fhp); +bool svcxdr_decode_fhandle (struct xdr_stream *xdr,struct svc_fh *fhp);#endif /* LINUX_NFSD_H */
fs/nfsd/xdr3.h +1 -1
@@ -102,7 +102,7 @@ struct nfsd3_commitargs {struct nfsd3_getaclargs {struct svc_fh fh; -int mask; +__u32 mask; };struct posix_acl ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 167/770 NFSD: Add an xdr_stream-based decoder for NFSv2/3 ACLs
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 6bb844b4eb6e3b109a2fdaffb60e6da722dc4356 ]
--- fs/nfs_common/nfsacl.c | 52 ++++++++++++++++++++++++++++++++++++++++++ include/linux/nfsacl.h | 3 +++ 2 files changed, 55 insertions(+)
fs/nfs_common/nfsacl.c +52 -0
@@ -295,3 +295,55 @@ int nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt, nfsacl_desc.desc.array_len; }EXPORT_SYMBOL_GPL (nfsacl_decode); + +/** +* nfs_stream_decode_acl - Decode an NFSv3 ACL +* +* @xdr: an xdr_stream positioned at an encoded ACL +* @aclcnt: OUT: count of ACEs in decoded posix_acl +* @pacl: OUT: a dynamically-allocated buffer containing the decoded posix_acl +* +* Return values: +* %false: The encoded ACL is not valid +* %true: @pacl contains a decoded ACL, and @xdr is advanced +* +* On a successful return, caller must release *pacl using posix_acl_release(). +*/ +bool nfs_stream_decode_acl (struct xdr_stream *xdr,unsigned int *aclcnt, +struct posix_acl **pacl) +{ +const size_t elem_size =XDR_UNIT *3 ; +struct nfsacl_decode_desc nfsacl_desc = { + .desc = { + .elem_size = elem_size, + .xcode = pacl ? xdr_nfsace_decode :NULL , + }, + }; +unsigned int base; +u32 entries; + +if (xdr_stream_decode_u32 (xdr, &entries) <0 ) +return false; +if (entries >NFS_ACL_MAX_ENTRIES ) +return false; + + base =xdr_stream_pos (xdr); +if (!xdr_inline_decode (xdr,XDR_UNIT + elem_size * entries)) +return false; + nfsacl_desc.desc.array_maxlen = entries; +if (xdr_decode_array2 (xdr->buf, base, &nfsacl_desc.desc)) +return false; + +if (pacl) { +if (entries != nfsacl_desc.desc.array_len || +posix_acl_from_nfsacl (nfsacl_desc.acl) !=0 ) { +posix_acl_release (nfsacl_desc.acl); +return false; + } + *pacl = nfsacl_desc.acl; + } +if (aclcnt) + *aclcnt = entries; +return true; +} +EXPORT_SYMBOL_GPL (nfs_stream_decode_acl);
include/linux/nfsacl.h +3 -0
@@ -38,5 +38,8 @@ nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,extern int nfsacl_decode (struct xdr_buf *buf,unsigned int base,unsigned int *aclcnt,struct posix_acl **pacl); +extern bool +nfs_stream_decode_acl (struct xdr_stream *xdr,unsigned int *aclcnt, +struct posix_acl **pacl);#endif /* __LINUX_NFSACL_H */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 168/770 NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 427eab3ba22891845265f9a3846de6ac152ec836 ]
--- fs/nfsd/nfs2acl.c | 29 ++++++++++++----------------- fs/nfsd/xdr3.h | 2 +- 2 files changed, 13 insertions(+), 18 deletions(-)
fs/nfsd/nfs2acl.c +12 -17
@@ -201,28 +201,23 @@ static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p)static int nfsaclsvc_decode_setaclargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_setaclargs *argp = rqstp->rq_argp; -struct kvec *head = rqstp->rq_arg.head; -unsigned int base; -int n; - p =nfs2svc_decode_fh (p, &argp->fh); -if (!p) +if (!svcxdr_decode_fhandle (xdr, &argp->fh)) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &argp->mask) <0 ) +return 0 ; +if (argp->mask & ~NFS_ACL_MASK )return 0 ; - argp->mask =ntohl (*p++); -if (argp->mask & ~NFS_ACL_MASK || - !xdr_argsize_check (rqstp, p)) +if (!nfs_stream_decode_acl (xdr,NULL , (argp->mask &NFS_ACL ) ? + &argp->acl_access :NULL )) +return 0 ; +if (!nfs_stream_decode_acl (xdr,NULL , (argp->mask &NFS_DFACL ) ? + &argp->acl_default :NULL ))return 0 ; - base = (char *)p - (char *)head->iov_base; - n =nfsacl_decode (&rqstp->rq_arg, base,NULL , - (argp->mask &NFS_ACL ) ? - &argp->acl_access :NULL ); -if (n >0 ) - n =nfsacl_decode (&rqstp->rq_arg, base + n,NULL , - (argp->mask &NFS_DFACL ) ? - &argp->acl_default :NULL ); -return (n >0 ); +return 1 ; }static int nfsaclsvc_decode_fhandleargs (struct svc_rqst *rqstp,__be32 *p)
fs/nfsd/xdr3.h +1 -1
@@ -108,7 +108,7 @@ struct nfsd3_getaclargs {struct posix_acl ;struct nfsd3_setaclargs {struct svc_fh fh; -int mask; +__u32 mask;struct posix_acl *acl_access;struct posix_acl *acl_default; };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 169/770 NFSD: Update the NFSv2 ACL GETATTR argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 571d31f37a57729c9d3463b5a692a84e619b408a ]
Since the ACL GETATTR procedure is the same as the normal GETATTR procedure, simply re-use nfssvc_decode_fhandleargs.
--- fs/nfsd/nfs2acl.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
fs/nfsd/nfs2acl.c +1 -11
@@ -220,16 +220,6 @@ static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p)return 1 ; } -static int nfsaclsvc_decode_fhandleargs (struct svc_rqst *rqstp,__be32 *p) -{ -struct nfsd_fhandle *argp = rqstp->rq_argp; - - p =nfs2svc_decode_fh (p, &argp->fh); -if (!p) -return 0 ; -return xdr_argsize_check (rqstp, p); -} -static int nfsaclsvc_decode_accessargs (struct svc_rqst *rqstp,__be32 *p) {struct nfsd3_accessargs *argp = rqstp->rq_argp;
@@ -392,7 +382,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = { }, [ACLPROC2_GETATTR] = { .pc_func = nfsacld_proc_getattr, - .pc_decode = nfsaclsvc_decode_fhandleargs, + .pc_decode = nfssvc_decode_fhandleargs, .pc_encode = nfsaclsvc_encode_attrstatres, .pc_release = nfsaclsvc_release_attrstat, .pc_argsize = sizeof(struct nfsd_fhandle),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 170/770 NFSD: Update the NFSv2 ACL ACCESS argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 64063892efc1daa3a48882673811ff327ba75ed5 ]
--- fs/nfsd/nfs2acl.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
fs/nfsd/nfs2acl.c +6 -5
@@ -222,14 +222,15 @@ static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p)static int nfsaclsvc_decode_accessargs (struct svc_rqst *rqstp,__be32 *p) { -struct nfsd3_accessargs *argp = rqstp->rq_argp; +struct xdr_stream *xdr = &rqstp->rq_arg_stream; +struct nfsd3_accessargs *args = rqstp->rq_argp; - p =nfs2svc_decode_fh (p, &argp->fh); -if (!p) +if (!svcxdr_decode_fhandle (xdr, &args->fh)) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->access) <0 )return 0 ; - argp->access =ntohl (*p++); -return xdr_argsize_check (rqstp, p); +return 1 ; }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 171/770 NFSD: Clean up after updating NFSv2 ACL decoders
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit baadce65d6ee3032b921d9c043ba808bc69d6b13 ]
--- fs/nfsd/nfsxdr.c | 18 ------------------ fs/nfsd/xdr.h | 1 - 2 files changed, 19 deletions(-)
fs/nfsd/nfsxdr.c +0 -18
@@ -26,18 +26,6 @@ static u32 nfs_ftypes[] = {* Basic NFSv2 data types (RFC 1094 Section 2.3) */ -static __be32 * -decode_fh (__be32 *p,struct svc_fh *fhp) -{ -fh_init (fhp,NFS_FHSIZE ); -memcpy (&fhp->fh_handle.fh_base, p,NFS_FHSIZE ); - fhp->fh_handle.fh_size =NFS_FHSIZE ; - -/* FIXME: Look up export pointer here and verify -* Sun Secure RPC if requested */ -return p + (NFS_FHSIZE >>2 ); -} -/** * svcxdr_decode_fhandle - Decode an NFSv2 file handle * @xdr: XDR stream positioned at an encoded NFSv2 FH
@@ -62,12 +50,6 @@ svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp)return true; } -/* Helper function for NFSv2 ACL code */ -__be32 *nfs2svc_decode_fh (__be32 *p,struct svc_fh *fhp) -{ -return decode_fh (p, fhp); -} -static __be32 *encode_fh (__be32 *p,struct svc_fh *fhp) {
fs/nfsd/xdr.h +0 -1
@@ -164,7 +164,6 @@ void nfssvc_release_readres(struct svc_rqst *rqstp);/* Helper functions for NFSv2 ACL code */ __be32 *nfs2svc_encode_fattr (struct svc_rqst *rqstp,__be32 *p,struct svc_fh *fhp,struct kstat *stat); -__be32 *nfs2svc_decode_fh (__be32 *p,struct svc_fh *fhp);bool svcxdr_decode_fhandle (struct xdr_stream *xdr,struct svc_fh *fhp);#endif /* LINUX_NFSD_H */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 172/770 NFSD: Update the NFSv3 GETACL argument decoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 05027eafc266487c6e056d10ab352861df95b5d4 ]
--- fs/nfsd/nfs3acl.c | 11 ++++++----- fs/nfsd/nfs3xdr.c | 11 ++++++++++- fs/nfsd/xdr3.h | 1 + 3 files changed, 17 insertions(+), 6 deletions(-)
fs/nfsd/nfs3acl.c +6 -5
@@ -124,19 +124,20 @@ static __be32 nfsd3_proc_setacl(struct svc_rqst *rqstp)/* * XDR decode functions */ +static int nfs3svc_decode_getaclargs (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_arg_stream;struct nfsd3_getaclargs *args = rqstp->rq_argp; - p =nfs3svc_decode_fh (p, &args->fh); -if (!p) +if (!svcxdr_decode_nfs_fh3 (xdr, &args->fh)) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &args->mask) <0 )return 0 ; - args->mask =ntohl (*p); p++; -return xdr_argsize_check (rqstp, p); +return 1 ; } -static int nfs3svc_decode_setaclargs (struct svc_rqst *rqstp,__be32 *p) {struct nfsd3_setaclargs *args = rqstp->rq_argp;
fs/nfsd/nfs3xdr.c +10 -1
@@ -53,7 +53,16 @@ svcxdr_decode_nfstime3(struct xdr_stream *xdr, struct timespec64 *timep)return true; } -static bool +/** +* svcxdr_decode_nfs_fh3 - Decode an NFSv3 file handle +* @xdr: XDR stream positioned at an undecoded NFSv3 FH +* @fhp: OUT: filled-in server file handle +* +* Return values: +* %false: The encoded file handle was not valid +* %true: @fhp has been initialized +*/ +bool svcxdr_decode_nfs_fh3 (struct xdr_stream *xdr,struct svc_fh *fhp) {__be32 *p;
fs/nfsd/xdr3.h +1 -0
@@ -308,6 +308,7 @@ int nfs3svc_encode_entry_plus(void *, const char *name,__be32 *nfs3svc_encode_post_op_attr (struct svc_rqst *rqstp,__be32 *p,struct svc_fh *fhp);__be32 *nfs3svc_decode_fh (__be32 *p,struct svc_fh *fhp); +bool svcxdr_decode_nfs_fh3 (struct xdr_stream *xdr,struct svc_fh *fhp);#endif /* _LINUX_NFSD_XDR3_H */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 173/770 NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream, again
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 68519ff2a1c72c67fcdc4b81671acda59f420af9 ]
--- fs/nfsd/nfs3acl.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-)
fs/nfsd/nfs3acl.c +13 -18
@@ -140,28 +140,23 @@ static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p)static int nfs3svc_decode_setaclargs (struct svc_rqst *rqstp,__be32 *p) { -struct nfsd3_setaclargs *args = rqstp->rq_argp; -struct kvec *head = rqstp->rq_arg.head; -unsigned int base; -int n; +struct xdr_stream *xdr = &rqstp->rq_arg_stream; +struct nfsd3_setaclargs *argp = rqstp->rq_argp; - p =nfs3svc_decode_fh (p, &args->fh); -if (!p) +if (!svcxdr_decode_nfs_fh3 (xdr, &argp->fh)) +return 0 ; +if (xdr_stream_decode_u32 (xdr, &argp->mask) <0 )return 0 ; - args->mask =ntohl (*p++); -if (args->mask & ~NFS_ACL_MASK || - !xdr_argsize_check (rqstp, p)) +if (argp->mask & ~NFS_ACL_MASK ) +return 0 ; +if (!nfs_stream_decode_acl (xdr,NULL , (argp->mask &NFS_ACL ) ? + &argp->acl_access :NULL )) +return 0 ; +if (!nfs_stream_decode_acl (xdr,NULL , (argp->mask &NFS_DFACL ) ? + &argp->acl_default :NULL ))return 0 ; - base = (char *)p - (char *)head->iov_base; - n =nfsacl_decode (&rqstp->rq_arg, base,NULL , - (args->mask &NFS_ACL ) ? - &args->acl_access :NULL ); -if (n >0 ) - n =nfsacl_decode (&rqstp->rq_arg, base + n,NULL , - (args->mask &NFS_DFACL ) ? - &args->acl_default :NULL ); -return (n >0 ); +return 1 ; }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 174/770 NFSD: Clean up after updating NFSv3 ACL decoders
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 9cee763ee654ce8622d673b8e32687d738e24ace ]
--- fs/nfsd/nfs3xdr.c | 20 -------------------- fs/nfsd/xdr3.h | 2 -- 2 files changed, 22 deletions(-)
fs/nfsd/nfs3xdr.c +0 -20
@@ -82,26 +82,6 @@ svcxdr_decode_nfs_fh3(struct xdr_stream *xdr, struct svc_fh *fhp)return true; } -static __be32 * -decode_fh (__be32 *p,struct svc_fh *fhp) -{ -unsigned int size; -fh_init (fhp,NFS3_FHSIZE ); - size =ntohl (*p++); -if (size >NFS3_FHSIZE ) -return NULL ; - -memcpy (&fhp->fh_handle.fh_base, p, size); - fhp->fh_handle.fh_size = size; -return p +XDR_QUADLEN (size); -} - -/* Helper function for NFSv3 ACL code */ -__be32 *nfs3svc_decode_fh (__be32 *p,struct svc_fh *fhp) -{ -return decode_fh (p, fhp); -} -static __be32 *encode_fh (__be32 *p,struct svc_fh *fhp) {
fs/nfsd/xdr3.h +0 -2
@@ -307,8 +307,6 @@ int nfs3svc_encode_entry_plus(void *, const char *name,/* Helper functions for NFSv3 ACL code */ __be32 *nfs3svc_encode_post_op_attr (struct svc_rqst *rqstp,__be32 *p,struct svc_fh *fhp); -__be32 *nfs3svc_decode_fh (__be32 *p,struct svc_fh *fhp);bool svcxdr_decode_nfs_fh3 (struct xdr_stream *xdr,struct svc_fh *fhp); -#endif /* _LINUX_NFSD_XDR3_H */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 175/770 nfsd: remove unused stats counters
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
[ Upstream commit 1b76d1df1a3683b6b23cd1c813d13c5e6a9d35e5 ]
Commit 501cb1849f86 ("nfsd: rip out the raparms cache") removed the code that updates read-ahead cache stats counters,
commit 8bbfa9f3889b ("knfsd: remove the nfsd thread busy histogram") removed code that updates the thread busy stats counters back in 2009 and code that updated filehandle cache stats was removed back in 2002.
Remove the unused stats counters from nfsd_stats struct and print hardcoded zeros in /proc/net/rpc/nfsd.
--- fs/nfsd/stats.c | 41 ++++++++++++++++------------------------- fs/nfsd/stats.h | 10 ---------- 2 files changed, 16 insertions(+), 35 deletions(-)
fs/nfsd/stats.c +16 -25
@@ -7,16 +7,14 @@* Format: * rc <hits> <misses> <nocache> * Statistsics for the reply cache -* fh <stale> <total-lookups> <anonlookups> <dir-not-in-dcache> <nondir-not-in-dcache> +* fh <stale> <deprecated filehandle cache stats> * statistics for filehandle lookup * io <bytes-read> <bytes-written> * statistics for IO throughput -* th <threads> <fullcnt> <10%-20%> <20%-30%> ... <90%-100%> <100%> -* time (seconds) when nfsd thread usage above thresholds -* and number of times that all threads were in use -* ra cache-size <10% <20% <30% ... <100% not-found -* number of times that read-ahead entry was found that deep in -* the cache. +* th <threads> <deprecated thread usage histogram stats> +* number of threads +* ra <deprecated ra-cache stats> +* * plus generic RPC stats (see net/sunrpc/stats.c) * * Copyright (C) 1995, 1996, 1997 Olaf Kirch <[email protected]>
@@ -38,31 +36,24 @@ static int nfsd_proc_show(struct seq_file *seq, void *v) {int i; -seq_printf (seq,"rc %u %u %u\nfh %u %u %u %u %u\nio %u %u\n" , +seq_printf (seq,"rc %u %u %u\nfh %u 0 0 0 0\nio %u %u\n" , nfsdstats.rchits, nfsdstats.rcmisses, nfsdstats.rcnocache, nfsdstats.fh_stale, - nfsdstats.fh_lookup, - nfsdstats.fh_anon, - nfsdstats.fh_nocache_dir, - nfsdstats.fh_nocache_nondir, nfsdstats.io_read, nfsdstats.io_write); +/* thread usage: */ -seq_printf (seq,"th %u %u" , nfsdstats.th_cnt, nfsdstats.th_fullcnt); -for (i=0 ; i<10 ; i++) { -unsigned int jifs = nfsdstats.th_usage[i]; -unsigned int sec = jifs /HZ , msec = (jifs %HZ )*1000 /HZ ; -seq_printf (seq," %u.%03u" , sec, msec); - } - -/* newline and ra-cache */ -seq_printf (seq,"\nra %u" , nfsdstats.ra_size); -for (i=0 ; i<11 ; i++) -seq_printf (seq," %u" , nfsdstats.ra_depth[i]); -seq_putc (seq,'\n' ); - +seq_printf (seq,"th %u 0" , nfsdstats.th_cnt); + +/* deprecated thread usage histogram stats */ +for (i =0 ; i <10 ; i++) +seq_puts (seq," 0.000" ); + +/* deprecated ra-cache stats */ +seq_puts (seq,"\nra 0 0 0 0 0 0 0 0 0 0 0 0\n" ); +/* show my rpc info */ svc_seq_show (seq, &nfsd_svcstats);
fs/nfsd/stats.h +0 -10
@@ -15,19 +15,9 @@ struct nfsd_stats {unsigned int rcmisses;/* repcache hits */ unsigned int rcnocache;/* uncached reqs */ unsigned int fh_stale;/* FH stale error */ -unsigned int fh_lookup;/* dentry cached */ -unsigned int fh_anon;/* anon file dentry returned */ -unsigned int fh_nocache_dir;/* filehandle not found in dcache */ -unsigned int fh_nocache_nondir;/* filehandle not found in dcache */ unsigned int io_read;/* bytes returned to read requests */ unsigned int io_write;/* bytes passed in write requests */ unsigned int th_cnt;/* number of available threads */ -unsigned int th_usage[10 ];/* number of ticks during which n perdeciles -* of available threads were in use */ -unsigned int th_fullcnt;/* number of times last free thread was used */ -unsigned int ra_size;/* size of ra cache */ -unsigned int ra_depth[11 ];/* number of times ra entry was found that deep -* in the cache (10percentiles). [10] = not found */ #ifdef CONFIG_NFSD_V4 unsigned int nfs4_opcount[LAST_NFS4_OP +1 ];/* count of individual nfsv4 operations */ #endif
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 176/770 nfsd: protect concurrent access to nfsd stats counters
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
[ Upstream commit e567b98ce9a4b35b63c364d24828a9e5cd7a8179 ]
nfsd stats counters can be updated by concurrent nfsd threads without any protection.
Convert some nfsd_stats and nfsd_net struct members to use percpu counters.
The longest_chain* members of struct nfsd_net remain unprotected.
--- fs/nfsd/netns.h | 23 +++++++------ fs/nfsd/nfs4proc.c | 2 +- fs/nfsd/nfscache.c | 52 +++++++++++++++++++++--------- fs/nfsd/nfsctl.c | 5 ++- fs/nfsd/nfsfh.c | 2 +- fs/nfsd/stats.c | 77 ++++++++++++++++++++++++++++++++++++-------- fs/nfsd/stats.h | 80 +++++++++++++++++++++++++++++++++++++++------- fs/nfsd/vfs.c | 4 +-- 8 files changed, 192 insertions(+), 53 deletions(-)
fs/nfsd/netns.h +14 -9
@@ -10,6 +10,7 @@#include <net/net_namespace.h> #include <net/netns/generic.h> +#include <linux/percpu_counter.h> /* Hash tables for nfs4_clientid state */ #define CLIENT_HASH_BITS 4
@@ -21,6 +22,14 @@struct cld_net ;struct nfsd4_client_tracking_ops ; +enum { +/* cache misses due only to checksum comparison failures */ +NFSD_NET_PAYLOAD_MISSES , +/* amount of memory (in bytes) currently consumed by the DRC */ +NFSD_NET_DRC_MEM_USAGE , +NFSD_NET_COUNTERS_NUM +}; +/* * Represents a nfsd "container". With respect to nfsv4 state tracking, the * fields of interest are the *_id_hashtbls and the *_name_tree. These track
@@ -149,20 +158,16 @@ struct nfsd_net {/* * Stats and other tracking of on the duplicate reply cache. -* These fields and the "rc" fields in nfsdstats are modified -* with only the per-bucket cache lock, which isn't really safe -* and should be fixed if we want the statistics to be -* completely accurate. +* The longest_chain* fields are modified with only the per-bucket +* cache lock, which isn't really safe and should be fixed if we want +* these statistics to be completely accurate. */ /* total number of entries */ atomic_t num_drc_entries; -/* cache misses due only to checksum comparison failures */ -unsigned int payload_misses; - -/* amount of memory (in bytes) currently consumed by the DRC */ -unsigned int drc_mem_usage; +/* Per-netns stats counters */ +struct percpu_counter counter[NFSD_NET_COUNTERS_NUM ];/* longest hash chain seen */ unsigned int longest_chain;
fs/nfsd/nfs4proc.c +1 -1
@@ -2168,7 +2168,7 @@ nfsd4_proc_null(struct svc_rqst *rqstp)static inline void nfsd4_increment_op_stats (u32 opnum) {if (opnum >=FIRST_NFS4_OP && opnum <=LAST_NFS4_OP ) - nfsdstats.nfs4_opcount[opnum]++; +percpu_counter_inc (&nfsdstats.counter[NFSD_STATS_NFS4_OP (opnum)]); }static const struct nfsd4_operation nfsd4_ops[];
fs/nfsd/nfscache.c +37 -15
134 lines not on this page · raw message
fs/nfsd/nfsctl.c +4 -1
@@ -1522,7 +1522,9 @@ static int __init init_nfsd(void) retval =nfsd4_init_pnfs ();if (retval) goto out_free_slabs; -nfsd_stat_init ();/* Statistics */ + retval =nfsd_stat_init ();/* Statistics */ +if (retval) + goto out_free_pnfs; retval =nfsd_drc_slab_create ();if (retval) goto out_free_stat;
@@ -1552,6 +1554,7 @@ static int __init init_nfsd(void)nfsd_drc_slab_free (); out_free_stat:nfsd_stat_shutdown (); +out_free_pnfs:nfsd4_exit_pnfs (); out_free_slabs:nfsd4_free_slabs ();
fs/nfsd/nfsfh.c +1 -1
@@ -422,7 +422,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) } out:if (error == nfserr_stale) - nfsdstats.fh_stale++; +nfsd_stats_fh_stale_inc ();return error; }
fs/nfsd/stats.c +64 -13
99 lines not on this page · raw message
fs/nfsd/stats.h +69 -11
96 lines not on this page · raw message
fs/nfsd/vfs.c +2 -2
@@ -897,7 +897,7 @@ static __be32 nfsd_finish_read(struct svc_rqst *rqstp, struct svc_fh *fhp, unsigned long *count, u32 *eof, ssize_t host_err) { if (host_err >= 0) { - nfsdstats.io_read += host_err; +nfsd_stats_io_read_add (host_err ); *eof =nfsd_eof_on_read (file, offset, host_err, *count); *count = host_err;fsnotify_access (file);
@@ -1050,7 +1050,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, goto out_nfserr; } *cnt = host_err; - nfsdstats.io_write += *cnt; +nfsd_stats_io_write_add (*cnt);fsnotify_modify (file); host_err =filemap_check_wb_err (file->f_mapping, since);if (host_err <0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 177/770 nfsd: report per-export stats
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
[ Upstream commit 20ad856e47323e208ae8d6a9ecfe5bf0be6f505e ]
Collect some nfsd stats per export in addition to the global stats.
A new nfsdfs export_stats file is created. It uses the same ops as the exports file to iterate the export entries and we use the file's name to determine the reported info per export. For example:
$ cat /proc/fs/nfsd/export_stats # Version 1.1 # Path Client Start-time # Stats /test localhost 92 fh_stale: 0 io_read: 9 io_write: 1
Every export entry reports the start time when stats collection started, so stats collecting scripts can know if stats where reset between samples.
--- fs/nfsd/export.c | 68 ++++++++++++++++++++++++++++++++++++++++++------ fs/nfsd/export.h | 15 +++++++++++ fs/nfsd/nfsctl.c | 3 +++ fs/nfsd/nfsd.h | 2 +- fs/nfsd/nfsfh.c | 4 +-- fs/nfsd/stats.h | 12 ++++++--- fs/nfsd/vfs.c | 4 +-- 7 files changed, 92 insertions(+), 16 deletions(-)
fs/nfsd/export.c +60 -8
@@ -331,12 +331,29 @@ static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc) fsloc->locations =NULL ; } +static int export_stats_init (struct export_stats *stats) +{ + stats->start_time =ktime_get_seconds (); +return nfsd_percpu_counters_init (stats->counter,EXP_STATS_COUNTERS_NUM ); +} + +static void export_stats_reset (struct export_stats *stats) +{ +nfsd_percpu_counters_reset (stats->counter,EXP_STATS_COUNTERS_NUM ); +} + +static void export_stats_destroy (struct export_stats *stats) +{ +nfsd_percpu_counters_destroy (stats->counter,EXP_STATS_COUNTERS_NUM ); +} +static void svc_export_put (struct kref *ref) { struct svc_export *exp = container_of(ref, struct svc_export, h.ref);path_put (&exp->ex_path);auth_domain_put (exp->ex_client);nfsd4_fslocs_free (&exp->ex_fslocs); +export_stats_destroy (&exp->ex_stats);kfree (exp->ex_uuid);kfree_rcu (exp, ex_rcu); }
@@ -692,22 +709,47 @@ static void exp_flags(struct seq_file *m, int flag, int fsid, kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fslocs);static void show_secinfo (struct seq_file *m,struct svc_export *exp); +static int is_export_stats_file (struct seq_file *m) +{ +/* +* The export_stats file uses the same ops as the exports file. +* We use the file's name to determine the reported info per export. +* There is no rename in nsfdfs, so d_name.name is stable. +*/ +return !strcmp (m->file->f_path.dentry->d_name.name,"export_stats" ); +} +static int svc_export_show (struct seq_file *m,struct cache_detail *cd,struct cache_head *h) { -struct svc_export *exp ; +struct svc_export *exp; +bool export_stats =is_export_stats_file (m); -if (h ==NULL ) { -seq_puts (m,"#path domain(flags)\n" ); +if (h ==NULL ) { +if (export_stats) +seq_puts (m,"#path domain start-time\n#\tstats\n" ); +else +seq_puts (m,"#path domain(flags)\n" );return 0 ; } exp = container_of(h, struct svc_export, h);seq_path (m, &exp->ex_path," \t\n\\" );seq_putc (m,'\t' );seq_escape (m, exp->ex_client->name," \t\n\\" ); +if (export_stats) { +seq_printf (m,"\t%lld\n" , exp->ex_stats.start_time); +seq_printf (m,"\tfh_stale: %lld\n" , +percpu_counter_sum_positive (&exp->ex_stats.counter[EXP_STATS_FH_STALE ])); +seq_printf (m,"\tio_read: %lld\n" , +percpu_counter_sum_positive (&exp->ex_stats.counter[EXP_STATS_IO_READ ])); +seq_printf (m,"\tio_write: %lld\n" , +percpu_counter_sum_positive (&exp->ex_stats.counter[EXP_STATS_IO_WRITE ])); +seq_putc (m,'\n' ); +return 0 ; + }seq_putc (m,'(' ); -if (test_bit (CACHE_VALID , &h->flags) && +if (test_bit (CACHE_VALID , &h->flags) && !test_bit (CACHE_NEGATIVE , &h->flags)) {exp_flags (m, exp->ex_flags, exp->ex_fsid, exp->ex_anon_uid, exp->ex_anon_gid, &exp->ex_fslocs);
@@ -748,6 +790,7 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem) new->ex_layout_types =0 ; new->ex_uuid =NULL ; new->cd = item->cd; +export_stats_reset (&new->ex_stats); }static void export_update (struct cache_head *cnew,struct cache_head *citem)
@@ -780,10 +823,15 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)static struct cache_head *svc_export_alloc (void ) {struct svc_export *i =kmalloc (sizeof (*i),GFP_KERNEL ); -if (i) -return &i->h; -else +if (!i) +return NULL ; + +if (export_stats_init (&i->ex_stats)) { +kfree (i);return NULL ; + } + +return &i->h; }static const struct cache_detail svc_export_cache_template = {
@@ -1245,10 +1293,14 @@ static int e_show(struct seq_file *m, void *p)struct cache_head *cp = p; struct svc_export *exp = container_of(cp, struct svc_export, h);struct cache_detail *cd = m->private; +bool export_stats =is_export_stats_file (m);if (p ==SEQ_START_TOKEN ) {seq_puts (m,"# Version 1.1\n" ); -seq_puts (m,"# Path Client(Flags) # IPs\n" ); +if (export_stats) +seq_puts (m,"# Path Client Start-time\n#\tStats\n" ); +else +seq_puts (m,"# Path Client(Flags) # IPs\n" );return 0 ; }
fs/nfsd/export.h +15 -0
@@ -6,6 +6,7 @@#define NFSD_EXPORT_H #include <linux/sunrpc/cache.h> +#include <linux/percpu_counter.h> #include <uapi/linux/nfsd/export.h> #include <linux/nfs4.h>
@@ -46,6 +47,19 @@ struct exp_flavor_info {u32 flags; }; +/* Per-export stats */ +enum { +EXP_STATS_FH_STALE , +EXP_STATS_IO_READ , +EXP_STATS_IO_WRITE , +EXP_STATS_COUNTERS_NUM +}; + +struct export_stats { +time64_t start_time; +struct percpu_counter counter[EXP_STATS_COUNTERS_NUM ]; +}; +struct svc_export {struct cache_head h;struct auth_domain * ex_client;
@@ -62,6 +76,7 @@ struct svc_export {struct nfsd4_deviceid_map *ex_devid_map;struct cache_detail *cd;struct rcu_head ex_rcu; +struct export_stats ex_stats; };/* an "export key" (expkey) maps a filehandlefragement to an
fs/nfsd/nfsctl.c +3 -0
@@ -32,6 +32,7 @@enum { NFSD_Root =1 , NFSD_List, + NFSD_Export_Stats, NFSD_Export_features, NFSD_Fh, NFSD_FO_UnlockIP,
@@ -1352,6 +1353,8 @@ static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc)static const struct tree_descr nfsd_files[] = { [NFSD_List] = {"exports" , &exports_nfsd_operations,S_IRUGO }, +/* Per-export io stats use same ops as exports file */ + [NFSD_Export_Stats] = {"export_stats" , &exports_nfsd_operations,S_IRUGO }, [NFSD_Export_features] = {"export_features" , &export_features_operations,S_IRUGO }, [NFSD_FO_UnlockIP] = {"unlock_ip" ,
fs/nfsd/nfsd.h +1 -1
@@ -24,8 +24,8 @@#include <uapi/linux/nfsd/debug.h> #include "netns.h" -#include "stats.h" #include "export.h" +#include "stats.h" #undef ifdebug#ifdef CONFIG_SUNRPC_DEBUG
fs/nfsd/nfsfh.c +2 -2
@@ -349,7 +349,7 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)__be32 fh_verify (struct svc_rqst *rqstp,struct svc_fh *fhp,umode_t type,int access) { -struct svc_export *exp; +struct svc_export *exp =NULL ;struct dentry *dentry;__be32 error;
@@ -422,7 +422,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) } out:if (error == nfserr_stale) -nfsd_stats_fh_stale_inc (); +nfsd_stats_fh_stale_inc (exp);return error; }
fs/nfsd/stats.h +9 -3
@@ -59,19 +59,25 @@ static inline void nfsd_stats_rc_nocache_inc(void)percpu_counter_inc (&nfsdstats.counter[NFSD_STATS_RC_NOCACHE ]); } -static inline void nfsd_stats_fh_stale_inc (void ) +static inline void nfsd_stats_fh_stale_inc (struct svc_export *exp) {percpu_counter_inc (&nfsdstats.counter[NFSD_STATS_FH_STALE ]); +if (exp) +percpu_counter_inc (&exp->ex_stats.counter[EXP_STATS_FH_STALE ]); } -static inline void nfsd_stats_io_read_add (s64 amount) +static inline void nfsd_stats_io_read_add (struct svc_export *exp,s64 amount) {percpu_counter_add (&nfsdstats.counter[NFSD_STATS_IO_READ ], amount); +if (exp) +percpu_counter_add (&exp->ex_stats.counter[EXP_STATS_IO_READ ], amount); } -static inline void nfsd_stats_io_write_add (s64 amount) +static inline void nfsd_stats_io_write_add (struct svc_export *exp,s64 amount) {percpu_counter_add (&nfsdstats.counter[NFSD_STATS_IO_WRITE ], amount); +if (exp) +percpu_counter_add (&exp->ex_stats.counter[EXP_STATS_IO_WRITE ], amount); }static inline void nfsd_stats_payload_misses_inc (struct nfsd_net *nn)
fs/nfsd/vfs.c +2 -2
@@ -897,7 +897,7 @@ static __be32 nfsd_finish_read(struct svc_rqst *rqstp, struct svc_fh *fhp, unsigned long *count, u32 *eof, ssize_t host_err) { if (host_err >= 0) { -nfsd_stats_io_read_add (host_err ); + nfsd_stats_io_read_add(fhp->fh_export, host_err); *eof =nfsd_eof_on_read (file, offset, host_err, *count); *count = host_err;fsnotify_access (file);
@@ -1050,7 +1050,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, goto out_nfserr; } *cnt = host_err; -nfsd_stats_io_write_add (*cnt); +nfsd_stats_io_write_add (exp, *cnt);fsnotify_modify (file); host_err =filemap_check_wb_err (file->f_mapping, since);if (host_err <0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 178/770 nfsd4: simplify process_lookup1
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Bruce Fields <[email protected]>
[ Upstream commit 33311873adb0d55c287b164117b5b4bb7b1bdc40 ]
This STALE_CLIENTID check is redundant with the one in lookup_clientid().
There's a difference in behavior is in case of memory allocation failure, which I think isn't a big deal.
--- fs/nfsd/nfs4state.c | 2 -- 1 file changed, 2 deletions(-)
fs/nfsd/nfs4state.c +0 -2
@@ -4722,8 +4722,6 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,struct nfs4_openowner *oo =NULL ;__be32 status; -if (STALE_CLIENTID (&open->op_clientid, nn)) -return nfserr_stale_clientid;/* * In case we need it later, after we've already created the * file and don't want to risk a further failure:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 179/770 nfsd: simplify process_lock
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Bruce Fields <[email protected]>
[ Upstream commit a9d53a75cf574d6aa41f3cb4968fffe4f64e0fad ]
Similarly, this STALE_CLIENTID check is already handled by:
nfs4_preprocess_confirmed_seqid_op()->
nfs4_preprocess_seqid_op()->
nfsd4_lookup_stateid()->
set_client()->
STALE_CLIENTID()(This may cause it to return a different error in some cases where there are multiple things wrong; pynfs test SEQ10 regressed on this commit because of that, but I think that's the test's fault, and I've fixed it separately.)
--- fs/nfsd/nfs4state.c | 4 ---- 1 file changed, 4 deletions(-)
fs/nfsd/nfs4state.c +0 -4
@@ -6720,10 +6720,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, &cstate->session->se_client->cl_clientid, sizeof(clientid_t)); - status = nfserr_stale_clientid; -if (STALE_CLIENTID (&lock->lk_new_clientid, nn)) - goto out; -/* validate and update open stateid and open seqid */ status = nfs4_preprocess_confirmed_seqid_op(cstate, lock->lk_new_open_seqid,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 180/770 nfsd: simplify nfsd_renew
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Bruce Fields <[email protected]>
[ Upstream commit b4587eb2cf4b6271f67fb93b75f7de2a2026e853 ]
You can take the single-exit thing too far, I think.
--- fs/nfsd/nfs4state.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
fs/nfsd/nfs4state.c +3 -6
@@ -5322,15 +5322,12 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,trace_nfsd_clid_renew (clid); status =lookup_clientid (clid, cstate, nn, false);if (status) - goto out; +return status; clp = cstate->clp; - status = nfserr_cb_path_down;if (!list_empty (&clp->cl_delegations) && clp->cl_cb_state !=NFSD4_CB_UP ) - goto out; - status = nfs_ok; -out: -return status; +return nfserr_cb_path_down; +return nfs_ok; }void
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 181/770 nfsd: rename lookup_clientid->set_client
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Bruce Fields <[email protected]>
[ Upstream commit 460d27091ae2c23e7ac959a61cd481c58832db58 ]
I think this is a better name, and I'm going to reuse elsewhere the code that does the lookup itself.
--- fs/nfsd/nfs4state.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
fs/nfsd/nfs4state.c +8 -10
@@ -4675,7 +4675,7 @@ static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struct nfs4return nfserr_bad_seqid; } -static __be32 lookup_clientid (clientid_t *clid, +static __be32 set_client (clientid_t *clid,struct nfsd4_compound_state *cstate,struct nfsd_net *nn,bool sessions)
@@ -4730,7 +4730,7 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,if (open->op_file ==NULL )return nfserr_jukebox; - status =lookup_clientid (clientid, cstate, nn, false); + status =set_client (clientid, cstate, nn, false);if (status)return status; clp = cstate->clp;
@@ -5320,7 +5320,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);trace_nfsd_clid_renew (clid); - status =lookup_clientid (clid, cstate, nn, false); + status =set_client (clid, cstate, nn, false);if (status)return status; clp = cstate->clp;
@@ -5701,8 +5701,7 @@ nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,if (ZERO_STATEID (stateid) ||ONE_STATEID (stateid) ||CLOSE_STATEID (stateid))return nfserr_bad_stateid; - status =lookup_clientid (&stateid->si_opaque.so_clid, cstate, nn, - false); + status =set_client (&stateid->si_opaque.so_clid, cstate, nn, false);if (status == nfserr_stale_clientid) {if (cstate->session)return nfserr_bad_stateid;
@@ -5841,7 +5840,7 @@ static __be32 find_cpntf_state(struct nfsd_net *nn, stateid_t *st, cps->cpntf_time =ktime_get_boottime_seconds ();memset (&cstate,0 ,sizeof (cstate)); - status =lookup_clientid (&cps->cp_p_clid, &cstate, nn, true); + status =set_client (&cps->cp_p_clid, &cstate, nn, true);if (status) goto out; status = nfsd4_lookup_stateid(&cstate, &cps->cp_p_stateid,
@@ -6933,8 +6932,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,return nfserr_inval;if (!nfsd4_has_session (cstate)) { - status =lookup_clientid (&lockt->lt_clientid, cstate, nn, - false); + status =set_client (&lockt->lt_clientid, cstate, nn, false);if (status) goto out; }
@@ -7118,7 +7116,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,dprintk ("nfsd4_release_lockowner clientid: (%08x/%08x):\n" , clid->cl_boot, clid->cl_id); - status =lookup_clientid (clid, cstate, nn, false); + status =set_client (clid, cstate, nn, false);if (status)return status;
@@ -7258,7 +7256,7 @@ nfs4_check_open_reclaim(clientid_t *clid,__be32 status;/* find clientid in conf_id_hashtbl */ - status =lookup_clientid (clid, cstate, nn, false); + status =set_client (clid, cstate, nn, false);if (status)return nfserr_reclaim_bad;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 182/770 nfsd: refactor set_client
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Bruce Fields <[email protected]>
[ Upstream commit 7950b5316e40d99dcb85ab81a2d1dbb913d7c1c8 ]
This'll be useful elsewhere.
--- fs/nfsd/nfs4state.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)
fs/nfsd/nfs4state.c +16 -16
@@ -4675,40 +4675,40 @@ static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struct nfs4return nfserr_bad_seqid; } +static struct nfs4_client *lookup_clientid (clientid_t *clid,bool sessions, +struct nfsd_net *nn) +{ +struct nfs4_client *found; + +spin_lock (&nn->client_lock); + found =find_confirmed_client (clid, sessions, nn); +if (found) +atomic_inc (&found->cl_rpc_users); +spin_unlock (&nn->client_lock); +return found; +} +static __be32 set_client (clientid_t *clid,struct nfsd4_compound_state *cstate,struct nfsd_net *nn,bool sessions) { -struct nfs4_client *found; -if (cstate->clp) { - found = cstate->clp; -if (!same_clid (&found->cl_clientid, clid)) +if (!same_clid (&cstate->clp->cl_clientid, clid))return nfserr_stale_clientid;return nfs_ok; } -if (STALE_CLIENTID (clid, nn))return nfserr_stale_clientid; -/* * For v4.1+ we get the client in the SEQUENCE op. If we don't have one * cached already then we know this is for is for v4.0 and "sessions" * will be false. */ WARN_ON_ONCE (cstate->session); -spin_lock (&nn->client_lock); - found =find_confirmed_client (clid, sessions, nn); -if (!found) { -spin_unlock (&nn->client_lock); + cstate->clp =lookup_clientid (clid, sessions, nn); +if (!cstate->clp)return nfserr_expired; - } -atomic_inc (&found->cl_rpc_users); -spin_unlock (&nn->client_lock); - -/* Cache the nfs4_client in cstate! */ - cstate->clp = found;return nfs_ok; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 183/770 nfsd: find_cpntf_state cleanup
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Bruce Fields <[email protected]>
[ Upstream commit 47fdb22dacae78f37701d82a94c16a014186d34e ]
I think this unusual use of struct compound_state could cause confusion.
It's not that much more complicated just to open-code this stateid lookup.
The only change in behavior should be a different error return in the case the copy is using a source stateid that is a revoked delegation, but I doubt that matters.
--- fs/nfsd/nfs4state.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-)
fs/nfsd/nfs4state.c +14 -8
@@ -5832,21 +5832,27 @@ static __be32 find_cpntf_state(struct nfsd_net *nn, stateid_t *st, {__be32 status;struct nfs4_cpntf_state *cps =NULL ; -struct nfsd4_compound_state cstate; +struct nfs4_client *found; status =manage_cpntf_state (nn, st,NULL , &cps);if (status)return status; cps->cpntf_time =ktime_get_boottime_seconds (); -memset (&cstate,0 ,sizeof (cstate)); - status =set_client (&cps->cp_p_clid, &cstate, nn, true); -if (status) + + status = nfserr_expired; + found =lookup_clientid (&cps->cp_p_clid, true, nn); +if (!found) goto out; - status =nfsd4_lookup_stateid (&cstate, &cps->cp_p_stateid, -NFS4_DELEG_STID |NFS4_OPEN_STID |NFS4_LOCK_STID , - stid, nn); -put_client_renew (cstate.clp); + + *stid =find_stateid_by_type (found, &cps->cp_p_stateid, +NFS4_DELEG_STID |NFS4_OPEN_STID |NFS4_LOCK_STID ); +if (*stid) + status = nfs_ok; +else + status = nfserr_bad_stateid; + +put_client_renew (found); out:nfs4_put_cpntf_state (nn, cps);return status;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 184/770 nfsd: remove unused set_client argument
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Bruce Fields <[email protected]>
[ Upstream commit f71475ba8c2a77fff8051903cf4b7d826c3d1693 ]
Every caller is setting this argument to false, so we don't need it.
Also cut this comment a bit and remove an unnecessary warning.
--- fs/nfsd/nfs4state.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
fs/nfsd/nfs4state.c +10 -13
@@ -4690,8 +4690,7 @@ static struct nfs4_client *lookup_clientid(clientid_t *clid, bool sessions,static __be32 set_client (clientid_t *clid,struct nfsd4_compound_state *cstate, -struct nfsd_net *nn, -bool sessions) +struct nfsd_net *nn) {if (cstate->clp) {if (!same_clid (&cstate->clp->cl_clientid, clid))
@@ -4701,12 +4700,10 @@ static __be32 set_client(clientid_t *clid,if (STALE_CLIENTID (clid, nn))return nfserr_stale_clientid;/* -* For v4.1+ we get the client in the SEQUENCE op. If we don't have one -* cached already then we know this is for is for v4.0 and "sessions" -* will be false. +* We're in the 4.0 case (otherwise the SEQUENCE op would have +* set cstate->clp), so session = false: */ -WARN_ON_ONCE (cstate->session); - cstate->clp =lookup_clientid (clid, sessions, nn); + cstate->clp =lookup_clientid (clid, false, nn);if (!cstate->clp)return nfserr_expired;return nfs_ok;
@@ -4730,7 +4727,7 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,if (open->op_file ==NULL )return nfserr_jukebox; - status =set_client (clientid, cstate, nn, false); + status =set_client (clientid, cstate, nn);if (status)return status; clp = cstate->clp;
@@ -5320,7 +5317,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);trace_nfsd_clid_renew (clid); - status =set_client (clid, cstate, nn, false); + status =set_client (clid, cstate, nn);if (status)return status; clp = cstate->clp;
@@ -5701,7 +5698,7 @@ nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,if (ZERO_STATEID (stateid) ||ONE_STATEID (stateid) ||CLOSE_STATEID (stateid))return nfserr_bad_stateid; - status =set_client (&stateid->si_opaque.so_clid, cstate, nn, false); + status =set_client (&stateid->si_opaque.so_clid, cstate, nn);if (status == nfserr_stale_clientid) {if (cstate->session)return nfserr_bad_stateid;
@@ -6938,7 +6935,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,return nfserr_inval;if (!nfsd4_has_session (cstate)) { - status =set_client (&lockt->lt_clientid, cstate, nn, false); + status =set_client (&lockt->lt_clientid, cstate, nn);if (status) goto out; }
@@ -7122,7 +7119,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,dprintk ("nfsd4_release_lockowner clientid: (%08x/%08x):\n" , clid->cl_boot, clid->cl_id); - status =set_client (clid, cstate, nn, false); + status =set_client (clid, cstate, nn);if (status)return status;
@@ -7262,7 +7259,7 @@ nfs4_check_open_reclaim(clientid_t *clid,__be32 status;/* find clientid in conf_id_hashtbl */ - status =set_client (clid, cstate, nn, false); + status =set_client (clid, cstate, nn);if (status)return nfserr_reclaim_bad;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 185/770 nfsd: simplify nfsd4_check_open_reclaim
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Bruce Fields <[email protected]>
[ Upstream commit 1722b04624806ced51693f546edb83e8b2297a77 ]
The set_client() was already taken care of by process_open1().
The comments here are mostly redundant with the code.
--- fs/nfsd/nfs4proc.c | 3 +-- fs/nfsd/nfs4state.c | 18 +++--------------- fs/nfsd/state.h | 3 +-- 3 files changed, 5 insertions(+), 19 deletions(-)
fs/nfsd/nfs4proc.c +1 -2
@@ -428,8 +428,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out;break ;case NFS4_OPEN_CLAIM_PREVIOUS : - status =nfs4_check_open_reclaim (&open->op_clientid, - cstate, nn); + status =nfs4_check_open_reclaim (cstate->clp);if (status) goto out; open->op_openowner->oo_flags |=NFS4_OO_CONFIRMED ;
fs/nfsd/nfs4state.c +3 -15
@@ -7248,25 +7248,13 @@ nfsd4_find_reclaim_client(struct xdr_netobj name, struct nfsd_net *nn)return NULL ; } -/* -* Called from OPEN. Look for clientid in reclaim list. -*/ __be32 -nfs4_check_open_reclaim (clientid_t *clid, -struct nfsd4_compound_state *cstate, -struct nfsd_net *nn) +nfs4_check_open_reclaim (struct nfs4_client *clp) { -__be32 status; - -/* find clientid in conf_id_hashtbl */ - status =set_client (clid, cstate, nn); -if (status) -return nfserr_reclaim_bad; - -if (test_bit (NFSD4_CLIENT_RECLAIM_COMPLETE , &cstate->clp->cl_flags)) +if (test_bit (NFSD4_CLIENT_RECLAIM_COMPLETE , &clp->cl_flags))return nfserr_no_grace; -if (nfsd4_client_record_check (cstate->clp)) +if (nfsd4_client_record_check (clp))return nfserr_reclaim_bad;return nfs_ok;
fs/nfsd/state.h +1 -2
@@ -649,8 +649,7 @@ void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *)extern void nfs4_release_reclaim (struct nfsd_net *);extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client (struct xdr_netobj name,struct nfsd_net *nn); -extern __be32 nfs4_check_open_reclaim (clientid_t *clid, -struct nfsd4_compound_state *cstate,struct nfsd_net *nn); +extern __be32 nfs4_check_open_reclaim (struct nfs4_client *);extern void nfsd4_probe_callback (struct nfs4_client *clp);extern void nfsd4_probe_callback_sync (struct nfs4_client *clp);extern void nfsd4_change_callback (struct nfs4_client *clp,struct nfs4_cb_conn *);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 186/770 nfsd: cstate->session->se_client -> cstate->clp
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Bruce Fields <[email protected]>
[ Upstream commit ec59659b4972ec25851aa03b4b5baba6764a62e4 ]
I'm not sure why we're writing this out the hard way in so many places.
--- fs/nfsd/nfs4proc.c | 5 ++--- fs/nfsd/nfs4state.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-)
fs/nfsd/nfs4proc.c +2 -3
@@ -378,8 +378,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,* Before RECLAIM_COMPLETE done, server should deny new lock */ if (nfsd4_has_session (cstate) && - !test_bit (NFSD4_CLIENT_RECLAIM_COMPLETE , - &cstate->session->se_client->cl_flags) && + !test_bit (NFSD4_CLIENT_RECLAIM_COMPLETE , &cstate->clp->cl_flags) && open->op_claim_type !=NFS4_OPEN_CLAIM_PREVIOUS )return nfserr_grace;
@@ -1881,7 +1880,7 @@ nfsd4_getdeviceinfo(struct svc_rqst *rqstp, nfserr = nfs_ok;if (gdp->gd_maxcount !=0 ) { nfserr = ops->proc_getdeviceinfo (exp->ex_path.mnt->mnt_sb, - rqstp, cstate->session->se_client, gdp); + rqstp, cstate->clp, gdp); } gdp->gd_notify_types &= ops->notify_types;
fs/nfsd/nfs4state.c +8 -8
@@ -3923,6 +3923,7 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) { struct nfsd4_reclaim_complete *rc = &u->reclaim_complete; +struct nfs4_client *clp = cstate->clp;__be32 status =0 ;if (rc->rca_one_fs) {
@@ -3936,12 +3937,11 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp, } status = nfserr_complete_already; -if (test_and_set_bit (NFSD4_CLIENT_RECLAIM_COMPLETE , - &cstate->session->se_client->cl_flags)) +if (test_and_set_bit (NFSD4_CLIENT_RECLAIM_COMPLETE , &clp->cl_flags)) goto out; status = nfserr_stale_clientid; -if (is_client_expired (cstate->session->se_client)) +if (is_client_expired (clp))/* * The following error isn't really legal. * But we only get here if the client just explicitly
@@ -3952,8 +3952,8 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp, goto out; status = nfs_ok; -nfsd4_client_record_create (cstate->session->se_client); -inc_reclaim_complete (cstate->session->se_client); +nfsd4_client_record_create (clp); +inc_reclaim_complete (clp); out:return status; }
@@ -5938,7 +5938,7 @@ nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, {struct nfsd4_test_stateid *test_stateid = &u->test_stateid;struct nfsd4_test_stateid_id *stateid; -struct nfs4_client *cl = cstate->session->se_client; +struct nfs4_client *cl = cstate->clp;list_for_each_entry (stateid, &test_stateid->ts_stateid_list, ts_id_list) stateid->ts_id_status =
@@ -5984,7 +5984,7 @@ nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,stateid_t *stateid = &free_stateid->fr_stateid;struct nfs4_stid *s;struct nfs4_delegation *dp; -struct nfs4_client *cl = cstate->session->se_client; +struct nfs4_client *cl = cstate->clp;__be32 ret = nfserr_bad_stateid;spin_lock (&cl->cl_lock);
@@ -6716,7 +6716,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,if (nfsd4_has_session (cstate))/* See rfc 5661 18.10.3: given clientid is ignored: */ memcpy (&lock->lk_new_clientid, - &cstate->session->se_client->cl_clientid, + &cstate->clp->cl_clientid,sizeof (clientid_t));/* validate and update open stateid and open seqid */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 187/770 NFSv4_2: SSC helper should use its own config.
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dai Ngo <[email protected]>
[ Upstream commit 02591f9febd5f69bb4c266a4abf899c4cf21964f ]
Currently NFSv4_2 SSC helper, nfs_ssc, incorrectly uses GRACE_PERIOD as its config. Fix by adding new config NFS_V4_2_SSC_HELPER which depends on NFS_V4_2 and is automatically selected when NFSD_V4 is enabled. Also removed the file name from a comment in nfs_ssc.c.
--- fs/Kconfig | 4 ++++ fs/nfs/nfs4file.c | 4 ++++ fs/nfs/super.c | 12 ++++++++++++ fs/nfs_common/Makefile | 2 +- fs/nfs_common/nfs_ssc.c | 2 -- fs/nfsd/Kconfig | 1 + 6 files changed, 22 insertions(+), 3 deletions(-)
fs/Kconfig +4 -0
@@ -333,6 +333,10 @@ config NFS_COMMON depends on NFSD || NFS_FS || LOCKD default y +config NFS_V4_2_SSC_HELPER + tristate + default y if NFS_V4=y || NFS_FS=y + source "net/sunrpc/Kconfig" source "fs/ceph/Kconfig" source "fs/cifs/Kconfig"
fs/nfs/nfs4file.c +4 -0
@@ -430,7 +430,9 @@ static const struct nfs4_ssc_client_ops nfs4_ssc_clnt_ops_tbl = {*/ void nfs42_ssc_register_ops (void ) { +#ifdef CONFIG_NFSD_V4 nfs42_ssc_register (&nfs4_ssc_clnt_ops_tbl); +#endif }/**
@@ -441,7 +443,9 @@ void nfs42_ssc_register_ops(void)*/ void nfs42_ssc_unregister_ops (void ) { +#ifdef CONFIG_NFSD_V4 nfs42_ssc_unregister (&nfs4_ssc_clnt_ops_tbl); +#endif }#endif /* CONFIG_NFS_V4_2 */
fs/nfs/super.c +12 -0
@@ -86,9 +86,11 @@ const struct super_operations nfs_sops = { };EXPORT_SYMBOL_GPL (nfs_sops); +#ifdef CONFIG_NFS_V4_2 static const struct nfs_ssc_client_ops nfs_ssc_clnt_ops_tbl = { .sco_sb_deactive = nfs_sb_deactive, }; +#endif #if IS_ENABLED (CONFIG_NFS_V4 )static int __init register_nfs4_fs (void )
@@ -111,15 +113,21 @@ static void unregister_nfs4_fs(void) }#endif +#ifdef CONFIG_NFS_V4_2 static void nfs_ssc_register_ops (void ) { +#ifdef CONFIG_NFSD_V4 nfs_ssc_register (&nfs_ssc_clnt_ops_tbl); +#endif }static void nfs_ssc_unregister_ops (void ) { +#ifdef CONFIG_NFSD_V4 nfs_ssc_unregister (&nfs_ssc_clnt_ops_tbl); +#endif } +#endif /* CONFIG_NFS_V4_2 */ static struct shrinker acl_shrinker = { .count_objects = nfs_access_cache_count,
@@ -148,7 +156,9 @@ int __init register_nfs_fs(void) ret =register_shrinker (&acl_shrinker);if (ret <0 ) goto error_3; +#ifdef CONFIG_NFS_V4_2 nfs_ssc_register_ops (); +#endif return 0 ; error_3:nfs_unregister_sysctl ();
@@ -168,7 +178,9 @@ void __exit unregister_nfs_fs(void)unregister_shrinker (&acl_shrinker);nfs_unregister_sysctl ();unregister_nfs4_fs (); +#ifdef CONFIG_NFS_V4_2 nfs_ssc_unregister_ops (); +#endif unregister_filesystem (&nfs_fs_type); }
fs/nfs_common/Makefile +1 -1
@@ -7,4 +7,4 @@ obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl.o nfs_acl-objs := nfsacl.o obj-$(CONFIG_GRACE_PERIOD) += grace.o -obj-$(CONFIG_GRACE_PERIOD) += nfs_ssc.o +obj-$(CONFIG_NFS_V4_2_SSC_HELPER) += nfs_ssc.o
fs/nfs_common/nfs_ssc.c +0 -2
@@ -1,7 +1,5 @@// SPDX-License-Identifier: GPL-2.0-only /* -* fs/nfs_common/nfs_ssc_comm.c -* * Helper for knfsd's SSC to access ops in NFS client modules * * Author: Dai Ngo <[email protected]>
fs/nfsd/Kconfig +1 -0
@@ -77,6 +77,7 @@ config NFSD_V4 select CRYPTO_MD5 select CRYPTO_SHA256 select GRACE_PERIOD + select NFS_V4_2_SSC_HELPER if NFS_V4_2 help This option enables support in your system's NFS server for version 4 of the NFS protocol (RFC 3530).
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 188/770 nfs: use change attribute for NFS re-exports
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Bruce Fields <[email protected]>
[ Upstream commit 3cc55f4434b421d37300aa9a167ace7d60b45ccf ]
When exporting NFS, we may as well use the real change attribute returned by the original server instead of faking up a change attribute from the ctime.
Note we can't do that by setting I_VERSION--that would also turn on the logic in iversion.h which treats the lower bit specially, and that doesn't make sense for NFS.
So instead we define a new export operation for filesystems like NFS that want to manage the change attribute themselves.
--- fs/nfs/export.c | 18 ++++++++++++++++++ fs/nfsd/nfsfh.h | 5 ++++- include/linux/exportfs.h | 1 + 3 files changed, 23 insertions(+), 1 deletion(-)
fs/nfs/export.c +18 -0
@@ -167,10 +167,28 @@ nfs_get_parent(struct dentry *dentry)return parent; } +static u64 nfs_fetch_iversion (struct inode *inode) +{ +struct nfs_server *server =NFS_SERVER (inode); + +/* Is this the right call?: */ +nfs_revalidate_inode (server, inode); +/* +* Also, note we're ignoring any returned error. That seems to be +* the practice for cache consistency information elsewhere in +* the server, but I'm not sure why. +*/ +if (server->nfs_client->rpc_ops->version >=4 ) +return inode_peek_iversion_raw (inode); +else +return time_to_chattr (&inode->i_ctime); +} +const struct export_operations nfs_export_ops = { .encode_fh = nfs_encode_fh, .fh_to_dentry = nfs_fh_to_dentry, .get_parent = nfs_get_parent, + .fetch_iversion = nfs_fetch_iversion, .flags =EXPORT_OP_NOWCC |EXPORT_OP_NOSUBTREECHK |EXPORT_OP_CLOSE_BEFORE_UNLINK |EXPORT_OP_REMOTE_FS |EXPORT_OP_NOATOMIC_ATTR ,
fs/nfsd/nfsfh.h +4 -1
@@ -12,6 +12,7 @@#include <linux/sunrpc/svc.h> #include <uapi/linux/nfsd/nfsfh.h> #include <linux/iversion.h> +#include <linux/exportfs.h> static inline __u32 ino_t_to_u32 (ino_t ino) {
@@ -264,7 +265,9 @@ fh_clear_wcc(struct svc_fh *fhp)static inline u64 nfsd4_change_attribute (struct kstat *stat,struct inode *inode) { -if (IS_I_VERSION (inode)) { +if (inode->i_sb->s_export_op->fetch_iversion) +return inode->i_sb->s_export_op->fetch_iversion (inode); +else if (IS_I_VERSION (inode)) {u64 chattr; chattr = stat->ctime.tv_sec;
include/linux/exportfs.h +1 -0
@@ -213,6 +213,7 @@ struct export_operations { bool write, u32 *device_generation);int (*commit_blocks)(struct inode *inode,struct iomap *iomaps,int nr_iomaps,struct iattr *iattr); +u64 (*fetch_iversion)(struct inode *);#define EXPORT_OP_NOWCC (0x1)/* don't collect v3 wcc data */ #define EXPORT_OP_NOSUBTREECHK (0x2)/* no subtree checking */ #define EXPORT_OP_CLOSE_BEFORE_UNLINK (0x4)/* close files before unlink */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 189/770 nfsd: skip some unnecessary stats in the v4 case
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: J. Bruce Fields <[email protected]>
[ Upstream commit 428a23d2bf0ca8fd4d364a464c3e468f0e81671e ]
In the typical case of v4 and an i_version-supporting filesystem, we can skip a stat which is only required to fake up a change attribute from ctime.
--- fs/nfsd/nfs3xdr.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-)
fs/nfsd/nfs3xdr.c +27 -17
@@ -364,6 +364,11 @@ encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)return encode_post_op_attr (rqstp, p, fhp); } +static bool fs_supports_change_attribute (struct super_block *sb) +{ +return sb->s_flags &SB_I_VERSION || sb->s_export_op->fetch_iversion; +} +/* * Fill in the pre_op attr for the wcc data */
@@ -372,24 +377,26 @@ void fill_pre_wcc(struct svc_fh *fhp)struct inode *inode;struct kstat stat;bool v4 = (fhp->fh_maxsize ==NFS4_FHSIZE ); -__be32 err;if (fhp->fh_no_wcc || fhp->fh_pre_saved)return ; inode =d_inode (fhp->fh_dentry); - err =fh_getattr (fhp, &stat); -if (err) { -/* Grab the times from inode anyway */ - stat.mtime = inode->i_mtime; - stat.ctime = inode->i_ctime; - stat.size = inode->i_size; +if (fs_supports_change_attribute (inode->i_sb) || !v4) { +__be32 err =fh_getattr (fhp, &stat); + +if (err) { +/* Grab the times from inode anyway */ + stat.mtime = inode->i_mtime; + stat.ctime = inode->i_ctime; + stat.size = inode->i_size; + } + fhp->fh_pre_mtime = stat.mtime; + fhp->fh_pre_ctime = stat.ctime; + fhp->fh_pre_size = stat.size; }if (v4) fhp->fh_pre_change =nfsd4_change_attribute (&stat, inode); - fhp->fh_pre_mtime = stat.mtime; - fhp->fh_pre_ctime = stat.ctime; - fhp->fh_pre_size = stat.size; fhp->fh_pre_saved = true; }
@@ -400,7 +407,6 @@ void fill_post_wcc(struct svc_fh *fhp) {bool v4 = (fhp->fh_maxsize ==NFS4_FHSIZE );struct inode *inode =d_inode (fhp->fh_dentry); -__be32 err;if (fhp->fh_no_wcc)return ;
@@ -408,12 +414,16 @@ void fill_post_wcc(struct svc_fh *fhp)if (fhp->fh_post_saved)printk ("nfsd: inode locked twice during operation.\n" ); - err =fh_getattr (fhp, &fhp->fh_post_attr); -if (err) { - fhp->fh_post_saved = false; - fhp->fh_post_attr.ctime = inode->i_ctime; - }else - fhp->fh_post_saved = true; + fhp->fh_post_saved = true; + +if (fs_supports_change_attribute (inode->i_sb) || !v4) { +__be32 err =fh_getattr (fhp, &fhp->fh_post_attr); + +if (err) { + fhp->fh_post_saved = false; + fhp->fh_post_attr.ctime = inode->i_ctime; + } + }if (v4) fhp->fh_post_change =nfsd4_change_attribute (&fhp->fh_post_attr, inode);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 190/770 inotify, memcg: account inotify instances to kmemcg
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shakeel Butt <[email protected]>
[ Upstream commit ac7b79fd190b02e7151bc7d2b9da692f537657f3 ]
Currently the fs sysctl inotify/max_user_instances is used to limit the number of inotify instances on the system. For systems running multiple workloads, the per-user namespace sysctl max_inotify_instances can be used to further partition inotify instances. However there is no easy way to set a sensible system level max limit on inotify instances and further partition it between the workloads. It is much easier to charge the underlying resource (i.e. memory) behind the inotify instances to the memcg of the workload and let their memory limits limit the number of inotify instances they can create.
With inotify instances charged to memcg, the admin can simply set max_user_instances to INT_MAX and let the memcg limits of the jobs limit their inotify instances.
--- fs/notify/fanotify/fanotify_user.c | 2 +- fs/notify/group.c | 25 ++++++++++++++++++++----- fs/notify/inotify/inotify_user.c | 4 ++-- include/linux/fsnotify_backend.h | 1 + 4 files changed, 24 insertions(+), 8 deletions(-)
fs/notify/fanotify/fanotify_user.c +1 -1
@@ -976,7 +976,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) f_flags |=O_NONBLOCK ;/* fsnotify_alloc_group takes a ref. Dropped in fanotify_release */ - group =fsnotify_alloc_group (&fanotify_fsnotify_ops); + group =fsnotify_alloc_user_group (&fanotify_fsnotify_ops);if (IS_ERR (group)) {free_uid (user);return PTR_ERR (group);
fs/notify/group.c +20 -5
@@ -111,14 +111,12 @@ void fsnotify_put_group(struct fsnotify_group *group) }EXPORT_SYMBOL_GPL (fsnotify_put_group); -/* -* Create a new fsnotify_group and hold a reference for the group returned. -*/ -struct fsnotify_group *fsnotify_alloc_group (const struct fsnotify_ops *ops) +static struct fsnotify_group *__fsnotify_alloc_group ( +const struct fsnotify_ops *ops,gfp_t gfp) {struct fsnotify_group *group; - group =kzalloc (sizeof (struct fsnotify_group ),GFP_KERNEL ); + group =kzalloc (sizeof (struct fsnotify_group ), gfp);if (!group)return ERR_PTR (-ENOMEM );
@@ -139,8 +137,25 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)return group; } + +/* +* Create a new fsnotify_group and hold a reference for the group returned. +*/ +struct fsnotify_group *fsnotify_alloc_group (const struct fsnotify_ops *ops) +{ +return __fsnotify_alloc_group (ops,GFP_KERNEL ); +}EXPORT_SYMBOL_GPL (fsnotify_alloc_group); +/* +* Create a new fsnotify_group and hold a reference for the group returned. +*/ +struct fsnotify_group *fsnotify_alloc_user_group (const struct fsnotify_ops *ops) +{ +return __fsnotify_alloc_group (ops,GFP_KERNEL_ACCOUNT ); +} +EXPORT_SYMBOL_GPL (fsnotify_alloc_user_group); +int fsnotify_fasync (int fd,struct file *file,int on) {struct fsnotify_group *group = file->private_data;
fs/notify/inotify/inotify_user.c +2 -2
@@ -632,11 +632,11 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events)struct fsnotify_group *group;struct inotify_event_info *oevent; - group =fsnotify_alloc_group (&inotify_fsnotify_ops); + group =fsnotify_alloc_user_group (&inotify_fsnotify_ops);if (IS_ERR (group))return group; - oevent =kmalloc (sizeof (struct inotify_event_info ),GFP_KERNEL ); + oevent =kmalloc (sizeof (struct inotify_event_info ),GFP_KERNEL_ACCOUNT );if (unlikely (!oevent)) {fsnotify_destroy_group (group);return ERR_PTR (-ENOMEM );
include/linux/fsnotify_backend.h +1 -0
@@ -470,6 +470,7 @@ static inline void fsnotify_update_flags(struct dentry *dentry)/* create a new group */ extern struct fsnotify_group *fsnotify_alloc_group (const struct fsnotify_ops *ops); +extern struct fsnotify_group *fsnotify_alloc_user_group (const struct fsnotify_ops *ops);/* get reference to a group */ extern void fsnotify_get_group (struct fsnotify_group *group);/* drop reference on a group from fsnotify_alloc_group */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 191/770 module: unexport find_module and module_mutex
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit 089049f6c9956c5cf1fc89fe10229c76e99f4bef ]
find_module is not used by modular code any more, and random driver code has no business calling it to start with.
--- kernel/module.c | 2 -- 1 file changed, 2 deletions(-)
kernel/module.c +0 -2
@@ -88,7 +88,6 @@* 3) module_addr_min/module_addr_max. * (delete and add uses RCU list operations). */ DEFINE_MUTEX (module_mutex); -EXPORT_SYMBOL_GPL (module_mutex);static LIST_HEAD (modules);/* Work queue for freeing init sections in success case */
@@ -645,7 +644,6 @@ struct module *find_module(const char *name)module_assert_mutex ();return find_module_all (name,strlen (name), false); } -EXPORT_SYMBOL_GPL (find_module);#ifdef CONFIG_SMP
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 192/770 module: use RCU to synchronize find_module
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit a006050575745ca2be25118b90f1c37f454ac542 ]
Allow for a RCU-sched critical section around find_module, following the lower level find_module_all helper, and switch the two callers outside of module.c to use such a RCU-sched critical section instead of module_mutex.
--- include/linux/module.h | 2 +- kernel/livepatch/core.c | 5 +++-- kernel/module.c | 1 - kernel/trace/trace_kprobe.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-)
include/linux/module.h +1 -1
@@ -582,7 +582,7 @@ static inline bool within_module(unsigned long addr, const struct module *mod)return within_module_init (addr, mod) ||within_module_core (addr, mod); } -/* Search for module by name: must hold module_mutex. */ +/* Search for module by name: must be in a RCU-sched critical section. */ struct module *find_module (const char *name);struct symsearch {
kernel/livepatch/core.c +3 -2
@@ -19,6 +19,7 @@#include <linux/moduleloader.h> #include <linux/completion.h> #include <linux/memory.h> +#include <linux/rcupdate.h> #include <asm/cacheflush.h> #include "core.h" #include "patch.h"
@@ -57,7 +58,7 @@ static void klp_find_object_module(struct klp_object *obj)if (!klp_is_module (obj))return ; -mutex_lock (&module_mutex); +rcu_read_lock_sched ();/* * We do not want to block removal of patched modules and therefore * we do not take a reference here. The patches are removed by
@@ -74,7 +75,7 @@ static void klp_find_object_module(struct klp_object *obj)if (mod && mod->klp_alive) obj->mod = mod; -mutex_unlock (&module_mutex); +rcu_read_unlock_sched (); }static bool klp_initialized (void )
kernel/module.c +0 -1
@@ -641,7 +641,6 @@ static struct module *find_module_all(const char *name, size_t len,struct module *find_module (const char *name) { -module_assert_mutex ();return find_module_all (name,strlen (name), false); }
kernel/trace/trace_kprobe.c +2 -2
@@ -124,9 +124,9 @@ static nokprobe_inline bool trace_kprobe_module_exist(struct trace_kprobe *tk)if (!p)return true; *p ='\0' ; -mutex_lock (&module_mutex); +rcu_read_lock_sched (); ret = !!find_module (tk->symbol); -mutex_unlock (&module_mutex); +rcu_read_unlock_sched (); *p =':' ;return ret;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 193/770 kallsyms: refactor {,module_}kallsyms_on_each_symbol
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit 013c1667cf78c1d847152f7116436d82dcab3db4 ]
Require an explicit call to module_kallsyms_on_each_symbol to look for symbols in modules instead of the call from kallsyms_on_each_symbol, and acquire module_mutex inside of module_kallsyms_on_each_symbol instead of leaving that up to the caller. Note that this slightly changes the behavior for the livepatch code in that the symbols from vmlinux are not iterated anymore if objname is set, but that actually is the desired behavior in this case.
--- kernel/kallsyms.c | 6 +++++- kernel/livepatch/core.c | 2 -- kernel/module.c | 13 ++++--------- 3 files changed, 9 insertions(+), 12 deletions(-)
kernel/kallsyms.c +5 -1
@@ -177,6 +177,10 @@ unsigned long kallsyms_lookup_name(const char *name)return module_kallsyms_lookup_name (name); } +/* +* Iterate over all symbols in vmlinux. For symbols from modules use +* module_kallsyms_on_each_symbol instead. +*/ int kallsyms_on_each_symbol (int (*fn)(void *,const char *,struct module *,unsigned long ),void *data)
@@ -192,7 +196,7 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,if (ret !=0 )return ret; } -return module_kallsyms_on_each_symbol (fn, data); +return 0 ; } static unsigned long get_symbol_pos(unsigned long addr,
kernel/livepatch/core.c +0 -2
@@ -164,12 +164,10 @@ static int klp_find_object_symbol(const char *objname, const char *name, .pos = sympos, }; -mutex_lock (&module_mutex);if (objname)module_kallsyms_on_each_symbol (klp_find_callback, &args);else kallsyms_on_each_symbol (klp_find_callback, &args); -mutex_unlock (&module_mutex);/* * Ensure an address was found. If sympos is 0, ensure symbol is unique;
kernel/module.c +4 -9
@@ -255,11 +255,6 @@ static void mod_update_bounds(struct module *mod)struct list_head *kdb_modules = &modules;/* kdb needs the list of modules */ #endif /* CONFIG_KGDB_KDB */ -static void module_assert_mutex (void ) -{ -lockdep_assert_held (&module_mutex); -} -static void module_assert_mutex_or_preempt (void ) {#ifdef CONFIG_LOCKDEP
@@ -4457,8 +4452,7 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,unsigned int i;int ret; -module_assert_mutex (); - +mutex_lock (&module_mutex);list_for_each_entry (mod, &modules, list) {/* We hold module_mutex: no need for rcu_dereference_sched */ struct mod_kallsyms *kallsyms = mod->kallsyms;
@@ -4474,10 +4468,11 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, ret =fn (data,kallsyms_symbol_name (kallsyms, i), mod,kallsyms_symbol_value (sym));if (ret !=0 ) - return ret; + break; } } -return 0 ; +mutex_unlock (&module_mutex); +return ret; }#endif /* CONFIG_KALLSYMS */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 194/770 kallsyms: only build {,module_}kallsyms_on_each_symbol when required
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit 3e3552056ab42f883d7723eeb42fed712b66bacf ]
kallsyms_on_each_symbol and module_kallsyms_on_each_symbol are only used by the livepatching code, so don't build them if livepatching is not enabled.
--- include/linux/kallsyms.h | 17 ++++------------- include/linux/module.h | 16 ++++------------ kernel/kallsyms.c | 2 ++ kernel/module.c | 2 ++ 4 files changed, 12 insertions(+), 25 deletions(-)
include/linux/kallsyms.h +4 -13
@@ -71,15 +71,14 @@ static inline void *dereference_symbol_descriptor(void *ptr)return ptr; } -#ifdef CONFIG_KALLSYMS -/* Lookup the address for a symbol. Returns 0 if not found. */ -unsigned long kallsyms_lookup_name (const char *name); - -/* Call a function on each kallsyms symbol in the core kernel */ int kallsyms_on_each_symbol (int (*fn)(void *,const char *,struct module *,unsigned long ),void *data); +#ifdef CONFIG_KALLSYMS +/* Lookup the address for a symbol. Returns 0 if not found. */ +unsigned long kallsyms_lookup_name (const char *name); +extern int kallsyms_lookup_size_offset (unsigned long addr,unsigned long *symbolsize,unsigned long *offset);
@@ -108,14 +107,6 @@ static inline unsigned long kallsyms_lookup_name(const char *name)return 0 ; } -static inline int kallsyms_on_each_symbol (int (*fn)(void *,const char *, -struct module *, -unsigned long ), -void *data) -{ -return 0 ; -} -static inline int kallsyms_lookup_size_offset (unsigned long addr,unsigned long *symbolsize,unsigned long *offset)
include/linux/module.h +4 -12
@@ -604,10 +604,6 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,/* Look for this name: can be of form module:name. */ unsigned long module_kallsyms_lookup_name (const char *name); -int module_kallsyms_on_each_symbol (int (*fn)(void *,const char *, -struct module *,unsigned long ), -void *data); -extern void __noreturn __module_put_and_exit (struct module *mod,long code);#define module_put_and_exit (code) __module_put_and_exit(THIS_MODULE, code)
@@ -791,14 +787,6 @@ static inline unsigned long module_kallsyms_lookup_name(const char *name)return 0 ; } -static inline int module_kallsyms_on_each_symbol (int (*fn)(void *,const char *, -struct module *, -unsigned long ), -void *data) -{ -return 0 ; -} -static inline int register_module_notifier (struct notifier_block *nb) {/* no events will happen anyway, so this can always succeed */
@@ -887,4 +875,8 @@ static inline bool module_sig_ok(struct module *module) }#endif /* CONFIG_MODULE_SIG */ +int module_kallsyms_on_each_symbol (int (*fn)(void *,const char *, +struct module *,unsigned long ), +void *data); +#endif /* _LINUX_MODULE_H */
kernel/kallsyms.c +2 -0
@@ -177,6 +177,7 @@ unsigned long kallsyms_lookup_name(const char *name)return module_kallsyms_lookup_name (name); } +#ifdef CONFIG_LIVEPATCH /* * Iterate over all symbols in vmlinux. For symbols from modules use * module_kallsyms_on_each_symbol instead.
@@ -198,6 +199,7 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, }return 0 ; } +#endif /* CONFIG_LIVEPATCH */ static unsigned long get_symbol_pos(unsigned long addr, unsigned long *symbolsize,
kernel/module.c +2 -0
@@ -4444,6 +4444,7 @@ unsigned long module_kallsyms_lookup_name(const char *name)return ret; } +#ifdef CONFIG_LIVEPATCH int module_kallsyms_on_each_symbol (int (*fn)(void *,const char *,struct module *,unsigned long ),void *data)
@@ -4474,6 +4475,7 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,mutex_unlock (&module_mutex);return ret; } +#endif /* CONFIG_LIVEPATCH */ #endif /* CONFIG_KALLSYMS */ /* Maximum number of characters written by module_flags() */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 195/770 fs: add file and path permissions helpers
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
[ Upstream commit 02f92b3868a1b34ab98464e76b0e4e060474ba10 ]
Add two simple helpers to check permissions on a file and path respectively and convert over some callers. It simplifies quite a few codepaths and also reduces the churn in later patches quite a bit. Christoph also correctly points out that this makes codepaths (e.g. ioctls) way easier to follow that would otherwise have to do more complex argument passing than necessary.
--- fs/init.c | 6 +++--- fs/notify/fanotify/fanotify_user.c | 2 +- fs/notify/inotify/inotify_user.c | 2 +- fs/open.c | 6 +++--- fs/udf/file.c | 2 +- fs/verity/enable.c | 2 +- include/linux/fs.h | 8 ++++++++ kernel/bpf/inode.c | 2 +- kernel/sys.c | 2 +- mm/madvise.c | 2 +- mm/memcontrol.c | 2 +- mm/mincore.c | 2 +- net/unix/af_unix.c | 2 +- 13 files changed, 24 insertions(+), 16 deletions(-)
fs/init.c +3 -3
@@ -49,7 +49,7 @@ int __init init_chdir(const char *filename) error =kern_path (filename,LOOKUP_FOLLOW |LOOKUP_DIRECTORY , &path);if (error)return error; - error =inode_permission (path.dentry->d_inode,MAY_EXEC |MAY_CHDIR ); + error =path_permission (&path,MAY_EXEC |MAY_CHDIR );if (!error)set_fs_pwd (current->fs, &path);path_put (&path);
@@ -64,7 +64,7 @@ int __init init_chroot(const char *filename) error =kern_path (filename,LOOKUP_FOLLOW |LOOKUP_DIRECTORY , &path);if (error)return error; - error =inode_permission (path.dentry->d_inode,MAY_EXEC |MAY_CHDIR ); + error =path_permission (&path,MAY_EXEC |MAY_CHDIR );if (error) goto dput_and_out; error = -EPERM ;
@@ -118,7 +118,7 @@ int __init init_eaccess(const char *filename) error =kern_path (filename,LOOKUP_FOLLOW , &path);if (error)return error; - error =inode_permission (d_inode (path.dentry),MAY_ACCESS ); + error =path_permission (&path,MAY_ACCESS );path_put (&path);return error; }
fs/notify/fanotify/fanotify_user.c +1 -1
@@ -702,7 +702,7 @@ static int fanotify_find_path(int dfd, const char __user *filename, }/* you can only watch an inode if you have read permissions on it */ - ret =inode_permission (path->dentry->d_inode,MAY_READ ); + ret =path_permission (path,MAY_READ );if (ret) {path_put (path); goto out;
fs/notify/inotify/inotify_user.c +1 -1
@@ -352,7 +352,7 @@ static int inotify_find_inode(const char __user *dirname, struct path *path,if (error)return error;/* you can only watch an inode if you have read permissions on it */ - error =inode_permission (path->dentry->d_inode,MAY_READ ); + error =path_permission (path,MAY_READ );if (error) {path_put (path);return error;
fs/open.c +3 -3
@@ -492,7 +492,7 @@ SYSCALL_DEFINE1(chdir, const char __user *, filename)if (error) goto out; - error =inode_permission (path.dentry->d_inode,MAY_EXEC |MAY_CHDIR ); + error =path_permission (&path,MAY_EXEC |MAY_CHDIR );if (error) goto dput_and_out;
@@ -521,7 +521,7 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd)if (!d_can_lookup (f.file->f_path.dentry)) goto out_putf; - error =inode_permission (file_inode (f.file),MAY_EXEC |MAY_CHDIR ); + error =file_permission (f.file,MAY_EXEC |MAY_CHDIR );if (!error)set_fs_pwd (current->fs, &f.file->f_path); out_putf:
@@ -540,7 +540,7 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)if (error) goto out; - error =inode_permission (path.dentry->d_inode,MAY_EXEC |MAY_CHDIR ); + error =path_permission (&path,MAY_EXEC |MAY_CHDIR );if (error) goto dput_and_out;
fs/udf/file.c +1 -1
@@ -181,7 +181,7 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)long old_block, new_block;int result; -if (inode_permission (inode,MAY_READ ) !=0 ) { +if (file_permission (filp,MAY_READ ) !=0 ) {udf_debug ("no permission to access inode %lu\n" , inode->i_ino);return -EPERM ; }
fs/verity/enable.c +1 -1
@@ -369,7 +369,7 @@ int fsverity_ioctl_enable(struct file *filp, const void __user *uarg)* has verity enabled, and to stabilize the data being hashed. */ - err =inode_permission (inode,MAY_WRITE ); + err =file_permission (filp,MAY_WRITE );if (err)return err;
include/linux/fs.h +8 -0
@@ -2824,6 +2824,14 @@ static inline int bmap(struct inode *inode, sector_t *block)extern int notify_change (struct dentry *,struct iattr *,struct inode **);extern int inode_permission (struct inode *,int );extern int generic_permission (struct inode *,int ); +static inline int file_permission (struct file *file,int mask) +{ +return inode_permission (file_inode (file), mask); +} +static inline int path_permission (const struct path *path,int mask) +{ +return inode_permission (d_inode (path->dentry), mask); +}extern int __check_sticky (struct inode *dir,struct inode *inode);static inline bool execute_ok (struct inode *inode)
kernel/bpf/inode.c +1 -1
@@ -507,7 +507,7 @@ static void *bpf_obj_do_get(const char __user *pathname,return ERR_PTR (ret); inode =d_backing_inode (path.dentry); - ret =inode_permission (inode,ACC_MODE (flags)); + ret =path_permission (&path,ACC_MODE (flags));if (ret) goto out;
kernel/sys.c +1 -1
@@ -1873,7 +1873,7 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)if (!S_ISREG (inode->i_mode) ||path_noexec (&exe.file->f_path)) goto exit; - err =inode_permission (inode,MAY_EXEC ); + err =file_permission (exe.file,MAY_EXEC );if (err) goto exit;
mm/madvise.c +1 -1
@@ -543,7 +543,7 @@ static inline bool can_do_pageout(struct vm_area_struct *vma)* opens a side channel. */ return inode_owner_or_capable (file_inode (vma->vm_file)) || -inode_permission (file_inode (vma->vm_file),MAY_WRITE ) ==0 ; +file_permission (vma->vm_file,MAY_WRITE ) ==0 ; } static long madvise_pageout(struct vm_area_struct *vma,
mm/memcontrol.c +1 -1
@@ -4918,7 +4918,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,/* the process need read permission on control file */ /* AV: shouldn't we check that it's been opened for read instead? */ - ret =inode_permission (file_inode (cfile.file),MAY_READ ); + ret =file_permission (cfile.file,MAY_READ );if (ret <0 ) goto out_put_cfile;
mm/mincore.c +1 -1
@@ -167,7 +167,7 @@ static inline bool can_do_mincore(struct vm_area_struct *vma)* mappings, which opens a side channel. */ return inode_owner_or_capable (file_inode (vma->vm_file)) || -inode_permission (file_inode (vma->vm_file),MAY_WRITE ) ==0 ; +file_permission (vma->vm_file,MAY_WRITE ) ==0 ; }static const struct mm_walk_ops mincore_walk_ops = {
net/unix/af_unix.c +1 -1
@@ -959,7 +959,7 @@ static struct sock *unix_find_other(struct net *net,if (err) goto fail; inode =d_backing_inode (path.dentry); - err =inode_permission (inode,MAY_WRITE ); + err =path_permission (&path,MAY_WRITE );if (err) goto put_fail;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 196/770 namei: introduce struct renamedata
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
[ Upstream commit 9fe61450972d3900bffb1dc26a17ebb9cdd92db2 ]
In order to handle idmapped mounts we will extend the vfs rename helper to take two new arguments in follow up patches. Since this operations already takes a bunch of arguments add a simple struct renamedata and make the current helper use it before we extend it.
--- fs/cachefiles/namei.c | 9 +++++++-- fs/ecryptfs/inode.c | 10 +++++++--- fs/namei.c | 21 +++++++++++++++------ fs/nfsd/vfs.c | 8 +++++++- fs/overlayfs/overlayfs.h | 9 ++++++++- include/linux/fs.h | 12 +++++++++++- 6 files changed, 55 insertions(+), 14 deletions(-)
fs/cachefiles/namei.c +7 -2
@@ -412,9 +412,14 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,if (ret <0 ) {cachefiles_io_error (cache,"Rename security error %d" , ret); }else { +struct renamedata rd = { + .old_dir =d_inode (dir), + .old_dentry = rep, + .new_dir =d_inode (cache->graveyard), + .new_dentry = grave, + };trace_cachefiles_rename (object, rep, grave, why); - ret =vfs_rename (d_inode (dir), rep, -d_inode (cache->graveyard), grave,NULL ,0 ); + ret =vfs_rename (&rd);if (ret !=0 && ret != -ENOMEM )cachefiles_io_error (cache,"Rename failed with error %d" , ret);
fs/ecryptfs/inode.c +7 -3
@@ -598,6 +598,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,struct dentry *lower_new_dir_dentry;struct dentry *trap;struct inode *target_inode; +struct renamedata rd = {};if (flags)return -EINVAL ;
@@ -627,9 +628,12 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, rc = -ENOTEMPTY ; goto out_lock; } - rc =vfs_rename (d_inode (lower_old_dir_dentry), lower_old_dentry, -d_inode (lower_new_dir_dentry), lower_new_dentry, -NULL ,0 ); + + rd.old_dir =d_inode (lower_old_dir_dentry); + rd.old_dentry = lower_old_dentry; + rd.new_dir =d_inode (lower_new_dir_dentry); + rd.new_dentry = lower_new_dentry; + rc =vfs_rename (&rd);if (rc) goto out_lock;if (target_inode)
fs/namei.c +15 -6
@@ -4277,11 +4277,14 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname* ->i_mutex on parents, which works but leads to some truly excessive * locking]. */ -int vfs_rename (struct inode *old_dir,struct dentry *old_dentry, -struct inode *new_dir,struct dentry *new_dentry, -struct inode **delegated_inode,unsigned int flags) +int vfs_rename (struct renamedata *rd) {int error; +struct inode *old_dir = rd->old_dir, *new_dir = rd->new_dir; +struct dentry *old_dentry = rd->old_dentry; +struct dentry *new_dentry = rd->new_dentry; +struct inode **delegated_inode = rd->delegated_inode; +unsigned int flags = rd->flags;bool is_dir =d_is_dir (old_dentry);struct inode *source = old_dentry->d_inode;struct inode *target = new_dentry->d_inode;
@@ -4429,6 +4432,7 @@ EXPORT_SYMBOL(vfs_rename);int do_renameat2 (int olddfd,struct filename *from,int newdfd,struct filename *to,unsigned int flags) { +struct renamedata rd;struct dentry *old_dentry, *new_dentry;struct dentry *trap;struct path old_path, new_path;
@@ -4532,9 +4536,14 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd, &new_path, new_dentry, flags);if (error) goto exit5; - error =vfs_rename (old_path.dentry->d_inode, old_dentry, - new_path.dentry->d_inode, new_dentry, - &delegated_inode, flags); + + rd.old_dir = old_path.dentry->d_inode; + rd.old_dentry = old_dentry; + rd.new_dir = new_path.dentry->d_inode; + rd.new_dentry = new_dentry; + rd.delegated_inode = &delegated_inode; + rd.flags = flags; + error =vfs_rename (&rd); exit5:dput (new_dentry); exit4:
fs/nfsd/vfs.c +7 -1
@@ -1812,7 +1812,13 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, close_cached = true; goto out_dput_old; }else { - host_err =vfs_rename (fdir, odentry, tdir, ndentry,NULL ,0 ); +struct renamedata rd = { + .old_dir = fdir, + .old_dentry = odentry, + .new_dir = tdir, + .new_dentry = ndentry, + }; + host_err =vfs_rename (&rd);if (!host_err) { host_err =commit_metadata (tfhp);if (!host_err)
fs/overlayfs/overlayfs.h +8 -1
@@ -212,9 +212,16 @@ static inline int ovl_do_rename(struct inode *olddir, struct dentry *olddentry, unsigned int flags) {int err; +struct renamedata rd = { + .old_dir = olddir, + .old_dentry = olddentry, + .new_dir = newdir, + .new_dentry = newdentry, + .flags = flags, + };pr_debug ("rename(%pd2, %pd2, 0x%x)\n" , olddentry, newdentry, flags); - err =vfs_rename (olddir, olddentry, newdir, newdentry,NULL , flags); + err =vfs_rename (&rd);if (err) {pr_debug ("...rename(%pd2, %pd2, ...) = %i\n" , olddentry, newdentry, err);
include/linux/fs.h +11 -1
@@ -1780,7 +1780,17 @@ extern int vfs_symlink(struct inode *, struct dentry *, const char *);extern int vfs_link (struct dentry *,struct inode *,struct dentry *,struct inode **);extern int vfs_rmdir (struct inode *,struct dentry *);extern int vfs_unlink (struct inode *,struct dentry *,struct inode **); -extern int vfs_rename (struct inode *,struct dentry *,struct inode *,struct dentry *,struct inode **,unsigned int ); + +struct renamedata { +struct inode *old_dir; +struct dentry *old_dentry; +struct inode *new_dir; +struct dentry *new_dentry; +struct inode **delegated_inode; +unsigned int flags; +} __randomize_layout; + +int vfs_rename (struct renamedata *);static inline int vfs_whiteout (struct inode *dir,struct dentry *dentry) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 197/770 NFSD: Extract the svcxdr_init_encode() helper
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit bddfdbcddbe267519cd36aeb115fdf8620980111 ]
NFSD initializes an encode xdr_stream only after the RPC layer has already inserted the RPC Reply header. Thus it behaves differently than xdr_init_encode does, which assumes the passed-in xdr_buf is entirely devoid of content.
nfs4proc.c has this server-side stream initialization helper, but it is visible only to the NFSv4 code. Move this helper to a place that can be accessed by NFSv2 and NFSv3 server XDR functions.
--- fs/nfsd/nfs4proc.c | 31 +++-------- fs/nfsd/nfs4state.c | 6 +- fs/nfsd/nfs4xdr.c | 110 ++++++++++++++++++------------------- fs/nfsd/nfssvc.c | 4 +- fs/nfsd/xdr4.h | 2 +- include/linux/sunrpc/svc.h | 25 +++++++++ 6 files changed, 94 insertions(+), 84 deletions(-)
fs/nfsd/nfs4proc.c +8 -23
@@ -2256,25 +2256,6 @@ static bool need_wrongsec_check(struct svc_rqst *rqstp)return !(nextd->op_flags &OP_HANDLES_WRONGSEC ); } -static void svcxdr_init_encode (struct svc_rqst *rqstp, -struct nfsd4_compoundres *resp) -{ -struct xdr_stream *xdr = &resp->xdr; -struct xdr_buf *buf = &rqstp->rq_res; -struct kvec *head = buf->head; - - xdr->buf = buf; - xdr->iov = head; - xdr->p = head->iov_base + head->iov_len; - xdr->end = head->iov_base +PAGE_SIZE - rqstp->rq_auth_slack; -/* Tail and page_len should be zero at this point: */ - buf->len = buf->head[0 ].iov_len; -xdr_reset_scratch_buffer (xdr); - xdr->page_ptr = buf->pages -1 ; - buf->buflen =PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages) - - rqstp->rq_auth_slack; -} -#ifdef CONFIG_NFSD_V4_2_INTER_SSC static void check_if_stalefh_allowed (struct nfsd4_compoundargs *args)
@@ -2329,10 +2310,14 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);__be32 status; -svcxdr_init_encode (rqstp, resp); - resp->tagp = resp->xdr.p; + resp->xdr = &rqstp->rq_res_stream; + +/* reserve space for: NFS status code */ +xdr_reserve_space (resp->xdr,XDR_UNIT ); + + resp->tagp = resp->xdr->p;/* reserve space for: taglen, tag, and opcnt */ -xdr_reserve_space (&resp->xdr,8 + args->taglen); +xdr_reserve_space (resp->xdr,XDR_UNIT *2 + args->taglen); resp->taglen = args->taglen; resp->tag = args->tag; resp->rqstp = rqstp;
@@ -2438,7 +2423,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) encode_op:if (op->status == nfserr_replay_me) { op->replay = &cstate->replay_owner->so_replay; -nfsd4_encode_replay (&resp->xdr, op); +nfsd4_encode_replay (resp->xdr, op); status = op->status = op->replay->rp_status; }else {nfsd4_encode_operation (resp, op);
fs/nfsd/nfs4state.c +3 -3
@@ -2925,7 +2925,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rstatic void nfsd4_store_cache_entry (struct nfsd4_compoundres *resp) { -struct xdr_buf *buf = resp->xdr.buf; +struct xdr_buf *buf = resp->xdr->buf;struct nfsd4_slot *slot = resp->cstate.slot;unsigned int base;
@@ -2995,7 +2995,7 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, struct nfsd4_sequence *seq) {struct nfsd4_slot *slot = resp->cstate.slot; -struct xdr_stream *xdr = &resp->xdr; +struct xdr_stream *xdr = resp->xdr;__be32 *p;__be32 status;
@@ -3740,7 +3740,7 @@ nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, {struct nfsd4_sequence *seq = &u->sequence;struct nfsd4_compoundres *resp = rqstp->rq_resp; -struct xdr_stream *xdr = &resp->xdr; +struct xdr_stream *xdr = resp->xdr;struct nfsd4_session *session;struct nfs4_client *clp;struct nfsd4_slot *slot;
fs/nfsd/nfs4xdr.c +55 -55
431 lines not on this page · raw message
fs/nfsd/nfssvc.c +2 -2
@@ -1030,7 +1030,7 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)* NFSv4 does some encoding while processing */ p = resv->iov_base + resv->iov_len; - resv->iov_len +=sizeof (__be32); +svcxdr_init_encode (rqstp); *statp = proc->pc_func (rqstp);if (*statp == rpc_drop_reply ||test_bit (RQ_DROPME , &rqstp->rq_flags))
@@ -1085,7 +1085,7 @@ int nfssvc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p)*/ int nfssvc_encode_voidres (struct svc_rqst *rqstp,__be32 *p) { -return xdr_ressize_check (rqstp, p); +return 1 ; }int nfsd_pool_stats_open (struct inode *inode,struct file *file)
fs/nfsd/xdr4.h +1 -1
@@ -698,7 +698,7 @@ struct nfsd4_compoundargs {struct nfsd4_compoundres {/* scratch variables for XDR encode */ -struct xdr_stream xdr; +struct xdr_stream *xdr;struct svc_rqst * rqstp;u32 taglen;
include/linux/sunrpc/svc.h +25 -0
@@ -248,6 +248,7 @@ struct svc_rqst {size_t rq_xprt_hlen;/* xprt header len */ struct xdr_buf rq_arg;struct xdr_stream rq_arg_stream; +struct xdr_stream rq_res_stream;struct page *rq_scratch_page;struct xdr_buf rq_res;struct page *rq_pages[RPCSVC_MAXPAGES +1 ];
@@ -574,4 +575,28 @@ static inline void svcxdr_init_decode(struct svc_rqst *rqstp) xdr_set_scratch_page(xdr, rqstp->rq_scratch_page); } +/** +* svcxdr_init_encode - Prepare an xdr_stream for svc Reply encoding +* @rqstp: controlling server RPC transaction context +* +*/ +static inline void svcxdr_init_encode (struct svc_rqst *rqstp) +{ +struct xdr_stream *xdr = &rqstp->rq_res_stream; +struct xdr_buf *buf = &rqstp->rq_res; +struct kvec *resv = buf->head; + +xdr_reset_scratch_buffer (xdr); + + xdr->buf = buf; + xdr->iov = resv; + xdr->p = resv->iov_base + resv->iov_len; + xdr->end = resv->iov_base +PAGE_SIZE - rqstp->rq_auth_slack; + buf->len = resv->iov_len; + xdr->page_ptr = buf->pages -1 ; + buf->buflen =PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages); + buf->buflen -= rqstp->rq_auth_slack; + xdr->rqst =NULL ; +} +#endif /* SUNRPC_SVC_H */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 198/770 NFSD: Update the GETATTR3res encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 2c42f804d30f6a8d86665eca84071b316821ea08 ]
As an additional clean up, some renaming is done to more closely reflect the data type and variable names used in the NFSv3 XDR definition provided in RFC 1813. "attrstat" is an NFSv2 thingie.
--- fs/nfsd/nfs3proc.c | 2 +- fs/nfsd/nfs3xdr.c | 95 ++++++++++++++++++++++++++++++++++++++++++---- fs/nfsd/nfsfh.c | 2 +- fs/nfsd/nfsfh.h | 2 +- fs/nfsd/xdr3.h | 2 +- 5 files changed, 91 insertions(+), 12 deletions(-)
fs/nfsd/nfs3proc.c +1 -1
@@ -741,7 +741,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { [NFS3PROC_GETATTR] = { .pc_func = nfsd3_proc_getattr, .pc_decode = nfs3svc_decode_fhandleargs, - .pc_encode = nfs3svc_encode_attrstatres, + .pc_encode = nfs3svc_encode_getattrres, .pc_release = nfs3svc_release_fhandle, .pc_argsize = sizeof(struct nfsd_fhandle), .pc_ressize = sizeof(struct nfsd3_attrstatres),
fs/nfsd/nfs3xdr.c +87 -8
129 lines not on this page · raw message
fs/nfsd/nfsfh.c +1 -1
@@ -710,7 +710,7 @@ char * SVCFH_fmt(struct svc_fh *fhp)return buf; } -enum fsid_source fsid_source (struct svc_fh *fhp) +enum fsid_source fsid_source (const struct svc_fh *fhp) {if (fhp->fh_handle.fh_version !=1 )return FSIDSOURCE_DEV ;
fs/nfsd/nfsfh.h +1 -1
@@ -82,7 +82,7 @@ enum fsid_source {FSIDSOURCE_FSID , FSIDSOURCE_UUID, }; -extern enum fsid_source fsid_source (struct svc_fh *fhp); +extern enum fsid_source fsid_source (const struct svc_fh *fhp);/*
fs/nfsd/xdr3.h +1 -1
@@ -280,7 +280,7 @@ int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *);int nfs3svc_decode_readdirargs (struct svc_rqst *,__be32 *);int nfs3svc_decode_readdirplusargs (struct svc_rqst *,__be32 *);int nfs3svc_decode_commitargs (struct svc_rqst *,__be32 *); -int nfs3svc_encode_attrstat (struct svc_rqst *,__be32 *); +int nfs3svc_encode_getattrres (struct svc_rqst *,__be32 *);int nfs3svc_encode_wccstat (struct svc_rqst *,__be32 *);int nfs3svc_encode_diropres (struct svc_rqst *,__be32 *);int nfs3svc_encode_accessres (struct svc_rqst *,__be32 *);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 199/770 NFSD: Update the NFSv3 ACCESS3res encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 907c38227fb57f5c537491ca76dd0b9636029393 ]
--- fs/nfsd/nfs3xdr.c | 50 ++++++++++++++++++++++++++++++++++++++++++----- fs/nfsd/vfs.h | 2 +- 2 files changed, 46 insertions(+), 6 deletions(-)
fs/nfsd/nfs3xdr.c +45 -5
@@ -383,6 +383,35 @@ encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)return encode_fattr3 (rqstp, p, fhp, &fhp->fh_post_attr); } +static bool +svcxdr_encode_post_op_attr (struct svc_rqst *rqstp,struct xdr_stream *xdr, +const struct svc_fh *fhp) +{ +struct dentry *dentry = fhp->fh_dentry; +struct kstat stat; + +/* +* The inode may be NULL if the call failed because of a +* stale file handle. In this case, no attributes are +* returned. +*/ +if (fhp->fh_no_wcc || !dentry || !d_really_is_positive (dentry)) + goto no_post_op_attrs; +if (fh_getattr (fhp, &stat) != nfs_ok) + goto no_post_op_attrs; + +if (xdr_stream_encode_item_present (xdr) <0 ) +return false; +lease_get_mtime (d_inode (dentry), &stat.mtime); +if (!svcxdr_encode_fattr3 (rqstp, xdr, fhp, &stat)) +return false; + +return true; + +no_post_op_attrs: +return xdr_stream_encode_item_absent (xdr) >0 ; +} +/* * Encode post-operation attributes. * The inode may be NULL if the call failed because of a stale file
@@ -835,13 +864,24 @@ nfs3svc_encode_diropres(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_encode_accessres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd3_accessres *resp = rqstp->rq_resp; - *p++ = resp->status; - p =encode_post_op_attr (rqstp, p, &resp->fh); -if (resp->status ==0 ) - *p++ =htonl (resp->access); -return xdr_ressize_check (rqstp, p); +if (!svcxdr_encode_nfsstat3 (xdr, resp->status)) +return 0 ; +switch (resp->status) { +case nfs_ok: +if (!svcxdr_encode_post_op_attr (rqstp, xdr, &resp->fh)) +return 0 ; +if (xdr_stream_encode_u32 (xdr, resp->access) <0 ) +return 0 ; +break ; +default : +if (!svcxdr_encode_post_op_attr (rqstp, xdr, &resp->fh)) +return 0 ; + } + +return 1 ; }/* READLINK */
fs/nfsd/vfs.h +1 -1
@@ -152,7 +152,7 @@ static inline void fh_drop_write(struct svc_fh *fh) } } -static inline __be32 fh_getattr (struct svc_fh *fh,struct kstat *stat) +static inline __be32 fh_getattr (const struct svc_fh *fh,struct kstat *stat) {struct path p = {.mnt = fh->fh_export->ex_path.mnt, .dentry = fh->fh_dentry};
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 200/770 NFSD: Update the NFSv3 LOOKUP3res encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 5cf353354af1a385f29dec4609a1532d32c83a25 ]
Also, clean up: Rename the encoder function to match the name of the result structure in RFC 1813, consistent with other encoder function names in nfs3xdr.c. "diropres" is an NFSv2 thingie.
--- fs/nfsd/nfs3proc.c | 2 +- fs/nfsd/nfs3xdr.c | 43 +++++++++++++++++++++++++++++++++++-------- fs/nfsd/xdr3.h | 2 +- 3 files changed, 37 insertions(+), 10 deletions(-)
fs/nfsd/nfs3proc.c +1 -1
@@ -763,7 +763,7 @@ static const struct svc_procedure nfsd_procedures3[22] = { [NFS3PROC_LOOKUP] = { .pc_func = nfsd3_proc_lookup, .pc_decode = nfs3svc_decode_diropargs, - .pc_encode = nfs3svc_encode_diropres, + .pc_encode = nfs3svc_encode_lookupres, .pc_release = nfs3svc_release_fhandle2, .pc_argsize = sizeof(struct nfsd3_diropargs), .pc_ressize = sizeof(struct nfsd3_diropres),
fs/nfsd/nfs3xdr.c +35 -8
59 lines not on this page · raw message
fs/nfsd/xdr3.h +1 -1
@@ -282,7 +282,7 @@ int nfs3svc_decode_readdirplusargs(struct svc_rqst *, __be32 *);int nfs3svc_decode_commitargs (struct svc_rqst *,__be32 *);int nfs3svc_encode_getattrres (struct svc_rqst *,__be32 *);int nfs3svc_encode_wccstat (struct svc_rqst *,__be32 *); -int nfs3svc_encode_diropres (struct svc_rqst *,__be32 *); +int nfs3svc_encode_lookupres (struct svc_rqst *,__be32 *);int nfs3svc_encode_accessres (struct svc_rqst *,__be32 *);int nfs3svc_encode_readlinkres (struct svc_rqst *,__be32 *);int nfs3svc_encode_readres (struct svc_rqst *,__be32 *);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 201/770 NFSD: Update the NFSv3 wccstat result encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 70f8e839859a994e324e1d18889f8319bbd5bff9 ]
--- fs/nfsd/nfs3xdr.c | 68 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 3 deletions(-)
fs/nfsd/nfs3xdr.c +65 -3
@@ -400,6 +400,35 @@ encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)return encode_fattr3 (rqstp, p, fhp, &fhp->fh_post_attr); } +static bool +svcxdr_encode_wcc_attr (struct xdr_stream *xdr,const struct svc_fh *fhp) +{ +__be32 *p; + + p =xdr_reserve_space (xdr,XDR_UNIT *6 ); +if (!p) +return false; + p =xdr_encode_hyper (p, (u64 )fhp->fh_pre_size); + p =encode_nfstime3 (p, &fhp->fh_pre_mtime); +encode_nfstime3 (p, &fhp->fh_pre_ctime); + +return true; +} + +static bool +svcxdr_encode_pre_op_attr (struct xdr_stream *xdr,const struct svc_fh *fhp) +{ +if (!fhp->fh_pre_saved) { +if (xdr_stream_encode_item_absent (xdr) <0 ) +return false; +return true; + } + +if (xdr_stream_encode_item_present (xdr) <0 ) +return false; +return svcxdr_encode_wcc_attr (xdr, fhp); +} +static bool svcxdr_encode_post_op_attr (struct svc_rqst *rqstp,struct xdr_stream *xdr,const struct svc_fh *fhp)
@@ -460,6 +489,39 @@ nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhreturn encode_post_op_attr (rqstp, p, fhp); } +/* +* Encode weak cache consistency data +*/ +static bool +svcxdr_encode_wcc_data (struct svc_rqst *rqstp,struct xdr_stream *xdr, +const struct svc_fh *fhp) +{ +struct dentry *dentry = fhp->fh_dentry; + +if (!dentry || !d_really_is_positive (dentry) || !fhp->fh_post_saved) + goto neither; + +/* before */ +if (!svcxdr_encode_pre_op_attr (xdr, fhp)) +return false; + +/* after */ +if (xdr_stream_encode_item_present (xdr) <0 ) +return false; +if (!svcxdr_encode_fattr3 (rqstp, xdr, fhp, &fhp->fh_post_attr)) +return false; + +return true; + +neither: +if (xdr_stream_encode_item_absent (xdr) <0 ) +return false; +if (!svcxdr_encode_post_op_attr (rqstp, xdr, fhp)) +return false; + +return true; +} +/* * Enocde weak cache consistency data */
@@ -855,11 +917,11 @@ nfs3svc_encode_getattrres(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_encode_wccstat (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd3_attrstat *resp = rqstp->rq_resp; - *p++ = resp->status; - p =encode_wcc_data (rqstp, p, &resp->fh); -return xdr_ressize_check (rqstp, p); +return svcxdr_encode_nfsstat3 (xdr, resp->status) && +svcxdr_encode_wcc_data (rqstp, xdr, &resp->fh); }/* LOOKUP */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 202/770 NFSD: Update the NFSv3 READLINK3res encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 9a9c8923b3efd593d0e6a405efef9d58c6e6804b ]
--- fs/nfsd/nfs3proc.c | 5 +++-- fs/nfsd/nfs3xdr.c | 34 ++++++++++++++++++---------------- fs/nfsd/xdr3.h | 1 + 3 files changed, 22 insertions(+), 18 deletions(-)
fs/nfsd/nfs3proc.c +3 -2
@@ -126,14 +126,15 @@ nfsd3_proc_readlink(struct svc_rqst *rqstp) {struct nfsd_fhandle *argp = rqstp->rq_argp;struct nfsd3_readlinkres *resp = rqstp->rq_resp; -char *buffer =page_address (*(rqstp->rq_next_page++));dprintk ("nfsd: READLINK(3) %s\n" ,SVCFH_fmt (&argp->fh));/* Read the symlink. */ fh_copy (&resp->fh, &argp->fh); resp->len =NFS3_MAXPATHLEN ; - resp->status =nfsd_readlink (rqstp, &resp->fh, buffer, &resp->len); + resp->pages = rqstp->rq_next_page++; + resp->status =nfsd_readlink (rqstp, &resp->fh, +page_address (*resp->pages), &resp->len);return rpc_success; }
fs/nfsd/nfs3xdr.c +18 -16
@@ -977,26 +977,28 @@ nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_encode_readlinkres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd3_readlinkres *resp = rqstp->rq_resp;struct kvec *head = rqstp->rq_res.head; - *p++ = resp->status; - p =encode_post_op_attr (rqstp, p, &resp->fh); -if (resp->status ==0 ) { - *p++ =htonl (resp->len); -xdr_ressize_check (rqstp, p); - rqstp->rq_res.page_len = resp->len; -if (resp->len &3 ) { -/* need to pad the tail */ - rqstp->rq_res.tail[0 ].iov_base = p; - *p =0 ; - rqstp->rq_res.tail[0 ].iov_len =4 - (resp->len&3 ); - } -if (svc_encode_result_payload (rqstp, head->iov_len, resp->len)) +if (!svcxdr_encode_nfsstat3 (xdr, resp->status)) +return 0 ; +switch (resp->status) { +case nfs_ok: +if (!svcxdr_encode_post_op_attr (rqstp, xdr, &resp->fh))return 0 ; -return 1 ; - }else -return xdr_ressize_check (rqstp, p); +if (xdr_stream_encode_u32 (xdr, resp->len) <0 ) +return 0 ; +xdr_write_pages (xdr, resp->pages,0 , resp->len); +if (svc_encode_result_payload (rqstp, head->iov_len, resp->len) <0 ) +return 0 ; +break ; +default : +if (!svcxdr_encode_post_op_attr (rqstp, xdr, &resp->fh)) +return 0 ; + } + +return 1 ; }/* READ */
fs/nfsd/xdr3.h +1 -0
@@ -137,6 +137,7 @@ struct nfsd3_readlinkres {__be32 status;struct svc_fh fh;__u32 len; +struct page **pages; };struct nfsd3_readres {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 203/770 NFSD: Update the NFSv3 READ3res encode to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit cc9bcdad7773c295375e66c892c7ac00524706f2 ]
--- fs/nfsd/nfs3proc.c | 1 + fs/nfsd/nfs3xdr.c | 43 ++++++++++++++++++++------------------ fs/nfsd/xdr3.h | 1 + include/linux/sunrpc/xdr.h | 20 ++++++++++++++++++ 4 files changed, 45 insertions(+), 20 deletions(-)
fs/nfsd/nfs3proc.c +1 -0
@@ -159,6 +159,7 @@ nfsd3_proc_read(struct svc_rqst *rqstp) v =0 ; len = argp->count; + resp->pages = rqstp->rq_next_page;while (len >0 ) {struct page *page = *(rqstp->rq_next_page++);
fs/nfsd/nfs3xdr.c +23 -20
53 lines not on this page · raw message
fs/nfsd/xdr3.h +1 -0
@@ -145,6 +145,7 @@ struct nfsd3_readres {struct svc_fh fh;unsigned long count;__u32 eof; +struct page **pages; };struct nfsd3_writeres {
include/linux/sunrpc/xdr.h +20 -0
@@ -394,6 +394,26 @@ static inline int xdr_stream_encode_item_absent(struct xdr_stream *xdr)return len; } +/** +* xdr_stream_encode_bool - Encode a "not present" list item +* @xdr: pointer to xdr_stream +* @n: boolean value to encode +* +* Return values: +* On success, returns length in bytes of XDR buffer consumed +* %-EMSGSIZE on XDR buffer overflow +*/ +static inline int xdr_stream_encode_bool (struct xdr_stream *xdr,__u32 n) +{ +const size_t len =XDR_UNIT ; +__be32 *p =xdr_reserve_space (xdr, len); + +if (unlikely (!p)) +return -EMSGSIZE ; + *p = n ? xdr_one : xdr_zero; +return len; +} +/** * xdr_stream_encode_u32 - Encode a 32-bit integer * @xdr: pointer to xdr_stream
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 204/770 NFSD: Update the NFSv3 WRITE3res encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit ecb7a085ac15a8844ebf12fca6ae51ce71ac9b3b ]
--- fs/nfsd/nfs3xdr.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-)
fs/nfsd/nfs3xdr.c +32 -8
@@ -131,6 +131,19 @@ encode_fh(__be32 *p, struct svc_fh *fhp)return p +XDR_QUADLEN (size); } +static bool +svcxdr_encode_writeverf3 (struct xdr_stream *xdr,const __be32 *verf) +{ +__be32 *p; + + p =xdr_reserve_space (xdr,NFS3_WRITEVERFSIZE ); +if (!p) +return false; +memcpy (p, verf,NFS3_WRITEVERFSIZE ); + +return true; +} +static bool svcxdr_decode_filename3 (struct xdr_stream *xdr,char **name,unsigned int *len) {
@@ -1038,17 +1051,28 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_encode_writeres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd3_writeres *resp = rqstp->rq_resp; - *p++ = resp->status; - p =encode_wcc_data (rqstp, p, &resp->fh); -if (resp->status ==0 ) { - *p++ =htonl (resp->count); - *p++ =htonl (resp->committed); - *p++ = resp->verf[0 ]; - *p++ = resp->verf[1 ]; +if (!svcxdr_encode_nfsstat3 (xdr, resp->status)) +return 0 ; +switch (resp->status) { +case nfs_ok: +if (!svcxdr_encode_wcc_data (rqstp, xdr, &resp->fh)) +return 0 ; +if (xdr_stream_encode_u32 (xdr, resp->count) <0 ) +return 0 ; +if (xdr_stream_encode_u32 (xdr, resp->committed) <0 ) +return 0 ; +if (!svcxdr_encode_writeverf3 (xdr, resp->verf)) +return 0 ; +break ; +default : +if (!svcxdr_encode_wcc_data (rqstp, xdr, &resp->fh)) +return 0 ; } -return xdr_ressize_check (rqstp, p); + +return 1 ; }/* CREATE, MKDIR, SYMLINK, MKNOD */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 205/770 NFSD: Update the NFSv3 CREATE family of encoders to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 78315b36781d259dcbdc102ff22c3f2f25712223 ]
--- fs/nfsd/nfs3xdr.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-)
fs/nfsd/nfs3xdr.c +28 -7
@@ -121,6 +121,17 @@ svcxdr_encode_nfs_fh3(struct xdr_stream *xdr, const struct svc_fh *fhp)return true; } +static bool +svcxdr_encode_post_op_fh3 (struct xdr_stream *xdr,const struct svc_fh *fhp) +{ +if (xdr_stream_encode_item_present (xdr) <0 ) +return false; +if (!svcxdr_encode_nfs_fh3 (xdr, fhp)) +return false; + +return true; +} +static __be32 *encode_fh (__be32 *p,struct svc_fh *fhp) {
@@ -1079,16 +1090,26 @@ nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_encode_createres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd3_diropres *resp = rqstp->rq_resp; - *p++ = resp->status; -if (resp->status ==0 ) { - *p++ = xdr_one; - p =encode_fh (p, &resp->fh); - p =encode_post_op_attr (rqstp, p, &resp->fh); +if (!svcxdr_encode_nfsstat3 (xdr, resp->status)) +return 0 ; +switch (resp->status) { +case nfs_ok: +if (!svcxdr_encode_post_op_fh3 (xdr, &resp->fh)) +return 0 ; +if (!svcxdr_encode_post_op_attr (rqstp, xdr, &resp->fh)) +return 0 ; +if (!svcxdr_encode_wcc_data (rqstp, xdr, &resp->dirfh)) +return 0 ; +break ; +default : +if (!svcxdr_encode_wcc_data (rqstp, xdr, &resp->dirfh)) +return 0 ; } - p =encode_wcc_data (rqstp, p, &resp->dirfh); -return xdr_ressize_check (rqstp, p); + +return 1 ; }/* RENAME */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 206/770 NFSD: Update the NFSv3 RENAMEv3res encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 89d79e9672dfa6d0cc416699c16f2d312da58ff2 ]
--- fs/nfsd/nfs3xdr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/nfsd/nfs3xdr.c +4 -4
@@ -1116,12 +1116,12 @@ nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_encode_renameres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd3_renameres *resp = rqstp->rq_resp; - *p++ = resp->status; - p =encode_wcc_data (rqstp, p, &resp->ffh); - p =encode_wcc_data (rqstp, p, &resp->tfh); -return xdr_ressize_check (rqstp, p); +return svcxdr_encode_nfsstat3 (xdr, resp->status) && +svcxdr_encode_wcc_data (rqstp, xdr, &resp->ffh) && +svcxdr_encode_wcc_data (rqstp, xdr, &resp->tfh); }/* LINK */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 207/770 NFSD: Update the NFSv3 LINK3res encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 4d74380a446f75eebb2171687d9b8baf0025bdf1 ]
--- fs/nfsd/nfs3xdr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/nfsd/nfs3xdr.c +4 -4
@@ -1128,12 +1128,12 @@ nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_encode_linkres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd3_linkres *resp = rqstp->rq_resp; - *p++ = resp->status; - p =encode_post_op_attr (rqstp, p, &resp->fh); - p =encode_wcc_data (rqstp, p, &resp->tfh); -return xdr_ressize_check (rqstp, p); +return svcxdr_encode_nfsstat3 (xdr, resp->status) && +svcxdr_encode_post_op_attr (rqstp, xdr, &resp->fh) && +svcxdr_encode_wcc_data (rqstp, xdr, &resp->tfh); }/* READDIR */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 208/770 NFSD: Update the NFSv3 FSSTAT3res encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 8b7044984fd6eeadf72285e3617116bd15e9e676 ]
--- fs/nfsd/nfs3xdr.c | 58 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 14 deletions(-)
fs/nfsd/nfs3xdr.c +44 -14
@@ -17,6 +17,13 @@#define NFSDDBG_FACILITY NFSDDBG_XDR +/* +* Force construction of an empty post-op attr +*/ +static const struct svc_fh nfs3svc_null_fh = { + .fh_no_wcc = true, +}; +/* * Mapping of S_IF* types to NFS file types */
@@ -1392,27 +1399,50 @@ nfs3svc_encode_entry_plus(void *cd, const char *name,return encode_entry (cd, name, namlen, offset, ino, d_type,1 ); } +static bool +svcxdr_encode_fsstat3resok (struct xdr_stream *xdr, +const struct nfsd3_fsstatres *resp) +{ +const struct kstatfs *s = &resp->stats; +u64 bs = s->f_bsize; +__be32 *p; + + p =xdr_reserve_space (xdr,XDR_UNIT *13 ); +if (!p) +return false; + p =xdr_encode_hyper (p, bs * s->f_blocks);/* total bytes */ + p =xdr_encode_hyper (p, bs * s->f_bfree);/* free bytes */ + p =xdr_encode_hyper (p, bs * s->f_bavail);/* user available bytes */ + p =xdr_encode_hyper (p, s->f_files);/* total inodes */ + p =xdr_encode_hyper (p, s->f_ffree);/* free inodes */ + p =xdr_encode_hyper (p, s->f_ffree);/* user available inodes */ + *p =cpu_to_be32 (resp->invarsec);/* mean unchanged time */ + +return true; +} +/* FSSTAT */ int nfs3svc_encode_fsstatres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd3_fsstatres *resp = rqstp->rq_resp; -struct kstatfs *s = &resp->stats; -u64 bs = s->f_bsize; - *p++ = resp->status; - *p++ = xdr_zero;/* no post_op_attr */ - -if (resp->status ==0 ) { - p =xdr_encode_hyper (p, bs * s->f_blocks);/* total bytes */ - p =xdr_encode_hyper (p, bs * s->f_bfree);/* free bytes */ - p =xdr_encode_hyper (p, bs * s->f_bavail);/* user available bytes */ - p =xdr_encode_hyper (p, s->f_files);/* total inodes */ - p =xdr_encode_hyper (p, s->f_ffree);/* free inodes */ - p =xdr_encode_hyper (p, s->f_ffree);/* user available inodes */ - *p++ =htonl (resp->invarsec);/* mean unchanged time */ +if (!svcxdr_encode_nfsstat3 (xdr, resp->status)) +return 0 ; +switch (resp->status) { +case nfs_ok: +if (!svcxdr_encode_post_op_attr (rqstp, xdr, &nfs3svc_null_fh)) +return 0 ; +if (!svcxdr_encode_fsstat3resok (xdr, resp)) +return 0 ; +break ; +default : +if (!svcxdr_encode_post_op_attr (rqstp, xdr, &nfs3svc_null_fh)) +return 0 ; } -return xdr_ressize_check (rqstp, p); + +return 1 ; }/* FSINFO */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 209/770 NFSD: Update the NFSv3 FSINFO3res encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 0a139d1b7f327010acc36e8162936d3108c7addb ]
--- fs/nfsd/nfs3xdr.c | 62 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 16 deletions(-)
fs/nfsd/nfs3xdr.c +46 -16
@@ -24,6 +24,15 @@ static const struct svc_fh nfs3svc_null_fh = { .fh_no_wcc = true, }; +/* +* time_delta. {1, 0} means the server is accurate only +* to the nearest second. +*/ +static const struct timespec64 nfs3svc_time_delta = { + .tv_sec =1 , + .tv_nsec =0 , +}; +/* * Mapping of S_IF* types to NFS file types */
@@ -1445,30 +1454,51 @@ nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p)return 1 ; } +static bool +svcxdr_encode_fsinfo3resok (struct xdr_stream *xdr, +const struct nfsd3_fsinfores *resp) +{ +__be32 *p; + + p =xdr_reserve_space (xdr,XDR_UNIT *12 ); +if (!p) +return false; + *p++ =cpu_to_be32 (resp->f_rtmax); + *p++ =cpu_to_be32 (resp->f_rtpref); + *p++ =cpu_to_be32 (resp->f_rtmult); + *p++ =cpu_to_be32 (resp->f_wtmax); + *p++ =cpu_to_be32 (resp->f_wtpref); + *p++ =cpu_to_be32 (resp->f_wtmult); + *p++ =cpu_to_be32 (resp->f_dtpref); + p =xdr_encode_hyper (p, resp->f_maxfilesize); + p =encode_nfstime3 (p, &nfs3svc_time_delta); + *p =cpu_to_be32 (resp->f_properties); + +return true; +} +/* FSINFO */ int nfs3svc_encode_fsinfores (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd3_fsinfores *resp = rqstp->rq_resp; - *p++ = resp->status; - *p++ = xdr_zero;/* no post_op_attr */ - -if (resp->status ==0 ) { - *p++ =htonl (resp->f_rtmax); - *p++ =htonl (resp->f_rtpref); - *p++ =htonl (resp->f_rtmult); - *p++ =htonl (resp->f_wtmax); - *p++ =htonl (resp->f_wtpref); - *p++ =htonl (resp->f_wtmult); - *p++ =htonl (resp->f_dtpref); - p =xdr_encode_hyper (p, resp->f_maxfilesize); - *p++ = xdr_one; - *p++ = xdr_zero; - *p++ =htonl (resp->f_properties); +if (!svcxdr_encode_nfsstat3 (xdr, resp->status)) +return 0 ; +switch (resp->status) { +case nfs_ok: +if (!svcxdr_encode_post_op_attr (rqstp, xdr, &nfs3svc_null_fh)) +return 0 ; +if (!svcxdr_encode_fsinfo3resok (xdr, resp)) +return 0 ; +break ; +default : +if (!svcxdr_encode_post_op_attr (rqstp, xdr, &nfs3svc_null_fh)) +return 0 ; } -return xdr_ressize_check (rqstp, p); +return 1 ; }/* PATHCONF */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 210/770 NFSD: Update the NFSv3 PATHCONF3res encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit ded04a587f6ceaaba3caefad4021f2212b46c9ff ]
--- fs/nfsd/nfs3xdr.c | 44 ++++++++++++++++++++++++++++---------- include/linux/sunrpc/xdr.h | 18 ++++++++++++++-- 2 files changed, 49 insertions(+), 13 deletions(-)
fs/nfsd/nfs3xdr.c +33 -11
@@ -1501,25 +1501,47 @@ nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p)return 1 ; } +static bool +svcxdr_encode_pathconf3resok (struct xdr_stream *xdr, +const struct nfsd3_pathconfres *resp) +{ +__be32 *p; + + p =xdr_reserve_space (xdr,XDR_UNIT *6 ); +if (!p) +return false; + *p++ =cpu_to_be32 (resp->p_link_max); + *p++ =cpu_to_be32 (resp->p_name_max); + p =xdr_encode_bool (p, resp->p_no_trunc); + p =xdr_encode_bool (p, resp->p_chown_restricted); + p =xdr_encode_bool (p, resp->p_case_insensitive); +xdr_encode_bool (p, resp->p_case_preserving); + +return true; +} +/* PATHCONF */ int nfs3svc_encode_pathconfres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd3_pathconfres *resp = rqstp->rq_resp; - *p++ = resp->status; - *p++ = xdr_zero;/* no post_op_attr */ - -if (resp->status ==0 ) { - *p++ =htonl (resp->p_link_max); - *p++ =htonl (resp->p_name_max); - *p++ =htonl (resp->p_no_trunc); - *p++ =htonl (resp->p_chown_restricted); - *p++ =htonl (resp->p_case_insensitive); - *p++ =htonl (resp->p_case_preserving); +if (!svcxdr_encode_nfsstat3 (xdr, resp->status)) +return 0 ; +switch (resp->status) { +case nfs_ok: +if (!svcxdr_encode_post_op_attr (rqstp, xdr, &nfs3svc_null_fh)) +return 0 ; +if (!svcxdr_encode_pathconf3resok (xdr, resp)) +return 0 ; +break ; +default : +if (!svcxdr_encode_post_op_attr (rqstp, xdr, &nfs3svc_null_fh)) +return 0 ; } -return xdr_ressize_check (rqstp, p); +return 1 ; }/* COMMIT */
include/linux/sunrpc/xdr.h +16 -2
@@ -395,7 +395,21 @@ static inline int xdr_stream_encode_item_absent(struct xdr_stream *xdr) }/** -* xdr_stream_encode_bool - Encode a "not present" list item +* xdr_encode_bool - Encode a boolean item +* @p: address in a buffer into which to encode +* @n: boolean value to encode +* +* Return value: +* Address of item following the encoded boolean +*/ +static inline __be32 *xdr_encode_bool (__be32 *p,u32 n) +{ + *p = n ? xdr_one : xdr_zero; +return p++; +} + +/** +* xdr_stream_encode_bool - Encode a boolean item * @xdr: pointer to xdr_stream * @n: boolean value to encode *
@@ -410,7 +424,7 @@ static inline int xdr_stream_encode_bool(struct xdr_stream *xdr, __u32 n)if (unlikely (!p))return -EMSGSIZE ; - *p = n ? xdr_one : xdr_zero; +xdr_encode_bool (p, n);return len; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 211/770 NFSD: Update the NFSv3 COMMIT3res encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 5ef2826c761079e27904c85034df34e601b82d94 ]
As an additional clean up, encode_wcc_data() is removed because it is now no longer used.
--- fs/nfsd/nfs3xdr.c | 54 +++++++++++++---------------------------------- 1 file changed, 15 insertions(+), 39 deletions(-)
fs/nfsd/nfs3xdr.c +15 -39
@@ -432,14 +432,6 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,return p; } -static __be32 * -encode_saved_post_attr (struct svc_rqst *rqstp,__be32 *p,struct svc_fh *fhp) -{ -/* Attributes to follow */ - *p++ = xdr_one; -return encode_fattr3 (rqstp, p, fhp, &fhp->fh_post_attr); -} -static bool svcxdr_encode_wcc_attr (struct xdr_stream *xdr,const struct svc_fh *fhp) {
@@ -562,30 +554,6 @@ svcxdr_encode_wcc_data(struct svc_rqst *rqstp, struct xdr_stream *xdr,return true; } -/* -* Enocde weak cache consistency data -*/ -static __be32 * -encode_wcc_data (struct svc_rqst *rqstp,__be32 *p,struct svc_fh *fhp) -{ -struct dentry *dentry = fhp->fh_dentry; - -if (dentry &&d_really_is_positive (dentry) && fhp->fh_post_saved) { -if (fhp->fh_pre_saved) { - *p++ = xdr_one; - p =xdr_encode_hyper (p, (u64 ) fhp->fh_pre_size); - p =encode_time3 (p, &fhp->fh_pre_mtime); - p =encode_time3 (p, &fhp->fh_pre_ctime); - }else { - *p++ = xdr_zero; - } -return encode_saved_post_attr (rqstp, p, fhp); - } -/* no pre- or post-attrs */ - *p++ = xdr_zero; -return encode_post_op_attr (rqstp, p, fhp); -} -static bool fs_supports_change_attribute (struct super_block *sb) {return sb->s_flags &SB_I_VERSION || sb->s_export_op->fetch_iversion;
@@ -1548,16 +1516,24 @@ nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p)int nfs3svc_encode_commitres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd3_commitres *resp = rqstp->rq_resp; - *p++ = resp->status; - p =encode_wcc_data (rqstp, p, &resp->fh); -/* Write verifier */ -if (resp->status ==0 ) { - *p++ = resp->verf[0 ]; - *p++ = resp->verf[1 ]; +if (!svcxdr_encode_nfsstat3 (xdr, resp->status)) +return 0 ; +switch (resp->status) { +case nfs_ok: +if (!svcxdr_encode_wcc_data (rqstp, xdr, &resp->fh)) +return 0 ; +if (!svcxdr_encode_writeverf3 (xdr, resp->verf)) +return 0 ; +break ; +default : +if (!svcxdr_encode_wcc_data (rqstp, xdr, &resp->fh)) +return 0 ; } -return xdr_ressize_check (rqstp, p); + +return 1 ; }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 212/770 NFSD: Add a helper that encodes NFSv3 directory offset cookies
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit a161e6c76aeba835e475a2f27dbbe5c37e565e94 ]
Refactor: De-duplicate identical code that handles encoding of directory offset cookies across page boundaries.
--- fs/nfsd/nfs3proc.c | 24 ++---------------------- fs/nfsd/nfs3xdr.c | 36 +++++++++++++++++++++++------------- fs/nfsd/xdr3.h | 2 ++ 3 files changed, 27 insertions(+), 35 deletions(-)
fs/nfsd/nfs3proc.c +2 -22
@@ -500,17 +500,7 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp) count +=PAGE_SIZE ; } resp->count = count >>2 ; -if (resp->offset) { -if (unlikely (resp->offset1)) { -/* we ended up with offset on a page boundary */ - *resp->offset =htonl (offset >>32 ); - *resp->offset1 =htonl (offset &0xffffffff ); - resp->offset1 =NULL ; - }else { -xdr_encode_hyper (resp->offset, offset); - } - resp->offset =NULL ; - } +nfs3svc_encode_cookie3 (resp, offset);return rpc_success; }
@@ -565,17 +555,7 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp) count +=PAGE_SIZE ; } resp->count = count >>2 ; -if (resp->offset) { -if (unlikely (resp->offset1)) { -/* we ended up with offset on a page boundary */ - *resp->offset =htonl (offset >>32 ); - *resp->offset1 =htonl (offset &0xffffffff ); - resp->offset1 =NULL ; - }else { -xdr_encode_hyper (resp->offset, offset); - } - resp->offset =NULL ; - } +nfs3svc_encode_cookie3 (resp, offset); out:return rpc_success;
fs/nfsd/nfs3xdr.c +23 -13
@@ -1219,6 +1219,28 @@ static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p,return p; } +/** +* nfs3svc_encode_cookie3 - Encode a directory offset cookie +* @resp: readdir result context +* @offset: offset cookie to encode +* +*/ +void nfs3svc_encode_cookie3 (struct nfsd3_readdirres *resp,u64 offset) +{ +if (!resp->offset) +return ; + +if (resp->offset1) { +/* we ended up with offset on a page boundary */ + *resp->offset =cpu_to_be32 (offset >>32 ); + *resp->offset1 =cpu_to_be32 (offset &0xffffffff ); + resp->offset1 =NULL ; + }else { +xdr_encode_hyper (resp->offset, offset); + } + resp->offset =NULL ; +} +/* * Encode a directory entry. This one works for both normal readdir * and readdirplus.
@@ -1244,19 +1266,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,int elen;/* estimated entry length in words */ int num_entry_words =0 ;/* actual number of words */ -if (cd->offset) { -u64 offset64 = offset; - -if (unlikely (cd->offset1)) { -/* we ended up with offset on a page boundary */ - *cd->offset =htonl (offset64 >>32 ); - *cd->offset1 =htonl (offset64 &0xffffffff ); - cd->offset1 =NULL ; - }else { -xdr_encode_hyper (cd->offset, offset64); - } - cd->offset =NULL ; - } +nfs3svc_encode_cookie3 (cd, offset);/* dprintk("encode_entry(%.*s @%ld%s)\n",
fs/nfsd/xdr3.h +2 -0
@@ -300,6 +300,8 @@ int nfs3svc_encode_commitres(struct svc_rqst *, __be32 *);void nfs3svc_release_fhandle (struct svc_rqst *);void nfs3svc_release_fhandle2 (struct svc_rqst *); + +void nfs3svc_encode_cookie3 (struct nfsd3_readdirres *resp,u64 offset);int nfs3svc_encode_entry (void *,const char *name,int namlen,loff_t offset,u64 ino,unsigned int );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 213/770 NFSD: Count bytes instead of pages in the NFSv3 READDIR encoder
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit a1409e2de4f11034c8eb30775cc3e37039a4ef13 ]
Clean up: Counting the bytes used by each returned directory entry seems less brittle to me than trying to measure consumed pages after the fact.
--- fs/nfsd/nfs3proc.c | 31 ++----------------------------- fs/nfsd/nfs3xdr.c | 1 + 2 files changed, 3 insertions(+), 29 deletions(-)
fs/nfsd/nfs3proc.c +2 -29
@@ -467,10 +467,7 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp) {struct nfsd3_readdirargs *argp = rqstp->rq_argp;struct nfsd3_readdirres *resp = rqstp->rq_resp; -int count =0 ;loff_t offset; -struct page **p; -caddr_t page_addr =NULL ; dprintk("nfsd: READDIR(3) %s %d bytes at %d\n", SVCFH_fmt(&argp->fh),
@@ -481,6 +478,7 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)/* Read directory and encode entries on the fly */ fh_copy (&resp->fh, &argp->fh); + resp->count =0 ; resp->common.err = nfs_ok; resp->rqstp = rqstp; offset = argp->cookie;
@@ -488,18 +486,6 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp) resp->status =nfsd_readdir (rqstp, &resp->fh, &offset, &resp->common, nfs3svc_encode_entry);memcpy (resp->verf, argp->verf,8 ); - count =0 ; -for (p = rqstp->rq_respages +1 ; p < rqstp->rq_next_page; p++) { - page_addr =page_address (*p); - -if (((caddr_t )resp->buffer >= page_addr) && - ((caddr_t )resp->buffer < page_addr +PAGE_SIZE )) { - count += (caddr_t )resp->buffer - page_addr; -break ; - } - count +=PAGE_SIZE ; - } - resp->count = count >>2 ;nfs3svc_encode_cookie3 (resp, offset);return rpc_success;
@@ -514,10 +500,7 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp) {struct nfsd3_readdirargs *argp = rqstp->rq_argp;struct nfsd3_readdirres *resp = rqstp->rq_resp; -int count =0 ;loff_t offset; -struct page **p; -caddr_t page_addr =NULL ; dprintk("nfsd: READDIR+(3) %s %d bytes at %d\n", SVCFH_fmt(&argp->fh),
@@ -528,6 +511,7 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp)/* Read directory and encode entries on the fly */ fh_copy (&resp->fh, &argp->fh); + resp->count =0 ; resp->common.err = nfs_ok; resp->rqstp = rqstp; offset = argp->cookie;
@@ -544,17 +528,6 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp) resp->status =nfsd_readdir (rqstp, &resp->fh, &offset, &resp->common, nfs3svc_encode_entry_plus);memcpy (resp->verf, argp->verf,8 ); -for (p = rqstp->rq_respages +1 ; p < rqstp->rq_next_page; p++) { - page_addr =page_address (*p); - -if (((caddr_t )resp->buffer >= page_addr) && - ((caddr_t )resp->buffer < page_addr +PAGE_SIZE )) { - count += (caddr_t )resp->buffer - page_addr; -break ; - } - count +=PAGE_SIZE ; - } - resp->count = count >>2 ;nfs3svc_encode_cookie3 (resp, offset); out:
fs/nfsd/nfs3xdr.c +1 -0
@@ -1364,6 +1364,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,return -EINVAL ; } + cd->count += num_entry_words; cd->buflen -= num_entry_words; cd->buffer = p; cd->common.err = nfs_ok;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 214/770 NFSD: Update the NFSv3 READDIR3res encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit e4ccfe3014de435984939a3d84b7f241d3b57b0d ]
--- fs/nfsd/nfs3proc.c | 3 ++- fs/nfsd/nfs3xdr.c | 54 ++++++++++++++++++++++++++++++---------------- fs/nfsd/xdr3.h | 1 + 3 files changed, 38 insertions(+), 20 deletions(-)
fs/nfsd/nfs3proc.c +2 -1
@@ -452,7 +452,8 @@ static void nfsd3_init_dirlist_pages(struct svc_rqst *rqstp,* and reserve room for the NULL ptr & eof flag (-2 words) */ resp->buflen = (count >>2 ) -2 ; - resp->buffer =page_address (*rqstp->rq_next_page); + resp->pages = rqstp->rq_next_page; + resp->buffer =page_address (*resp->pages);while (count >0 ) { rqstp->rq_next_page++; count -=PAGE_SIZE ;
fs/nfsd/nfs3xdr.c +35 -19
68 lines not on this page · raw message
fs/nfsd/xdr3.h +1 -0
@@ -176,6 +176,7 @@ struct nfsd3_readdirres {struct svc_fh scratch;int count;__be32 verf[2 ]; +struct page **pages;struct readdir_cd common;__be32 * buffer;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 215/770 NFSD: Update NFSv3 READDIR entry encoders to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 7f87fc2d34d475225e78b7f5c4eabb121f4282b2 ]
The benefit of the xdr_stream helpers is that they transparently handle encoding an XDR data item that crosses page boundaries. Most of the open-coded logic to do that here can be eliminated.
A sub-buffer and sub-stream are set up as a sink buffer for the directory entry encoder. As an entry is encoded, it is added to the end of the content in this buffer/stream. The total length of the directory list is tracked in the buffer's @len field.
When it comes time to encode the Reply, the sub-buffer is merged into rq_res's page array at the correct place using xdr_write_pages().
--- fs/nfsd/nfs3proc.c | 35 ++++++---- fs/nfsd/nfs3xdr.c | 166 +++++++++++++++++++++++++++++++++++++++++---- fs/nfsd/xdr3.h | 14 ++-- 3 files changed, 185 insertions(+), 30 deletions(-)
fs/nfsd/nfs3proc.c +21 -14
@@ -446,18 +446,30 @@ static void nfsd3_init_dirlist_pages(struct svc_rqst *rqstp, struct nfsd3_readdirres *resp, int count) { +struct xdr_buf *buf = &resp->dirlist; +struct xdr_stream *xdr = &resp->xdr; + count =min_t (u32, count,svc_max_payload (rqstp)); -/* Convert byte count to number of words (i.e. >> 2), -* and reserve room for the NULL ptr & eof flag (-2 words) */ - resp->buflen = (count >>2 ) -2 ; +memset (buf,0 ,sizeof (*buf)); - resp->pages = rqstp->rq_next_page; - resp->buffer =page_address (*resp->pages); +/* Reserve room for the NULL ptr & eof flag (-2 words) */ + buf->buflen = count -XDR_UNIT *2 ; + buf->pages = rqstp->rq_next_page;while (count >0 ) { rqstp->rq_next_page++; count -=PAGE_SIZE ; } + +/* This is xdr_init_encode(), but it assumes that +* the head kvec has already been consumed. */ +xdr_set_scratch_buffer (xdr,NULL ,0 ); + xdr->buf = buf; + xdr->page_ptr = buf->pages; + xdr->iov =NULL ; + xdr->p =page_address (*buf->pages); + xdr->end = xdr->p + (PAGE_SIZE >>2 ); + xdr->rqst =NULL ; }/*
@@ -476,16 +488,13 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)nfsd3_init_dirlist_pages (rqstp, resp, argp->count); -/* Read directory and encode entries on the fly */ fh_copy (&resp->fh, &argp->fh); - - resp->count =0 ; resp->common.err = nfs_ok; + resp->cookie_offset =0 ; resp->rqstp = rqstp; offset = argp->cookie; - resp->status =nfsd_readdir (rqstp, &resp->fh, &offset, - &resp->common, nfs3svc_encode_entry); + &resp->common, nfs3svc_encode_entry3);memcpy (resp->verf, argp->verf,8 );nfs3svc_encode_cookie3 (resp, offset);
@@ -509,11 +518,9 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp)nfsd3_init_dirlist_pages (rqstp, resp, argp->count); -/* Read directory and encode entries on the fly */ fh_copy (&resp->fh, &argp->fh); - - resp->count =0 ; resp->common.err = nfs_ok; + resp->cookie_offset =0 ; resp->rqstp = rqstp; offset = argp->cookie;
@@ -527,7 +534,7 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp) } resp->status =nfsd_readdir (rqstp, &resp->fh, &offset, - &resp->common, nfs3svc_encode_entry_plus); + &resp->common, nfs3svc_encode_entryplus3);memcpy (resp->verf, argp->verf,8 );nfs3svc_encode_cookie3 (resp, offset);
fs/nfsd/nfs3xdr.c +154 -12
194 lines not on this page · raw message
fs/nfsd/xdr3.h +10 -4
@@ -169,20 +169,22 @@ struct nfsd3_linkres { };struct nfsd3_readdirres { +/* Components of the reply */ __be32 status;struct svc_fh fh; -/* Just to save kmalloc on every readdirplus entry (svc_fh is a -* little large for the stack): */ -struct svc_fh scratch;int count;__be32 verf[2 ]; -struct page **pages; +/* Used to encode the reply's entry list */ +struct xdr_stream xdr; +struct xdr_buf dirlist; +struct svc_fh scratch;struct readdir_cd common;__be32 * buffer;int buflen;__be32 * offset;__be32 * offset1; +unsigned int cookie_offset;struct svc_rqst * rqstp; };
@@ -309,6 +311,10 @@ int nfs3svc_encode_entry(void *, const char *name,int nfs3svc_encode_entry_plus (void *,const char *name,int namlen,loff_t offset,u64 ino,unsigned int ); +int nfs3svc_encode_entry3 (void *data,const char *name,int namlen, +loff_t offset,u64 ino,unsigned int d_type); +int nfs3svc_encode_entryplus3 (void *data,const char *name,int namlen, +loff_t offset,u64 ino,unsigned int d_type);/* Helper functions for NFSv3 ACL code */ __be32 *nfs3svc_encode_post_op_attr (struct svc_rqst *rqstp,__be32 *p,struct svc_fh *fhp);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 216/770 NFSD: Remove unused NFSv3 directory entry encoders
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 1411934627f9fe31a36ac8c43179ce9b63edce5c ]
Clean up.
--- fs/nfsd/nfs3xdr.c | 190 ---------------------------------------------- fs/nfsd/xdr3.h | 11 --- 2 files changed, 201 deletions(-)
fs/nfsd/nfs3xdr.c +0 -190
@@ -148,16 +148,6 @@ svcxdr_encode_post_op_fh3(struct xdr_stream *xdr, const struct svc_fh *fhp)return true; } -static __be32 * -encode_fh (__be32 *p,struct svc_fh *fhp) -{ -unsigned int size = fhp->fh_handle.fh_size; - *p++ =htonl (size); -if (size) p[XDR_QUADLEN (size)-1 ]=0 ; -memcpy (p, &fhp->fh_handle.fh_base, size); -return p +XDR_QUADLEN (size); -} -static bool svcxdr_encode_cookieverf3 (struct xdr_stream *xdr,const __be32 *verf) {
@@ -1164,20 +1154,6 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p)return 1 ; } -static __be32 * -encode_entry_baggage (struct nfsd3_readdirres *cd,__be32 *p,const char *name, -int namlen,u64 ino) -{ - *p++ = xdr_one;/* mark entry present */ - p =xdr_encode_hyper (p, ino);/* file id */ - p =xdr_encode_array (p, name, namlen);/* name length & name */ - - cd->offset = p;/* remember pointer */ - p =xdr_encode_hyper (p,NFS_OFFSET_MAX );/* offset of next entry */ - -return p; -} -static __be32 compose_entry_fh (struct nfsd3_readdirres *cd,struct svc_fh *fhp,const char *name,int namlen,u64 ino)
@@ -1216,26 +1192,6 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,return rv; } -static __be32 *encode_entryplus_baggage (struct nfsd3_readdirres *cd,__be32 *p,const char *name,int namlen,u64 ino) -{ -struct svc_fh *fh = &cd->scratch; -__be32 err; - -fh_init (fh,NFS3_FHSIZE ); - err =compose_entry_fh (cd, fh, name, namlen, ino); -if (err) { - *p++ =0 ; - *p++ =0 ; - goto out; - } - p =encode_post_op_attr (cd->rqstp, p, fh); - *p++ = xdr_one;/* yes, a file handle follows */ - p =encode_fh (p, fh); -out: -fh_put (fh); -return p; -} -/** * nfs3svc_encode_cookie3 - Encode a directory offset cookie * @resp: readdir result context
@@ -1255,152 +1211,6 @@ void nfs3svc_encode_cookie3(struct nfsd3_readdirres *resp, u64 offset) resp->cookie_offset =0 ; } -/* -* Encode a directory entry. This one works for both normal readdir -* and readdirplus. -* The normal readdir reply requires 2 (fileid) + 1 (stringlen) -* + string + 2 (cookie) + 1 (next) words, i.e. 6 + strlen. -* -* The readdirplus baggage is 1+21 words for post_op_attr, plus the -* file handle. -*/ - -#define NFS3_ENTRY_BAGGAGE (2 + 1 + 2 + 1) -#define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2)) -static int -encode_entry (struct readdir_cd *ccd,const char *name,int namlen, -loff_t offset,u64 ino,unsigned int d_type,int plus) -{ - struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, - common); -__be32 *p = cd->buffer; -caddr_t curr_page_addr =NULL ; -struct page ** page; -int slen;/* string (name) length */ -int elen;/* estimated entry length in words */ -int num_entry_words =0 ;/* actual number of words */ - -nfs3svc_encode_cookie3 (cd, offset); - -/* -dprintk("encode_entry(%.*s @%ld%s)\n", -namlen, name, (long) offset, plus? " plus" : ""); -*/ - -/* truncate filename if too long */ - namlen =min (namlen,NFS3_MAXNAMLEN ); - - slen =XDR_QUADLEN (namlen); - elen = slen +NFS3_ENTRY_BAGGAGE - + (plus?NFS3_ENTRYPLUS_BAGGAGE :0 ); - -if (cd->buflen < elen) { - cd->common.err = nfserr_toosmall; -return -EINVAL ; - } - -/* determine which page in rq_respages[] we are currently filling */ -for (page = cd->rqstp->rq_respages +1 ; - page < cd->rqstp->rq_next_page; page++) { - curr_page_addr =page_address (*page); - -if (((caddr_t )cd->buffer >= curr_page_addr) && - ((caddr_t )cd->buffer < curr_page_addr +PAGE_SIZE )) -break ; - } - -if ((caddr_t)(cd->buffer + elen) < (curr_page_addr +PAGE_SIZE )) { -/* encode entry in current page */ - - p =encode_entry_baggage (cd, p, name, namlen, ino); - -if (plus) - p =encode_entryplus_baggage (cd, p, name, namlen, ino); - num_entry_words = p - cd->buffer; - }else if (*(page+1 ) !=NULL ) { -/* temporarily encode entry into next page, then move back to -* current and next page in rq_respages[] */ -__be32 *p1, *tmp; -int len1, len2; - -/* grab next page for temporary storage of entry */ - p1 = tmp =page_address (*(page+1 )); - - p1 =encode_entry_baggage (cd, p1, name, namlen, ino); - -if (plus) - p1 =encode_entryplus_baggage (cd, p1, name, namlen, ino); - -/* determine entry word length and lengths to go in pages */ - num_entry_words = p1 - tmp; - len1 = curr_page_addr +PAGE_SIZE - (caddr_t )cd->buffer; -if ((num_entry_words <<2 ) < len1) { -/* the actual number of words in the entry is less -* than elen and can still fit in the current page -*/ -memmove (p, tmp, num_entry_words <<2 ); - p += num_entry_words; - -/* update offset */ - cd->offset = cd->buffer + (cd->offset - tmp); - }else { -unsigned int offset_r = (cd->offset - tmp) <<2 ; - -/* update pointer to offset location. -* This is a 64bit quantity, so we need to -* deal with 3 cases: -* - entirely in first page -* - entirely in second page -* - 4 bytes in each page -*/ -if (offset_r +8 <= len1) { - cd->offset = p + (cd->offset - tmp); - }else if (offset_r >= len1) { - cd->offset -= len1 >>2 ; - }else { -/* sitting on the fence */ -BUG_ON (offset_r != len1 -4 ); - cd->offset = p + (cd->offset - tmp); - cd->offset1 = tmp; - } - - len2 = (num_entry_words <<2 ) - len1; - -/* move from temp page to current and next pages */ -memmove (p, tmp, len1); -memmove (tmp, (caddr_t )tmp+len1, len2); - - p = tmp + (len2 >>2 ); - } - } -else { - cd->common.err = nfserr_toosmall; -return -EINVAL ; - } - - cd->count += num_entry_words; - cd->buflen -= num_entry_words; - cd->buffer = p; - cd->common.err = nfs_ok; -return 0 ; - -} - -int -nfs3svc_encode_entry (void *cd,const char *name, -int namlen,loff_t offset,u64 ino,unsigned int d_type) -{ -return encode_entry (cd, name, namlen, offset, ino, d_type,0 ); -} - -int -nfs3svc_encode_entry_plus (void *cd,const char *name, -int namlen,loff_t offset,u64 ino, -unsigned int d_type) -{ -return encode_entry (cd, name, namlen, offset, ino, d_type,1 ); -} -static bool svcxdr_encode_entry3_common (struct nfsd3_readdirres *resp,const char *name,int namlen,loff_t offset,u64 ino)
fs/nfsd/xdr3.h +0 -11
@@ -172,7 +172,6 @@ struct nfsd3_readdirres {/* Components of the reply */ __be32 status;struct svc_fh fh; -int count;__be32 verf[2 ];/* Used to encode the reply's entry list */
@@ -180,10 +179,6 @@ struct nfsd3_readdirres {struct xdr_buf dirlist;struct svc_fh scratch;struct readdir_cd common; -__be32 * buffer; -int buflen; -__be32 * offset; -__be32 * offset1;unsigned int cookie_offset;struct svc_rqst * rqstp;
@@ -305,12 +300,6 @@ void nfs3svc_release_fhandle(struct svc_rqst *);void nfs3svc_release_fhandle2 (struct svc_rqst *);void nfs3svc_encode_cookie3 (struct nfsd3_readdirres *resp,u64 offset); -int nfs3svc_encode_entry (void *,const char *name, -int namlen,loff_t offset,u64 ino, -unsigned int ); -int nfs3svc_encode_entry_plus (void *,const char *name, -int namlen,loff_t offset,u64 ino, -unsigned int );int nfs3svc_encode_entry3 (void *data,const char *name,int namlen,loff_t offset,u64 ino,unsigned int d_type); int nfs3svc_encode_entryplus3(void *data, const char *name, int namlen,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 217/770 NFSD: Reduce svc_rqst::rq_pages churn during READDIR operations
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 76ed0dd96eeb2771b21bf5dcbd88326ef89ee0ed ]
During NFSv2 and NFSv3 READDIR/PLUS operations, NFSD advances rq_next_page to the full size of the client-requested buffer, then releases all those pages at the end of the request. The next request to use that nfsd thread has to refill the pages.
NFSD does this even when the dirlist in the reply is small. With NFSv3 clients that send READDIR operations with large buffer sizes, that can be 256 put_page/alloc_page pairs per READDIR request, even though those pages often remain unused.
We can save some work by not releasing dirlist buffer pages that were not used to form the READDIR Reply. I've left the NFSv2 code alone since there are never more than three pages involved in an NFSv2 READDIR Reply.
Eventually we should nail down why these pages need to be released at all in order to avoid allocating and releasing pages unnecessarily.
--- fs/nfsd/nfs3proc.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/nfsd/nfs3proc.c +6 -0
@@ -498,6 +498,9 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)memcpy (resp->verf, argp->verf,8 );nfs3svc_encode_cookie3 (resp, offset); +/* Recycle only pages that were part of the reply */ + rqstp->rq_next_page = resp->xdr.page_ptr +1 ; +return rpc_success; }
@@ -538,6 +541,9 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp)memcpy (resp->verf, argp->verf,8 );nfs3svc_encode_cookie3 (resp, offset); +/* Recycle only pages that were part of the reply */ + rqstp->rq_next_page = resp->xdr.page_ptr +1 ; + out:return rpc_success; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 218/770 NFSD: Update the NFSv2 stat encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit a887eaed2a964754334cd3f8c5fe87e413e68fef ]
--- fs/nfsd/nfsproc.c | 10 +++++----- fs/nfsd/nfsxdr.c | 19 ++++++++++++++++--- fs/nfsd/xdr.h | 2 +- 3 files changed, 22 insertions(+), 9 deletions(-)
fs/nfsd/nfsproc.c +5 -5
@@ -736,7 +736,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { [NFSPROC_REMOVE] = { .pc_func = nfsd_proc_remove, .pc_decode = nfssvc_decode_diropargs, - .pc_encode = nfssvc_encode_stat, + .pc_encode = nfssvc_encode_statres, .pc_argsize = sizeof(struct nfsd_diropargs), .pc_ressize = sizeof(struct nfsd_stat), .pc_cachetype = RC_REPLSTAT,
@@ -746,7 +746,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { [NFSPROC_RENAME] = { .pc_func = nfsd_proc_rename, .pc_decode = nfssvc_decode_renameargs, - .pc_encode = nfssvc_encode_stat, + .pc_encode = nfssvc_encode_statres, .pc_argsize = sizeof(struct nfsd_renameargs), .pc_ressize = sizeof(struct nfsd_stat), .pc_cachetype = RC_REPLSTAT,
@@ -756,7 +756,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { [NFSPROC_LINK] = { .pc_func = nfsd_proc_link, .pc_decode = nfssvc_decode_linkargs, - .pc_encode = nfssvc_encode_stat, + .pc_encode = nfssvc_encode_statres, .pc_argsize = sizeof(struct nfsd_linkargs), .pc_ressize = sizeof(struct nfsd_stat), .pc_cachetype = RC_REPLSTAT,
@@ -766,7 +766,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { [NFSPROC_SYMLINK] = { .pc_func = nfsd_proc_symlink, .pc_decode = nfssvc_decode_symlinkargs, - .pc_encode = nfssvc_encode_stat, + .pc_encode = nfssvc_encode_statres, .pc_argsize = sizeof(struct nfsd_symlinkargs), .pc_ressize = sizeof(struct nfsd_stat), .pc_cachetype = RC_REPLSTAT,
@@ -787,7 +787,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { [NFSPROC_RMDIR] = { .pc_func = nfsd_proc_rmdir, .pc_decode = nfssvc_decode_diropargs, - .pc_encode = nfssvc_encode_stat, + .pc_encode = nfssvc_encode_statres, .pc_argsize = sizeof(struct nfsd_diropargs), .pc_ressize = sizeof(struct nfsd_stat), .pc_cachetype = RC_REPLSTAT,
fs/nfsd/nfsxdr.c +16 -3
@@ -26,6 +26,19 @@ static u32 nfs_ftypes[] = {* Basic NFSv2 data types (RFC 1094 Section 2.3) */ +static bool +svcxdr_encode_stat (struct xdr_stream *xdr,__be32 status) +{ +__be32 *p; + + p =xdr_reserve_space (xdr,sizeof (status)); +if (!p) +return false; + *p = status; + +return true; +} +/** * svcxdr_decode_fhandle - Decode an NFSv2 file handle * @xdr: XDR stream positioned at an encoded NFSv2 FH
@@ -390,12 +403,12 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)*/ int -nfssvc_encode_stat (struct svc_rqst *rqstp,__be32 *p) +nfssvc_encode_statres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd_stat *resp = rqstp->rq_resp; - *p++ = resp->status; -return xdr_ressize_check (rqstp, p); +return svcxdr_encode_stat (xdr, resp->status); }int
fs/nfsd/xdr.h +1 -1
@@ -147,7 +147,7 @@ int nfssvc_decode_renameargs(struct svc_rqst *, __be32 *);int nfssvc_decode_linkargs (struct svc_rqst *,__be32 *);int nfssvc_decode_symlinkargs (struct svc_rqst *,__be32 *);int nfssvc_decode_readdirargs (struct svc_rqst *,__be32 *); -int nfssvc_encode_stat (struct svc_rqst *,__be32 *); +int nfssvc_encode_statres (struct svc_rqst *,__be32 *);int nfssvc_encode_attrstat (struct svc_rqst *,__be32 *);int nfssvc_encode_diropres (struct svc_rqst *,__be32 *);int nfssvc_encode_readlinkres (struct svc_rqst *,__be32 *);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 219/770 NFSD: Update the NFSv2 attrstat encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 92b54a4fa4224e6116eb0d87a39dd05af23fcdfa ]
--- fs/nfsd/nfsproc.c | 6 ++-- fs/nfsd/nfsxdr.c | 90 ++++++++++++++++++++++++++++++++++++++++++----- fs/nfsd/xdr.h | 2 +- 3 files changed, 86 insertions(+), 12 deletions(-)
fs/nfsd/nfsproc.c +3 -3
@@ -640,7 +640,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { [NFSPROC_GETATTR] = { .pc_func = nfsd_proc_getattr, .pc_decode = nfssvc_decode_fhandleargs, - .pc_encode = nfssvc_encode_attrstat, + .pc_encode = nfssvc_encode_attrstatres, .pc_release = nfssvc_release_attrstat, .pc_argsize = sizeof(struct nfsd_fhandle), .pc_ressize = sizeof(struct nfsd_attrstat),
@@ -651,7 +651,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { [NFSPROC_SETATTR] = { .pc_func = nfsd_proc_setattr, .pc_decode = nfssvc_decode_sattrargs, - .pc_encode = nfssvc_encode_attrstat, + .pc_encode = nfssvc_encode_attrstatres, .pc_release = nfssvc_release_attrstat, .pc_argsize = sizeof(struct nfsd_sattrargs), .pc_ressize = sizeof(struct nfsd_attrstat),
@@ -714,7 +714,7 @@ static const struct svc_procedure nfsd_procedures2[18] = { [NFSPROC_WRITE] = { .pc_func = nfsd_proc_write, .pc_decode = nfssvc_decode_writeargs, - .pc_encode = nfssvc_encode_attrstat, + .pc_encode = nfssvc_encode_attrstatres, .pc_release = nfssvc_release_attrstat, .pc_argsize = sizeof(struct nfsd_writeargs), .pc_ressize = sizeof(struct nfsd_attrstat),
fs/nfsd/nfsxdr.c +82 -8
117 lines not on this page · raw message
fs/nfsd/xdr.h +1 -1
@@ -148,7 +148,7 @@ int nfssvc_decode_linkargs(struct svc_rqst *, __be32 *);int nfssvc_decode_symlinkargs (struct svc_rqst *,__be32 *);int nfssvc_decode_readdirargs (struct svc_rqst *,__be32 *);int nfssvc_encode_statres (struct svc_rqst *,__be32 *); -int nfssvc_encode_attrstat (struct svc_rqst *,__be32 *); +int nfssvc_encode_attrstatres (struct svc_rqst *,__be32 *);int nfssvc_encode_diropres (struct svc_rqst *,__be32 *);int nfssvc_encode_readlinkres (struct svc_rqst *,__be32 *);int nfssvc_encode_readres (struct svc_rqst *,__be32 *);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 220/770 NFSD: Update the NFSv2 diropres encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit e3b4ef221ac57c08341c97a10c8a81c041f76716 ]
--- fs/nfsd/nfsxdr.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-)
fs/nfsd/nfsxdr.c +25 -13
@@ -63,11 +63,17 @@ svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp)return true; } -static __be32 * -encode_fh (__be32 *p,struct svc_fh *fhp) +static bool +svcxdr_encode_fhandle (struct xdr_stream *xdr,const struct svc_fh *fhp) { +__be32 *p; + + p =xdr_reserve_space (xdr,NFS_FHSIZE ); +if (!p) +return false;memcpy (p, &fhp->fh_handle.fh_base,NFS_FHSIZE ); -return p + (NFS_FHSIZE >>2 ); + +return true; } static __be32 *
@@ -244,7 +250,7 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,return p; } -static int +static bool svcxdr_encode_fattr (struct svc_rqst *rqstp,struct xdr_stream *xdr,const struct svc_fh *fhp,const struct kstat *stat) {
@@ -257,7 +263,7 @@ svcxdr_encode_fattr(struct svc_rqst *rqstp, struct xdr_stream *xdr, p =xdr_reserve_space (xdr,XDR_UNIT *17 );if (!p) -return 0 ; +return false; *p++ =cpu_to_be32 (nfs_ftypes[type >>12 ]); *p++ =cpu_to_be32 ((u32 )stat->mode);
@@ -299,7 +305,7 @@ svcxdr_encode_fattr(struct svc_rqst *rqstp, struct xdr_stream *xdr, p =encode_timeval (p, &time);encode_timeval (p, &stat->ctime); -return 1 ; +return true; }/* Helper function for NFSv2 ACL code */
@@ -501,15 +507,21 @@ nfssvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p)int nfssvc_encode_diropres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd_diropres *resp = rqstp->rq_resp; - *p++ = resp->status; -if (resp->status != nfs_ok) - goto out; - p =encode_fh (p, &resp->fh); - p =encode_fattr (rqstp, p, &resp->fh, &resp->stat); -out: -return xdr_ressize_check (rqstp, p); +if (!svcxdr_encode_stat (xdr, resp->status)) +return 0 ; +switch (resp->status) { +case nfs_ok: +if (!svcxdr_encode_fhandle (xdr, &resp->fh)) +return 0 ; +if (!svcxdr_encode_fattr (rqstp, xdr, &resp->fh, &resp->stat)) +return 0 ; +break ; + } + +return 1 ; }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 221/770 NFSD: Update the NFSv2 READLINK result encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit d9014b0f8fae11f22a3d356553844e06ddcdce4a ]
--- fs/nfsd/nfsproc.c | 5 +++-- fs/nfsd/nfsxdr.c | 26 ++++++++++++-------------- fs/nfsd/xdr.h | 1 + 3 files changed, 16 insertions(+), 16 deletions(-)
fs/nfsd/nfsproc.c +3 -2
@@ -151,13 +151,14 @@ nfsd_proc_readlink(struct svc_rqst *rqstp) {struct nfsd_fhandle *argp = rqstp->rq_argp;struct nfsd_readlinkres *resp = rqstp->rq_resp; -char *buffer =page_address (*(rqstp->rq_next_page++));dprintk ("nfsd: READLINK %s\n" ,SVCFH_fmt (&argp->fh));/* Read the symlink. */ resp->len =NFS_MAXPATHLEN ; - resp->status =nfsd_readlink (rqstp, &argp->fh, buffer, &resp->len); + resp->page = *(rqstp->rq_next_page++); + resp->status =nfsd_readlink (rqstp, &argp->fh, +page_address (resp->page), &resp->len);fh_put (&argp->fh);return rpc_success;
fs/nfsd/nfsxdr.c +12 -14
@@ -527,24 +527,22 @@ nfssvc_encode_diropres(struct svc_rqst *rqstp, __be32 *p)int nfssvc_encode_readlinkres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd_readlinkres *resp = rqstp->rq_resp;struct kvec *head = rqstp->rq_res.head; - *p++ = resp->status; -if (resp->status != nfs_ok) -return xdr_ressize_check (rqstp, p); - - *p++ =htonl (resp->len); -xdr_ressize_check (rqstp, p); - rqstp->rq_res.page_len = resp->len; -if (resp->len &3 ) { -/* need to pad the tail */ - rqstp->rq_res.tail[0 ].iov_base = p; - *p =0 ; - rqstp->rq_res.tail[0 ].iov_len =4 - (resp->len&3 ); - } -if (svc_encode_result_payload (rqstp, head->iov_len, resp->len)) +if (!svcxdr_encode_stat (xdr, resp->status))return 0 ; +switch (resp->status) { +case nfs_ok: +if (xdr_stream_encode_u32 (xdr, resp->len) <0 ) +return 0 ; +xdr_write_pages (xdr, &resp->page,0 , resp->len); +if (svc_encode_result_payload (rqstp, head->iov_len, resp->len) <0 ) +return 0 ; +break ; + } +return 1 ; }
fs/nfsd/xdr.h +1 -0
@@ -94,6 +94,7 @@ struct nfsd_diropres {struct nfsd_readlinkres {__be32 status;int len; +struct page *page; };struct nfsd_readres {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 222/770 NFSD: Update the NFSv2 READ result encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit a6f8d9dc9e44b51303d9abde4643460137d19b28 ]
--- fs/nfsd/nfsproc.c | 1 + fs/nfsd/nfsxdr.c | 32 +++++++++++++++----------------- fs/nfsd/xdr.h | 1 + 3 files changed, 17 insertions(+), 17 deletions(-)
fs/nfsd/nfsproc.c +1 -0
@@ -185,6 +185,7 @@ nfsd_proc_read(struct svc_rqst *rqstp) v =0 ; len = argp->count; + resp->pages = rqstp->rq_next_page;while (len >0 ) {struct page *page = *(rqstp->rq_next_page++);
fs/nfsd/nfsxdr.c +15 -17
@@ -549,27 +549,25 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p)int nfssvc_encode_readres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd_readres *resp = rqstp->rq_resp;struct kvec *head = rqstp->rq_res.head; - *p++ = resp->status; -if (resp->status != nfs_ok) -return xdr_ressize_check (rqstp, p); - - p =encode_fattr (rqstp, p, &resp->fh, &resp->stat); - *p++ =htonl (resp->count); -xdr_ressize_check (rqstp, p); - -/* now update rqstp->rq_res to reflect data as well */ - rqstp->rq_res.page_len = resp->count; -if (resp->count &3 ) { -/* need to pad the tail */ - rqstp->rq_res.tail[0 ].iov_base = p; - *p =0 ; - rqstp->rq_res.tail[0 ].iov_len =4 - (resp->count&3 ); - } -if (svc_encode_result_payload (rqstp, head->iov_len, resp->count)) +if (!svcxdr_encode_stat (xdr, resp->status))return 0 ; +switch (resp->status) { +case nfs_ok: +if (!svcxdr_encode_fattr (rqstp, xdr, &resp->fh, &resp->stat)) +return 0 ; +if (xdr_stream_encode_u32 (xdr, resp->count) <0 ) +return 0 ; +xdr_write_pages (xdr, resp->pages, rqstp->rq_res.page_base, + resp->count); +if (svc_encode_result_payload (rqstp, head->iov_len, resp->count) <0 ) +return 0 ; +break ; + } +return 1 ; }
fs/nfsd/xdr.h +1 -0
@@ -102,6 +102,7 @@ struct nfsd_readres {struct svc_fh fh;unsigned long count;struct kstat stat; +struct page **pages; };struct nfsd_readdirres {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 223/770 NFSD: Update the NFSv2 STATFS result encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit bf15229f2ced4f14946eef958336f764e30f8efb ]
--- fs/nfsd/nfsxdr.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-)
fs/nfsd/nfsxdr.c +16 -9
@@ -592,19 +592,26 @@ nfssvc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p)int nfssvc_encode_statfsres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd_statfsres *resp = rqstp->rq_resp;struct kstatfs *stat = &resp->stats; - *p++ = resp->status; -if (resp->status != nfs_ok) -return xdr_ressize_check (rqstp, p); +if (!svcxdr_encode_stat (xdr, resp->status)) +return 0 ; +switch (resp->status) { +case nfs_ok: + p =xdr_reserve_space (xdr,XDR_UNIT *5 ); +if (!p) +return 0 ; + *p++ =cpu_to_be32 (NFSSVC_MAXBLKSIZE_V2 ); + *p++ =cpu_to_be32 (stat->f_bsize); + *p++ =cpu_to_be32 (stat->f_blocks); + *p++ =cpu_to_be32 (stat->f_bfree); + *p =cpu_to_be32 (stat->f_bavail); +break ; + } - *p++ =htonl (NFSSVC_MAXBLKSIZE_V2 );/* max transfer size */ - *p++ =htonl (stat->f_bsize); - *p++ =htonl (stat->f_blocks); - *p++ =htonl (stat->f_bfree); - *p++ =htonl (stat->f_bavail); -return xdr_ressize_check (rqstp, p); +return 1 ; }int
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 224/770 NFSD: Add a helper that encodes NFSv3 directory offset cookies, again
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit d52532002ffa217ad3fa4c3ba86c95203d21dd21 ]
Refactor: Add helper function similar to nfs3svc_encode_cookie3().
--- fs/nfsd/nfsproc.c | 3 +-- fs/nfsd/nfsxdr.c | 18 ++++++++++++++++-- fs/nfsd/xdr.h | 1 + 3 files changed, 18 insertions(+), 4 deletions(-)
fs/nfsd/nfsproc.c +1 -2
@@ -595,8 +595,7 @@ nfsd_proc_readdir(struct svc_rqst *rqstp) &resp->common, nfssvc_encode_entry); resp->count = resp->buffer - buffer; -if (resp->offset) - *resp->offset =htonl (offset); +nfssvc_encode_nfscookie (resp, offset);fh_put (&argp->fh);return rpc_success;
fs/nfsd/nfsxdr.c +16 -2
@@ -614,6 +614,21 @@ nfssvc_encode_statfsres(struct svc_rqst *rqstp, __be32 *p)return 1 ; } +/** +* nfssvc_encode_nfscookie - Encode a directory offset cookie +* @resp: readdir result context +* @offset: offset cookie to encode +* +*/ +void nfssvc_encode_nfscookie (struct nfsd_readdirres *resp,u32 offset) +{ +if (!resp->offset) +return ; + + *resp->offset =cpu_to_be32 (offset); + resp->offset =NULL ; +} +int nfssvc_encode_entry (void *ccdv,const char *name,int namlen,loff_t offset,u64 ino,unsigned int d_type)
@@ -632,8 +647,7 @@ nfssvc_encode_entry(void *ccdv, const char *name, cd->common.err = nfserr_fbig;return -EINVAL ; } -if (cd->offset) - *cd->offset =htonl (offset); +nfssvc_encode_nfscookie (cd, offset);/* truncate filename */ namlen =min (namlen,NFS2_MAXNAMLEN );
fs/nfsd/xdr.h +1 -0
@@ -157,6 +157,7 @@ int nfssvc_encode_readres(struct svc_rqst *, __be32 *);int nfssvc_encode_statfsres (struct svc_rqst *,__be32 *);int nfssvc_encode_readdirres (struct svc_rqst *,__be32 *); +void nfssvc_encode_nfscookie (struct nfsd_readdirres *resp,u32 offset);int nfssvc_encode_entry (void *,const char *name,int namlen,loff_t offset,u64 ino,unsigned int );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 225/770 NFSD: Count bytes instead of pages in the NFSv2 READDIR encoder
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 8141d6a2bb6c655ff0c0b81ced80d9025f03e926 ]
Clean up: Counting the bytes used by each returned directory entry seems less brittle to me than trying to measure consumed pages after the fact.
--- fs/nfsd/nfsproc.c | 4 ---- fs/nfsd/nfsxdr.c | 3 ++- 2 files changed, 2 insertions(+), 5 deletions(-)
fs/nfsd/nfsproc.c +0 -4
@@ -578,14 +578,12 @@ nfsd_proc_readdir(struct svc_rqst *rqstp)struct nfsd_readdirargs *argp = rqstp->rq_argp;struct nfsd_readdirres *resp = rqstp->rq_resp;loff_t offset; -__be32 *buffer;dprintk ("nfsd: READDIR %s %d bytes at %d\n" ,SVCFH_fmt (&argp->fh), argp->count, argp->cookie);nfsd_init_dirlist_pages (rqstp, resp, argp->count); - buffer = resp->buffer; resp->offset =NULL ; resp->common.err = nfs_ok;
@@ -593,8 +591,6 @@ nfsd_proc_readdir(struct svc_rqst *rqstp) offset = argp->cookie; resp->status =nfsd_readdir (rqstp, &argp->fh, &offset, &resp->common, nfssvc_encode_entry); - - resp->count = resp->buffer - buffer;nfssvc_encode_nfscookie (resp, offset);fh_put (&argp->fh);
fs/nfsd/nfsxdr.c +2 -1
@@ -584,7 +584,7 @@ nfssvc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p) p = resp->buffer; *p++ =0 ;/* no more entries */ *p++ =htonl ((resp->common.err == nfserr_eof)); - rqstp->rq_res.page_len = (((unsigned long )p-1 ) & ~PAGE_MASK )+1 ; + rqstp->rq_res.page_len = resp->count <<2 ;return 1 ; }
@@ -667,6 +667,7 @@ nfssvc_encode_entry(void *ccdv, const char *name, cd->offset = p;/* remember pointer */ *p++ =htonl (~0U );/* offset of next entry */ + cd->count += p - cd->buffer; cd->buflen = buflen; cd->buffer = p; cd->common.err = nfs_ok;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 226/770 NFSD: Update the NFSv2 READDIR result encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 94c8f8c682a6497af7ea71351b18f637c6337d42 ]
--- fs/nfsd/nfsxdr.c | 22 +++++++++++++--------- fs/nfsd/xdr.h | 1 + 2 files changed, 14 insertions(+), 9 deletions(-)
fs/nfsd/nfsxdr.c +13 -9
@@ -574,17 +574,21 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p)int nfssvc_encode_readdirres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd_readdirres *resp = rqstp->rq_resp; - *p++ = resp->status; -if (resp->status != nfs_ok) -return xdr_ressize_check (rqstp, p); - -xdr_ressize_check (rqstp, p); - p = resp->buffer; - *p++ =0 ;/* no more entries */ - *p++ =htonl ((resp->common.err == nfserr_eof)); - rqstp->rq_res.page_len = resp->count <<2 ; +if (!svcxdr_encode_stat (xdr, resp->status)) +return 0 ; +switch (resp->status) { +case nfs_ok: +xdr_write_pages (xdr, &resp->page,0 , resp->count <<2 ); +/* no more entries */ +if (xdr_stream_encode_item_absent (xdr) <0 ) +return 0 ; +if (xdr_stream_encode_bool (xdr, resp->common.err == nfserr_eof) <0 ) +return 0 ; +break ; + }return 1 ; }
fs/nfsd/xdr.h +1 -0
@@ -114,6 +114,7 @@ struct nfsd_readdirres {__be32 * buffer;int buflen;__be32 * offset; +struct page *page; };struct nfsd_statfsres {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 227/770 NFSD: Update the NFSv2 READDIR entry encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit f5dcccd647da513a89f3b6ca392b0c1eb050b9fc ]
--- fs/nfsd/nfsproc.c | 26 +++++++++++---- fs/nfsd/nfsxdr.c | 81 ++++++++++++++++++++++++++++++++++++++++++++--- fs/nfsd/xdr.h | 7 ++++ 3 files changed, 103 insertions(+), 11 deletions(-)
fs/nfsd/nfsproc.c +19 -7
@@ -559,14 +559,27 @@ static void nfsd_init_dirlist_pages(struct svc_rqst *rqstp, struct nfsd_readdirres *resp, int count) { +struct xdr_buf *buf = &resp->dirlist; +struct xdr_stream *xdr = &resp->xdr; + count =min_t (u32, count,PAGE_SIZE ); -/* Convert byte count to number of words (i.e. >> 2), -* and reserve room for the NULL ptr & eof flag (-2 words) */ - resp->buflen = (count >>2 ) -2 ; +memset (buf,0 ,sizeof (*buf)); - resp->buffer =page_address (*rqstp->rq_next_page); +/* Reserve room for the NULL ptr & eof flag (-2 words) */ + buf->buflen = count -sizeof (__be32) *2 ; + buf->pages = rqstp->rq_next_page; rqstp->rq_next_page++; + +/* This is xdr_init_encode(), but it assumes that +* the head kvec has already been consumed. */ +xdr_set_scratch_buffer (xdr,NULL ,0 ); + xdr->buf = buf; + xdr->page_ptr = buf->pages; + xdr->iov =NULL ; + xdr->p =page_address (*buf->pages); + xdr->end = xdr->p + (PAGE_SIZE >>2 ); + xdr->rqst =NULL ; }/*
@@ -585,12 +598,11 @@ nfsd_proc_readdir(struct svc_rqst *rqstp)nfsd_init_dirlist_pages (rqstp, resp, argp->count); - resp->offset =NULL ; resp->common.err = nfs_ok; -/* Read directory and encode entries on the fly */ + resp->cookie_offset =0 ; offset = argp->cookie; resp->status =nfsd_readdir (rqstp, &argp->fh, &offset, - &resp->common, nfssvc_encode_entry); + &resp->common, nfs2svc_encode_entry);nfssvc_encode_nfscookie (resp, offset);fh_put (&argp->fh);
fs/nfsd/nfsxdr.c +77 -4
103 lines not on this page · raw message
fs/nfsd/xdr.h +7 -0
@@ -106,15 +106,20 @@ struct nfsd_readres { };struct nfsd_readdirres { +/* Components of the reply */ __be32 status;int count; +/* Used to encode the reply's entry list */ +struct xdr_stream xdr; +struct xdr_buf dirlist;struct readdir_cd common;__be32 * buffer;int buflen;__be32 * offset;struct page *page; +unsigned int cookie_offset; };struct nfsd_statfsres {
@@ -159,6 +164,8 @@ int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *);int nfssvc_encode_readdirres (struct svc_rqst *,__be32 *);void nfssvc_encode_nfscookie (struct nfsd_readdirres *resp,u32 offset); +int nfs2svc_encode_entry (void *data,const char *name,int namlen, +loff_t offset,u64 ino,unsigned int d_type);int nfssvc_encode_entry (void *,const char *name,int namlen,loff_t offset,u64 ino,unsigned int );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 228/770 NFSD: Remove unused NFSv2 directory entry encoders
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 8a2cf9f5709cc20a1114a7d22655928314fc86f8 ]
Clean up.
--- fs/nfsd/nfsproc.c | 2 +- fs/nfsd/nfsxdr.c | 51 +++-------------------------------------------- fs/nfsd/xdr.h | 10 ++-------- 3 files changed, 6 insertions(+), 57 deletions(-)
fs/nfsd/nfsproc.c +1 -1
@@ -602,7 +602,7 @@ nfsd_proc_readdir(struct svc_rqst *rqstp) resp->cookie_offset =0 ; offset = argp->cookie; resp->status =nfsd_readdir (rqstp, &argp->fh, &offset, - &resp->common, nfs2svc_encode_entry); + &resp->common, nfssvc_encode_entry);nfssvc_encode_nfscookie (resp, offset);fh_put (&argp->fh);
fs/nfsd/nfsxdr.c +3 -48
69 lines not on this page · raw message
fs/nfsd/xdr.h +2 -8
@@ -115,10 +115,6 @@ struct nfsd_readdirres {struct xdr_stream xdr;struct xdr_buf dirlist;struct readdir_cd common; -__be32 * buffer; -int buflen; -__be32 * offset; -struct page *page;unsigned int cookie_offset; };
@@ -164,10 +160,8 @@ int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *);int nfssvc_encode_readdirres (struct svc_rqst *,__be32 *);void nfssvc_encode_nfscookie (struct nfsd_readdirres *resp,u32 offset); -int nfs2svc_encode_entry (void *data,const char *name,int namlen, -loff_t offset,u64 ino,unsigned int d_type); -int nfssvc_encode_entry (void *,const char *name, -int namlen,loff_t offset,u64 ino,unsigned int ); +int nfssvc_encode_entry (void *data,const char *name,int namlen, +loff_t offset,u64 ino,unsigned int d_type);void nfssvc_release_attrstat (struct svc_rqst *rqstp);void nfssvc_release_diropres (struct svc_rqst *rqstp);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 229/770 NFSD: Add an xdr_stream-based encoder for NFSv2/3 ACLs
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 8edc0648880a151026fe625fa1b76772b5766f68 ]
--- fs/nfs_common/nfsacl.c | 71 ++++++++++++++++++++++++++++++++++++++++++ include/linux/nfsacl.h | 3 ++ 2 files changed, 74 insertions(+)
fs/nfs_common/nfsacl.c +71 -0
@@ -136,6 +136,77 @@ int nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode, }EXPORT_SYMBOL_GPL (nfsacl_encode); +/** +* nfs_stream_encode_acl - Encode an NFSv3 ACL +* +* @xdr: an xdr_stream positioned to receive an encoded ACL +* @inode: inode of file whose ACL this is +* @acl: posix_acl to encode +* @encode_entries: whether to encode ACEs as well +* @typeflag: ACL type: NFS_ACL_DEFAULT or zero +* +* Return values: +* %false: The ACL could not be encoded +* %true: @xdr is advanced to the next available position +*/ +bool nfs_stream_encode_acl (struct xdr_stream *xdr,struct inode *inode, +struct posix_acl *acl,int encode_entries, +int typeflag) +{ +const size_t elem_size =XDR_UNIT *3 ; +u32 entries = (acl && acl->a_count) ?max_t (int, acl->a_count,4 ) :0 ; +struct nfsacl_encode_desc nfsacl_desc = { + .desc = { + .elem_size = elem_size, + .array_len = encode_entries ? entries :0 , + .xcode = xdr_nfsace_encode, + }, + .acl = acl, + .typeflag = typeflag, + .uid = inode->i_uid, + .gid = inode->i_gid, + }; +struct nfsacl_simple_acl aclbuf; +unsigned int base; +int err; + +if (entries >NFS_ACL_MAX_ENTRIES ) +return false; +if (xdr_stream_encode_u32 (xdr, entries) <0 ) +return false; + +if (encode_entries && acl && acl->a_count ==3 ) { +struct posix_acl *acl2 = &aclbuf.acl; + +/* Avoid the use of posix_acl_alloc(). nfsacl_encode() is +* invoked in contexts where a memory allocation failure is +* fatal. Fortunately this fake ACL is small enough to +* construct on the stack. */ +posix_acl_init (acl2,4 ); + +/* Insert entries in canonical order: other orders seem +to confuse Solaris VxFS. */ + acl2->a_entries[0 ] = acl->a_entries[0 ];/* ACL_USER_OBJ */ + acl2->a_entries[1 ] = acl->a_entries[1 ];/* ACL_GROUP_OBJ */ + acl2->a_entries[2 ] = acl->a_entries[1 ];/* ACL_MASK */ + acl2->a_entries[2 ].e_tag =ACL_MASK ; + acl2->a_entries[3 ] = acl->a_entries[2 ];/* ACL_OTHER */ + nfsacl_desc.acl = acl2; + } + + base =xdr_stream_pos (xdr); +if (!xdr_reserve_space (xdr,XDR_UNIT + + elem_size * nfsacl_desc.desc.array_len)) +return false; + err =xdr_encode_array2 (xdr->buf, base, &nfsacl_desc.desc); +if (err) +return false; + +return true; +} +EXPORT_SYMBOL_GPL (nfs_stream_encode_acl); + +struct nfsacl_decode_desc {struct xdr_array2_desc desc;unsigned int count;
include/linux/nfsacl.h +3 -0
@@ -41,5 +41,8 @@ nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,extern bool nfs_stream_decode_acl (struct xdr_stream *xdr,unsigned int *aclcnt,struct posix_acl **pacl); +extern bool +nfs_stream_encode_acl (struct xdr_stream *xdr,struct inode *inode, +struct posix_acl *acl,int encode_entries,int typeflag);#endif /* __LINUX_NFSACL_H */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 230/770 NFSD: Update the NFSv2 GETACL result encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit f8cba47344f794b54373189bec23195b51020faf ]
--- fs/nfsd/nfs2acl.c | 42 ++++++++++++++++-------------------------- fs/nfsd/nfsxdr.c | 24 ++++++++++++++++++++++-- fs/nfsd/xdr.h | 3 +++ 3 files changed, 41 insertions(+), 28 deletions(-)
fs/nfsd/nfs2acl.c +16 -26
@@ -240,51 +240,41 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p)/* GETACL */ static int nfsaclsvc_encode_getaclres (struct svc_rqst *rqstp,__be32 *p) { +struct xdr_stream *xdr = &rqstp->rq_res_stream;struct nfsd3_getaclres *resp = rqstp->rq_resp;struct dentry *dentry = resp->fh.fh_dentry;struct inode *inode; -struct kvec *head = rqstp->rq_res.head; -unsigned int base; -int n;int w; - *p++ = resp->status; -if (resp->status != nfs_ok) -return xdr_ressize_check (rqstp, p); +if (!svcxdr_encode_stat (xdr, resp->status)) +return 0 ; -/* -* Since this is version 2, the check for nfserr in -* nfsd_dispatch actually ensures the following cannot happen. -* However, it seems fragile to depend on that. -*/ if (dentry ==NULL ||d_really_is_negative (dentry)) -return 0 ; +return 1 ; inode =d_inode (dentry); - p =nfs2svc_encode_fattr (rqstp, p, &resp->fh, &resp->stat); - *p++ =htonl (resp->mask); -if (!xdr_ressize_check (rqstp, p)) +if (!svcxdr_encode_fattr (rqstp, xdr, &resp->fh, &resp->stat)) +return 0 ; +if (xdr_stream_encode_u32 (xdr, resp->mask) <0 )return 0 ; - base = (char *)p - (char *)head->iov_base; rqstp->rq_res.page_len = w =nfsacl_size ( (resp->mask &NFS_ACL ) ? resp->acl_access :NULL , (resp->mask &NFS_DFACL ) ? resp->acl_default :NULL );while (w >0 ) {if (!*(rqstp->rq_next_page++)) -return 0 ; +return 1 ; w -=PAGE_SIZE ; } - n =nfsacl_encode (&rqstp->rq_res, base, inode, - resp->acl_access, - resp->mask &NFS_ACL ,0 ); -if (n >0 ) - n =nfsacl_encode (&rqstp->rq_res, base + n, inode, - resp->acl_default, - resp->mask &NFS_DFACL , -NFS_ACL_DEFAULT ); -return (n >0 ); +if (!nfs_stream_encode_acl (xdr, inode, resp->acl_access, + resp->mask &NFS_ACL ,0 )) +return 0 ; +if (!nfs_stream_encode_acl (xdr, inode, resp->acl_default, + resp->mask &NFS_DFACL ,NFS_ACL_DEFAULT )) +return 0 ; + +return 1 ; }static int nfsaclsvc_encode_attrstatres (struct svc_rqst *rqstp,__be32 *p)
fs/nfsd/nfsxdr.c +22 -2
@@ -26,7 +26,16 @@ static const u32 nfs_ftypes[] = {* Basic NFSv2 data types (RFC 1094 Section 2.3) */ -static bool +/** +* svcxdr_encode_stat - Encode an NFSv2 status code +* @xdr: XDR stream +* @status: status value to encode +* +* Return values: +* %false: Send buffer space was exhausted +* %true: Success +*/ +bool svcxdr_encode_stat (struct xdr_stream *xdr,__be32 status) {__be32 *p;
@@ -250,7 +259,18 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,return p; } -static bool +/** +* svcxdr_encode_fattr - Encode NFSv2 file attributes +* @rqstp: Context of a completed RPC transaction +* @xdr: XDR stream +* @fhp: File handle to encode +* @stat: Attributes to encode +* +* Return values: +* %false: Send buffer space was exhausted +* %true: Success +*/ +bool svcxdr_encode_fattr (struct svc_rqst *rqstp,struct xdr_stream *xdr,const struct svc_fh *fhp,const struct kstat *stat) {
fs/nfsd/xdr.h +3 -0
@@ -170,5 +170,8 @@ void nfssvc_release_readres(struct svc_rqst *rqstp);/* Helper functions for NFSv2 ACL code */ __be32 *nfs2svc_encode_fattr (struct svc_rqst *rqstp,__be32 *p,struct svc_fh *fhp,struct kstat *stat);bool svcxdr_decode_fhandle (struct xdr_stream *xdr,struct svc_fh *fhp); +bool svcxdr_encode_stat (struct xdr_stream *xdr,__be32 status); +bool svcxdr_encode_fattr (struct svc_rqst *rqstp,struct xdr_stream *xdr, +const struct svc_fh *fhp,const struct kstat *stat);#endif /* LINUX_NFSD_H */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 231/770 NFSD: Update the NFSv2 SETACL result encoder to use struct xdr_stream
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 778f068fa0c0846b650ebdb8795fd51b5badc332 ]
The SETACL result encoder is exactly the same as the NFSv2 attrstatres decoder.
--- fs/nfsd/nfs2acl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/nfsd/nfs2acl.c +2 -2
@@ -363,8 +363,8 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = { [ACLPROC2_SETACL] = { .pc_func = nfsacld_proc_setacl, .pc_decode = nfsaclsvc_decode_setaclargs, - .pc_encode = nfsaclsvc_encode_attrstatres, - .pc_release = nfsaclsvc_release_attrstat, + .pc_encode = nfssvc_encode_attrstatres, + .pc_release = nfssvc_release_attrstat, .pc_argsize = sizeof(struct nfsd3_setaclargs), .pc_ressize = sizeof(struct nfsd_attrstat), .pc_cachetype = RC_NOCACHE,
Signature · 1 line
2.43.0