Commit 8bda9557 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull nfsd updates from Chuck Lever:
 "New features:

   - Support for server-side disconnect injection via debugfs

   - Protocol definitions for new RPC_AUTH_TLS authentication flavor

  Performance improvements:

   - Reduce page allocator traffic in the NFSD splice read actor

   - Reduce CPU utilization in svcrdma's Send completion handler

  Notable bug fixes:

   - Stabilize lockd operation when re-exporting NFS mounts

   - Fix the use of %.*s in NFSD tracepoints

   - Fix /proc/sys/fs/nfs/nsm_use_hostnames"

* tag 'nfsd-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (31 commits)
  nfsd: fix crash on LOCKT on reexported NFSv3
  nfs: don't allow reexport reclaims
  lockd: don't attempt blocking locks on nfs reexports
  nfs: don't atempt blocking locks on nfs reexports
  Keep read and write fds with each nlm_file
  lockd: update nlm_lookup_file reexport comment
  nlm: minor refactoring
  nlm: minor nlm_lookup_file argument change
  lockd: lockd server-side shouldn't set fl_ops
  SUNRPC: Add documentation for the fail_sunrpc/ directory
  SUNRPC: Server-side disconnect injection
  SUNRPC: Move client-side disconnect injection
  SUNRPC: Add a /sys/kernel/debug/fail_sunrpc/ directory
  svcrdma: xpt_bc_xprt is already clear in __svc_rdma_free()
  nfsd4: Fix forced-expiry locking
  rpc: fix gss_svc_init cleanup on failure
  SUNRPC: Add RPC_AUTH_TLS protocol numbers
  lockd: change the proc_handler for nsm_use_hostnames
  sysctl: introduce new proc handler proc_dobool
  SUNRPC: Fix a NULL pointer deref in trace_svc_stats_latency()
  ...
parents 4529fb15 0bcc7ca4
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -24,6 +24,10 @@ Available fault injection capabilities

  injects futex deadlock and uaddr fault errors.

- fail_sunrpc

  injects kernel RPC client and server failures.

- fail_make_request

  injects disk IO errors on devices permitted by setting
@@ -151,6 +155,20 @@ configuration of fault-injection capabilities.
	default is 'N', setting it to 'Y' will disable failure injections
	when dealing with private (address space) futexes.

- /sys/kernel/debug/fail_sunrpc/ignore-client-disconnect:

	Format: { 'Y' | 'N' }

	default is 'N', setting it to 'Y' will disable disconnect
	injection on the RPC client.

- /sys/kernel/debug/fail_sunrpc/ignore-server-disconnect:

	Format: { 'Y' | 'N' }

	default is 'N', setting it to 'Y' will disable disconnect
	injection on the RPC server.

- /sys/kernel/debug/fail_function/inject:

	Format: { 'function-name' | '!function-name' | '' }
+1 −1
Original line number Diff line number Diff line
@@ -584,7 +584,7 @@ static struct ctl_table nlm_sysctls[] = {
		.data		= &nsm_use_hostnames,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec,
		.proc_handler	= proc_dobool,
	},
	{
		.procname	= "nsm_local_state",
+5 −2
Original line number Diff line number Diff line
@@ -40,12 +40,15 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,

	/* Obtain file pointer. Not used by FREE_ALL call. */
	if (filp != NULL) {
		if ((error = nlm_lookup_file(rqstp, &file, &lock->fh)) != 0)
		int mode = lock_to_openmode(&lock->fl);

		error = nlm_lookup_file(rqstp, &file, lock);
		if (error)
			goto no_locks;
		*filp = file;

		/* Set up the missing parts of the file_lock structure */
		lock->fl.fl_file  = file->f_file;
		lock->fl.fl_file  = file->f_file[mode];
		lock->fl.fl_pid = current->tgid;
		lock->fl.fl_lmops = &nlmsvc_lock_operations;
		nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
+48 −34
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <linux/lockd/nlm.h>
#include <linux/lockd/lockd.h>
#include <linux/kthread.h>
#include <linux/exportfs.h>

#define NLMDBG_FACILITY		NLMDBG_SVCLOCK

@@ -395,28 +396,10 @@ nlmsvc_release_lockowner(struct nlm_lock *lock)
		nlmsvc_put_lockowner(lock->fl.fl_owner);
}

static void nlmsvc_locks_copy_lock(struct file_lock *new, struct file_lock *fl)
{
	struct nlm_lockowner *nlm_lo = (struct nlm_lockowner *)fl->fl_owner;
	new->fl_owner = nlmsvc_get_lockowner(nlm_lo);
}

static void nlmsvc_locks_release_private(struct file_lock *fl)
{
	nlmsvc_put_lockowner((struct nlm_lockowner *)fl->fl_owner);
}

static const struct file_lock_operations nlmsvc_lock_ops = {
	.fl_copy_lock = nlmsvc_locks_copy_lock,
	.fl_release_private = nlmsvc_locks_release_private,
};

void nlmsvc_locks_init_private(struct file_lock *fl, struct nlm_host *host,
						pid_t pid)
{
	fl->fl_owner = nlmsvc_find_lockowner(host, pid);
	if (fl->fl_owner != NULL)
		fl->fl_ops = &nlmsvc_lock_ops;
}

/*
@@ -488,17 +471,24 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
	    struct nlm_cookie *cookie, int reclaim)
{
	struct nlm_block	*block = NULL;
	struct inode		*inode = nlmsvc_file_inode(file);
	int			error;
	int			mode;
	int			async_block = 0;
	__be32			ret;

	dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
				locks_inode(file->f_file)->i_sb->s_id,
				locks_inode(file->f_file)->i_ino,
				inode->i_sb->s_id, inode->i_ino,
				lock->fl.fl_type, lock->fl.fl_pid,
				(long long)lock->fl.fl_start,
				(long long)lock->fl.fl_end,
				wait);

	if (inode->i_sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS) {
		async_block = wait;
		wait = 0;
	}

	/* Lock file against concurrent access */
	mutex_lock(&file->f_mutex);
	/* Get existing block (in case client is busy-waiting)
@@ -542,7 +532,8 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,

	if (!wait)
		lock->fl.fl_flags &= ~FL_SLEEP;
	error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
	mode = lock_to_openmode(&lock->fl);
	error = vfs_lock_file(file->f_file[mode], F_SETLK, &lock->fl, NULL);
	lock->fl.fl_flags &= ~FL_SLEEP;

	dprintk("lockd: vfs_lock_file returned %d\n", error);
@@ -558,7 +549,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
			 */
			if (wait)
				break;
			ret = nlm_lck_denied;
			ret = async_block ? nlm_lck_blocked : nlm_lck_denied;
			goto out;
		case FILE_LOCK_DEFERRED:
			if (wait)
@@ -595,12 +586,13 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
		struct nlm_lock *conflock, struct nlm_cookie *cookie)
{
	int			error;
	int			mode;
	__be32			ret;
	struct nlm_lockowner	*test_owner;

	dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
				locks_inode(file->f_file)->i_sb->s_id,
				locks_inode(file->f_file)->i_ino,
				nlmsvc_file_inode(file)->i_sb->s_id,
				nlmsvc_file_inode(file)->i_ino,
				lock->fl.fl_type,
				(long long)lock->fl.fl_start,
				(long long)lock->fl.fl_end);
@@ -613,7 +605,8 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
	/* If there's a conflicting lock, remember to clean up the test lock */
	test_owner = (struct nlm_lockowner *)lock->fl.fl_owner;

	error = vfs_test_lock(file->f_file, &lock->fl);
	mode = lock_to_openmode(&lock->fl);
	error = vfs_test_lock(file->f_file[mode], &lock->fl);
	if (error) {
		/* We can't currently deal with deferred test requests */
		if (error == FILE_LOCK_DEFERRED)
@@ -634,7 +627,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
	conflock->caller = "somehost";	/* FIXME */
	conflock->len = strlen(conflock->caller);
	conflock->oh.len = 0;		/* don't return OH info */
	conflock->svid = ((struct nlm_lockowner *)lock->fl.fl_owner)->pid;
	conflock->svid = lock->fl.fl_pid;
	conflock->fl.fl_type = lock->fl.fl_type;
	conflock->fl.fl_start = lock->fl.fl_start;
	conflock->fl.fl_end = lock->fl.fl_end;
@@ -659,11 +652,11 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
__be32
nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock)
{
	int	error;
	int	error = 0;

	dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n",
				locks_inode(file->f_file)->i_sb->s_id,
				locks_inode(file->f_file)->i_ino,
				nlmsvc_file_inode(file)->i_sb->s_id,
				nlmsvc_file_inode(file)->i_ino,
				lock->fl.fl_pid,
				(long long)lock->fl.fl_start,
				(long long)lock->fl.fl_end);
@@ -672,7 +665,12 @@ nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock)
	nlmsvc_cancel_blocked(net, file, lock);

	lock->fl.fl_type = F_UNLCK;
	error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
	if (file->f_file[O_RDONLY])
		error = vfs_lock_file(file->f_file[O_RDONLY], F_SETLK,
					&lock->fl, NULL);
	if (file->f_file[O_WRONLY])
		error = vfs_lock_file(file->f_file[O_WRONLY], F_SETLK,
					&lock->fl, NULL);

	return (error < 0)? nlm_lck_denied_nolocks : nlm_granted;
}
@@ -689,10 +687,11 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l
{
	struct nlm_block	*block;
	int status = 0;
	int mode;

	dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
				locks_inode(file->f_file)->i_sb->s_id,
				locks_inode(file->f_file)->i_ino,
				nlmsvc_file_inode(file)->i_sb->s_id,
				nlmsvc_file_inode(file)->i_ino,
				lock->fl.fl_pid,
				(long long)lock->fl.fl_start,
				(long long)lock->fl.fl_end);
@@ -704,7 +703,8 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l
	block = nlmsvc_lookup_block(file, lock);
	mutex_unlock(&file->f_mutex);
	if (block != NULL) {
		vfs_cancel_lock(block->b_file->f_file,
		mode = lock_to_openmode(&lock->fl);
		vfs_cancel_lock(block->b_file->f_file[mode],
				&block->b_call->a_args.lock.fl);
		status = nlmsvc_unlink_block(block);
		nlmsvc_release_block(block);
@@ -788,9 +788,21 @@ nlmsvc_notify_blocked(struct file_lock *fl)
	printk(KERN_WARNING "lockd: notification for unknown block!\n");
}

static fl_owner_t nlmsvc_get_owner(fl_owner_t owner)
{
	return nlmsvc_get_lockowner(owner);
}

static void nlmsvc_put_owner(fl_owner_t owner)
{
	nlmsvc_put_lockowner(owner);
}

const struct lock_manager_operations nlmsvc_lock_operations = {
	.lm_notify = nlmsvc_notify_blocked,
	.lm_grant = nlmsvc_grant_deferred,
	.lm_get_owner = nlmsvc_get_owner,
	.lm_put_owner = nlmsvc_put_owner,
};

/*
@@ -809,6 +821,7 @@ nlmsvc_grant_blocked(struct nlm_block *block)
{
	struct nlm_file		*file = block->b_file;
	struct nlm_lock		*lock = &block->b_call->a_args.lock;
	int			mode;
	int			error;
	loff_t			fl_start, fl_end;

@@ -834,7 +847,8 @@ nlmsvc_grant_blocked(struct nlm_block *block)
	lock->fl.fl_flags |= FL_SLEEP;
	fl_start = lock->fl.fl_start;
	fl_end = lock->fl.fl_end;
	error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
	mode = lock_to_openmode(&lock->fl);
	error = vfs_lock_file(file->f_file[mode], F_SETLK, &lock->fl, NULL);
	lock->fl.fl_flags &= ~FL_SLEEP;
	lock->fl.fl_start = fl_start;
	lock->fl.fl_end = fl_end;
+4 −2
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
	struct nlm_host		*host = NULL;
	struct nlm_file		*file = NULL;
	struct nlm_lock		*lock = &argp->lock;
	int			mode;
	__be32			error = 0;

	/* nfsd callbacks must have been installed for this procedure */
@@ -69,13 +70,14 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,

	/* Obtain file pointer. Not used by FREE_ALL call. */
	if (filp != NULL) {
		error = cast_status(nlm_lookup_file(rqstp, &file, &lock->fh));
		error = cast_status(nlm_lookup_file(rqstp, &file, lock));
		if (error != 0)
			goto no_locks;
		*filp = file;

		/* Set up the missing parts of the file_lock structure */
		lock->fl.fl_file  = file->f_file;
		mode = lock_to_openmode(&lock->fl);
		lock->fl.fl_file  = file->f_file[mode];
		lock->fl.fl_pid = current->tgid;
		lock->fl.fl_lmops = &nlmsvc_lock_operations;
		nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
Loading