All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jeff.layton@primarydata.com>
To: bfields@fieldses.org
Cc: linux-nfs@vger.kernel.org
Subject: Re: [PATCH v2 033/117] nfsd: ensure that nfs4_file_get_access enforces deny modes
Date: Fri, 27 Jun 2014 15:59:58 -0400	[thread overview]
Message-ID: <20140627155958.10a6420d@tlielax.poochiereds.net> (raw)
In-Reply-To: <1403810017-16062-34-git-send-email-jlayton@primarydata.com>

On Thu, 26 Jun 2014 15:12:13 -0400
Jeff Layton <jlayton@primarydata.com> wrote:

> The current enforcement of deny modes is both inefficient and scattered.
> The former is a problem now, and the latter problem will mean races once
> the client_mutex is removed.
> 
> First, we address the inefficiency. We (necessarily) track deny modes on
> a per-stateid basis, but when we go to enforce them we have to walk the
> entire list of stateids and check against each one. Instead of doing
> that, maintain a per-nfs4_file deny mode.
> 
> When a file is opened, we simply set any deny bits in that mode that
> were specified in the OPEN call. We can then use that unified deny mode
> to do a simple check to see whether there are any conflicts without
> needing to walk the entire stateid list.
> 
> The only time we'll need to walk the entire list of stateids is when
> a stateid that has a deny mode on it is being released, or one is having
> its deny mode downgraded. In that case, we must walk the entire list
> and recalculate the fi_share_deny field. Since deny modes are pretty
> rare today, this shouldn't happen much under normal workloads.
> 
> To address the potential for races once the client_mutex is removed, we
> first check for conflicting deny modes in nfs4_file_get_access prior to
> opening the file. If it turns out that we need to do a VFS layer open of
> the file, then do so and recheck for conflicting deny modes afterward.
> If there are any, then just put access to the file and return
> nfserr_share_denied.
> 
> Finally, deal with potential races in get_lock_access. Taking an
> fi_access reference must be done under the fi_lock, or that could race
> with a nfs4_file_put_access call. Since we will have just dropped the
> lock after finding a readable or writeable file, add some *_locked
> variants of find_readable_file and find_writeable_file that we can call
> while already holding the fi_lock.
> 
> Signed-off-by: Jeff Layton <jlayton@primarydata.com>
> ---
>  fs/nfsd/nfs4state.c | 229 +++++++++++++++++++++++++++++++++++++++-------------
>  fs/nfsd/state.h     |   1 +
>  2 files changed, 172 insertions(+), 58 deletions(-)
> 
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index 0b6cd933eac6..93d175661c8d 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -276,27 +276,49 @@ static struct file *__nfs4_get_fd(struct nfs4_file *f, int oflag)
>  	return NULL;
>  }
>  
> -static struct file *find_writeable_file(struct nfs4_file *f)
> +static struct file *find_writeable_file_locked(struct nfs4_file *f)
>  {
>  	struct file *ret;
>  
> -	spin_lock(&f->fi_lock);
> +	lockdep_assert_held(&f->fi_lock);
> +
>  	ret = __nfs4_get_fd(f, O_WRONLY);
>  	if (!ret)
>  		ret = __nfs4_get_fd(f, O_RDWR);
> -	spin_unlock(&f->fi_lock);
>  	return ret;
>  }
>  
> -static struct file *find_readable_file(struct nfs4_file *f)
> +static struct file *find_writeable_file(struct nfs4_file *f)
>  {
>  	struct file *ret;
>  
>  	spin_lock(&f->fi_lock);
> +	ret = find_writeable_file_locked(f);
> +	spin_unlock(&f->fi_lock);
> +
> +	return ret;
> +}
> +
> +static struct file *find_readable_file_locked(struct nfs4_file *f)
> +{
> +	struct file *ret;
> +
> +	lockdep_assert_held(&f->fi_lock);
> +
>  	ret = __nfs4_get_fd(f, O_RDONLY);
>  	if (!ret)
>  		ret = __nfs4_get_fd(f, O_RDWR);
> +	return ret;
> +}
> +
> +static struct file *find_readable_file(struct nfs4_file *f)
> +{
> +	struct file *ret;
> +
> +	spin_lock(&f->fi_lock);
> +	ret = find_readable_file_locked(f);
>  	spin_unlock(&f->fi_lock);
> +
>  	return ret;
>  }
>  
> @@ -362,26 +384,72 @@ static unsigned int file_hashval(struct inode *ino)
>  
>  static struct hlist_head file_hashtbl[FILE_HASH_SIZE];
>  
> -static void __nfs4_file_get_access(struct nfs4_file *fp, int oflag)
> +static void
> +__nfs4_file_get_access(struct nfs4_file *fp, u32 access)
>  {
> -	WARN_ON_ONCE(!(fp->fi_fds[oflag] || fp->fi_fds[O_RDWR]));
> -	atomic_inc(&fp->fi_access[oflag]);
> +	int oflag = nfs4_access_to_omode(access);
> +
> +	lockdep_assert_held(&fp->fi_lock);
> +
> +	if (oflag == O_RDWR) {
> +		atomic_inc(&fp->fi_access[O_RDONLY]);
> +		atomic_inc(&fp->fi_access[O_WRONLY]);
> +	} else
> +		atomic_inc(&fp->fi_access[oflag]);
>  }
>  
> -static void nfs4_file_get_access(struct nfs4_file *fp, u32 access)
> +static __be32
> +nfs4_file_get_access(struct nfs4_file *fp, u32 access)
>  {
> -	int oflag = nfs4_access_to_omode(access);
> -
>  	/* Note: relies on NFS4_SHARE_ACCESS_BOTH == READ|WRITE */
> -	access &= (NFS4_SHARE_ACCESS_READ|NFS4_SHARE_ACCESS_WRITE);
> +	access &= NFS4_SHARE_ACCESS_BOTH;
> +
> +	/* Does this access mask make sense? */
>  	if (access == 0)
> -		return;
> +		return nfserr_inval;
>  
> -	if (oflag == O_RDWR) {
> -		__nfs4_file_get_access(fp, O_RDONLY);
> -		__nfs4_file_get_access(fp, O_WRONLY);
> -	} else
> -		__nfs4_file_get_access(fp, oflag);
> +	/* Does it conflict with a deny mode already set? */
> +	if ((access & fp->fi_share_deny) != 0)
> +		return nfserr_share_denied;
> +
> +	__nfs4_file_get_access(fp, access);
> +	return nfs_ok;
> +}
> +
> +static __be32 nfs4_file_check_deny(struct nfs4_file *fp, u32 access, u32 deny)
> +{
> +	int rdcnt = 0;
> +	int wrcnt = 0;
> +
> +	lockdep_assert_held(&fp->fi_lock);
> +

We should optimize this function for the vastly common case where
"deny" is 0. Check for that and return nfs_ok immediately if it is.

> +	/*
> +	 * We must take into account any references that were already taken
> +	 * on behalf of this open attempt.
> +	 */
> +	switch (access) {
> +	case NFS4_SHARE_ACCESS_READ:
> +		++rdcnt;
> +		break;
> +	case NFS4_SHARE_ACCESS_WRITE:
> +		++wrcnt;
> +		break;
> +	case NFS4_SHARE_ACCESS_BOTH:
> +		++rdcnt;
> +		++wrcnt;
> +	}
> +
> +	/* Note: relies on NFS4_SHARE_DENY_BOTH == READ|WRITE */
> +	deny &= NFS4_SHARE_DENY_BOTH;
> +	if (deny) {
> +		if ((deny & NFS4_SHARE_DENY_READ) &&
> +		    (atomic_read(&fp->fi_access[O_RDONLY]) - rdcnt) > 0)
> +			return nfserr_share_denied;
> +		if ((deny & NFS4_SHARE_DENY_WRITE) &&
> +		    (atomic_read(&fp->fi_access[O_WRONLY]) - wrcnt) > 0)
> +			return nfserr_share_denied;
> +	}
> +	return nfs_ok;
>  }
>  
>  static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag)
> @@ -710,17 +778,6 @@ bmap_to_share_mode(unsigned long bmap) {
>  	return access;
>  }
>  
> -static bool
> -test_share(struct nfs4_ol_stateid *stp, struct nfsd4_open *open) {
> -	unsigned int access, deny;
> -
> -	access = bmap_to_share_mode(stp->st_access_bmap);
> -	deny = bmap_to_share_mode(stp->st_deny_bmap);
> -	if ((access & open->op_share_deny) || (deny & open->op_share_access))
> -		return false;
> -	return true;
> -}
> -
>  /* set share access for a given stateid */
>  static inline void
>  set_access(u32 access, struct nfs4_ol_stateid *stp)
> @@ -763,11 +820,31 @@ test_deny(u32 access, struct nfs4_ol_stateid *stp)
>  	return test_bit(access, &stp->st_deny_bmap);
>  }
>  
> +/*
> + * A stateid that had a deny mode associated with it is being released
> + * or downgraded. Recalculate the deny mode on the file.
> + */
> +static void
> +recalculate_deny_mode(struct nfs4_file *fp)
> +{
> +	struct nfs4_ol_stateid *stp;
> +
> +	spin_lock(&fp->fi_lock);
> +	fp->fi_share_deny = 0;
> +	list_for_each_entry(stp, &fp->fi_stateids, st_perfile)
> +		fp->fi_share_deny |= bmap_to_share_mode(stp->st_deny_bmap);
> +	spin_unlock(&fp->fi_lock);
> +}
> +
>  /* release all access and file references for a given stateid */
>  static void
>  release_all_access(struct nfs4_ol_stateid *stp)
>  {
>  	int i;
> +	struct nfs4_file *fp = stp->st_file;
> +
> +	if (fp && stp->st_deny_bmap != 0)
> +		recalculate_deny_mode(fp);
>  
>  	for (i = 1; i < 4; i++) {
>  		if (test_access(i, stp))
> @@ -2760,6 +2837,7 @@ static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino)
>  	fp->fi_inode = ino;
>  	fp->fi_had_conflict = false;
>  	fp->fi_lease = NULL;
> +	fp->fi_share_deny = 0;
>  	memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
>  	memset(fp->fi_access, 0, sizeof(fp->fi_access));
>  	hlist_add_head(&fp->fi_hash, &file_hashtbl[hashval]);
> @@ -2988,22 +3066,15 @@ nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
>  {
>  	struct inode *ino = current_fh->fh_dentry->d_inode;
>  	struct nfs4_file *fp;
> -	struct nfs4_ol_stateid *stp;
> -	__be32 ret;
> +	__be32 ret = nfs_ok;
>  
>  	fp = find_file(ino);
>  	if (!fp)
> -		return nfs_ok;
> -	ret = nfserr_locked;
> -	/* Search for conflicting share reservations */
> +		return ret;
> +	/* Check for conflicting share reservations */
>  	spin_lock(&fp->fi_lock);
> -	list_for_each_entry(stp, &fp->fi_stateids, st_perfile) {
> -		if (test_deny(deny_type, stp) ||
> -		    test_deny(NFS4_SHARE_DENY_BOTH, stp))
> -			goto out;
> -	}
> -	ret = nfs_ok;
> -out:
> +	if (fp->fi_share_deny & deny_type)
> +		ret = nfserr_locked;
>  	spin_unlock(&fp->fi_lock);
>  	put_nfs4_file(fp);
>  	return ret;
> @@ -3204,21 +3275,18 @@ nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_ol_st
>  	struct nfs4_ol_stateid *local;
>  	struct nfs4_openowner *oo = open->op_openowner;
>  
> -	spin_lock(&fp->fi_lock);
> +	lockdep_assert_held(&fp->fi_lock);
> +
>  	list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
>  		/* ignore lock owners */
>  		if (local->st_stateowner->so_is_open_owner == 0)
>  			continue;
>  		/* remember if we have seen this open owner */
> -		if (local->st_stateowner == &oo->oo_owner)
> +		if (local->st_stateowner == &oo->oo_owner) {
>  			*stpp = local;
> -		/* check for conflicting share reservations */
> -		if (!test_share(local, open)) {
> -			spin_unlock(&fp->fi_lock);
> -			return nfserr_share_denied;
> +			break;
>  		}
>  	}
> -	spin_unlock(&fp->fi_lock);
>  	return nfs_ok;
>  }
>  
> @@ -3257,18 +3325,46 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
>  	int access = nfs4_access_to_access(open->op_share_access);
>  
>  	spin_lock(&fp->fi_lock);
> +	/* Are we trying to set a deny mode that would conflict? */
> +	status = nfs4_file_check_deny(fp, 0, open->op_share_deny);
> +	if (status != nfs_ok) {
> +		spin_unlock(&fp->fi_lock);
> +		goto out;
> +	}
> +
> +	/* Set access to the file */
> +	status = nfs4_file_get_access(fp, open->op_share_access);
> +	if (status != nfs_ok) {
> +		spin_unlock(&fp->fi_lock);
> +		goto out;
> +	}
> +
>  	if (!fp->fi_fds[oflag]) {
>  		spin_unlock(&fp->fi_lock);
>  		status = nfsd_open(rqstp, cur_fh, S_IFREG, access, &filp);
>  		if (status)
> -			goto out;
> +			goto out_put_access;
>  		spin_lock(&fp->fi_lock);
>  		if (!fp->fi_fds[oflag]) {
>  			fp->fi_fds[oflag] = filp;
>  			filp = NULL;
>  		}
> +
> +		/*
> +		 * Recheck: did someone race in and open the file in a way that
> +		 *	    would conflict with our deny bits?
> +		 */
> +		if (nfs4_file_check_deny(fp, open->op_share_access,
> +					 open->op_share_deny)) {
> +			spin_unlock(&fp->fi_lock);
> +			status = nfserr_share_denied;
> +			goto out_put_access;
> +		}
> +
> +		/* Set any new deny bits */
> +		fp->fi_share_deny |= (open->op_share_deny &
> +					NFS4_SHARE_DENY_BOTH);

Oof, I think we have a potential race here. It's possible that we'll
end up setting new bits in fi_share_deny, but then another task comes
along and does a recalculation of it just after the fi_lock is dropped
below. Since the stateid isn't hashed yet, it won't get factored into
the recalculated deny mode and we'll lose those bits.

I think the remedy is probably to go ahead and just hash the stateid
before calling nfs4_get_vfs_file. Then if it returns error, we'll just
have to unhash it and ensure that it's eventually destroyed.

So, this patch will probably need a respin to deal with that.

>  	}
> -	nfs4_file_get_access(fp, open->op_share_access);
>  	spin_unlock(&fp->fi_lock);
>  	if (filp)
>  		fput(filp);
> @@ -3276,13 +3372,11 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
>  	status = nfsd4_truncate(rqstp, cur_fh, open);
>  	if (status)
>  		goto out_put_access;
> -
> -	return nfs_ok;
> -
> -out_put_access:
> -	nfs4_file_put_access(fp, open->op_share_access);
>  out:
>  	return status;
> +out_put_access:
> +	nfs4_file_put_access(fp, open->op_share_access);
> +	goto out;
>  }
>  
>  static __be32
> @@ -3526,7 +3620,12 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
>  	 */
>  	fp = find_or_add_file(ino, open->op_file);
>  	if (fp != open->op_file) {
> -		if ((status = nfs4_check_open(fp, open, &stp)))
> +		spin_lock(&fp->fi_lock);
> +		status = nfs4_file_check_deny(fp, 0, open->op_share_deny);
> +		if (status == nfs_ok)
> +			status = nfs4_check_open(fp, open, &stp);
> +		spin_unlock(&fp->fi_lock);
> +		if (status)
>  			goto out;
>  		status = nfs4_check_deleg(cl, open, &dp);
>  		if (status)
> @@ -4241,10 +4340,16 @@ static void
>  reset_union_bmap_deny(unsigned long deny, struct nfs4_ol_stateid *stp)
>  {
>  	int i;
> +	u32 prev_deny = bmap_to_share_mode(stp->st_deny_bmap);
> +
>  	for (i = 0; i < 4; i++) {
>  		if ((i & deny) != i)
>  			clear_deny(i, stp);
>  	}
> +
> +	/* Downgrade per-file deny mode if this one changed */
> +	if (prev_deny != deny)
> +		recalculate_deny_mode(stp->st_file);
>  }
>  
>  __be32
> @@ -4541,9 +4646,11 @@ static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access)
>  {
>  	struct nfs4_file *fp = lock_stp->st_file;
>  
> +	lockdep_assert_held(&fp->fi_lock);
> +
>  	if (test_access(access, lock_stp))
>  		return;
> -	nfs4_file_get_access(fp, access);
> +	__nfs4_file_get_access(fp, access);
>  	set_access(access, lock_stp);
>  }
>  
> @@ -4595,6 +4702,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
>  	struct file *filp = NULL;
>  	struct file_lock *file_lock = NULL;
>  	struct file_lock *conflock = NULL;
> +	struct nfs4_file *fp;
>  	__be32 status = 0;
>  	bool new_state = false;
>  	int lkflg;
> @@ -4672,20 +4780,25 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
>  		goto out;
>  	}
>  
> +	fp = lock_stp->st_file;
>  	locks_init_lock(file_lock);
>  	switch (lock->lk_type) {
>  		case NFS4_READ_LT:
>  		case NFS4_READW_LT:
> -			filp = find_readable_file(lock_stp->st_file);
> +			spin_lock(&fp->fi_lock);
> +			filp = find_readable_file_locked(fp);
>  			if (filp)
>  				get_lock_access(lock_stp, NFS4_SHARE_ACCESS_READ);
> +			spin_unlock(&fp->fi_lock);
>  			file_lock->fl_type = F_RDLCK;
>  			break;
>  		case NFS4_WRITE_LT:
>  		case NFS4_WRITEW_LT:
> -			filp = find_writeable_file(lock_stp->st_file);
> +			spin_lock(&fp->fi_lock);
> +			filp = find_writeable_file_locked(fp);
>  			if (filp)
>  				get_lock_access(lock_stp, NFS4_SHARE_ACCESS_WRITE);
> +			spin_unlock(&fp->fi_lock);
>  			file_lock->fl_type = F_WRLCK;
>  			break;
>  		default:
> diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
> index dc56ec234df7..561b94181751 100644
> --- a/fs/nfsd/state.h
> +++ b/fs/nfsd/state.h
> @@ -392,6 +392,7 @@ struct nfs4_file {
>  	 *   + 1 to both of the above if NFS4_SHARE_ACCESS_BOTH is set.
>  	 */
>  	atomic_t		fi_access[2];
> +	u32			fi_share_deny;
>  	struct file		*fi_deleg_file;
>  	struct file_lock	*fi_lease;
>  	atomic_t		fi_delegees;


-- 
Jeff Layton <jlayton@primarydata.com>

  reply	other threads:[~2014-06-27 20:00 UTC|newest]

Thread overview: 162+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-26 19:11 [PATCH v2 000/117] nfsd: eliminate the client_mutex Jeff Layton
2014-06-26 19:11 ` [PATCH v2 001/117] nfsd: fix file access refcount leak when nfsd4_truncate fails Jeff Layton
2014-06-26 19:24   ` Jeff Layton
2014-06-28 11:00     ` Christoph Hellwig
2014-06-26 19:11 ` [PATCH v2 002/117] nfsd: fix return of nfs4_acl_write_who Jeff Layton
2014-06-26 19:11 ` [PATCH v2 003/117] nfsd: add __force to opaque verifier field casts Jeff Layton
2014-06-26 19:11 ` [PATCH v2 004/117] nfsd: clean up sparse endianness warnings in nfscache.c Jeff Layton
2014-06-26 19:11 ` [PATCH v2 005/117] nfsd: nfsd_splice_read and nfsd_readv should return __be32 Jeff Layton
2014-06-26 19:11 ` [PATCH v2 006/117] nfsd: add appropriate __force directives to filehandle generation code Jeff Layton
2014-06-26 19:11 ` [PATCH v2 007/117] nfsd: properly handle embedded newlines in fault_injection input Jeff Layton
2014-06-28 11:01   ` Christoph Hellwig
2014-06-26 19:11 ` [PATCH v2 008/117] nfsd: Protect addition to the file_hashtbl Jeff Layton
2014-06-26 19:11 ` [PATCH v2 009/117] nfsd: wait to initialize work struct just prior to using it Jeff Layton
2014-06-28 11:02   ` Christoph Hellwig
2014-06-26 19:11 ` [PATCH v2 010/117] nfsd: Avoid taking state_lock while holding inode lock in nfsd_break_one_deleg Jeff Layton
2014-06-28 11:06   ` Christoph Hellwig
2014-06-28 12:18     ` Jeff Layton
2014-06-26 19:11 ` [PATCH v2 011/117] nfsd: nfs4_preprocess_seqid_op should only set *stpp on success Jeff Layton
2014-06-26 19:11 ` [PATCH v2 012/117] nfsd: Cleanup nfs4svc_encode_compoundres Jeff Layton
2014-06-26 19:11 ` [PATCH v2 013/117] nfsd: Don't get a session reference without a client reference Jeff Layton
2014-06-26 19:11 ` [PATCH v2 014/117] nfsd: Allow struct nfsd4_compound_state to cache the nfs4_client Jeff Layton
2014-06-29 12:05   ` Christoph Hellwig
2014-06-26 19:11 ` [PATCH v2 015/117] nfsd: lock owners are not per open stateid Jeff Layton
2014-06-28 11:07   ` Christoph Hellwig
2014-06-26 19:11 ` [PATCH v2 016/117] nfsd: Allow lockowners to hold several stateids Jeff Layton
2014-06-26 19:11 ` [PATCH v2 017/117] nfsd: NFSv4 lock-owners are not associated to a specific file Jeff Layton
2014-06-26 19:11 ` [PATCH v2 018/117] nfsd: clean up nfs4_release_lockowner Jeff Layton
2014-06-29  6:47   ` Christoph Hellwig
2014-06-29 11:08     ` Jeff Layton
2014-06-30 11:02       ` Jeff Layton
2014-06-30 11:04         ` Christoph Hellwig
2014-06-26 19:11 ` [PATCH v2 019/117] nfsd: declare v4.1+ openowners confirmed on creation Jeff Layton
2014-06-29  6:48   ` Christoph Hellwig
2014-06-26 19:12 ` [PATCH v2 020/117] nfsd: Cleanup - Let nfsd4_lookup_stateid() take a cstate argument Jeff Layton
2014-06-29  6:49   ` Christoph Hellwig
2014-06-26 19:12 ` [PATCH v2 021/117] nfsd: clean up nfsd4_close_open_stateid Jeff Layton
2014-06-29 12:00   ` Christoph Hellwig
2014-06-26 19:12 ` [PATCH v2 022/117] nfsd: Cache the client that was looked up in lookup_clientid() Jeff Layton
2014-06-29 12:14   ` Christoph Hellwig
2014-06-29 14:57     ` Jeff Layton
2014-06-30 10:34       ` Christoph Hellwig
2014-06-30 10:59         ` Jeff Layton
2014-06-30 11:03           ` Christoph Hellwig
2014-06-30 11:23             ` Jeff Layton
2014-06-26 19:12 ` [PATCH v2 023/117] nfsd: Convert nfsd4_process_open1() to work with lookup_clientid() Jeff Layton
2014-06-29 12:16   ` Christoph Hellwig
2014-06-29 15:08     ` Jeff Layton
2014-06-30 10:35       ` Christoph Hellwig
2014-06-26 19:12 ` [PATCH v2 024/117] nfsd: Always use lookup_clientid() in nfsd4_process_open1 Jeff Layton
2014-06-29 12:16   ` Christoph Hellwig
2014-06-26 19:12 ` [PATCH v2 025/117] nfsd: Convert nfs4_check_open_reclaim() to work with lookup_clientid() Jeff Layton
2014-06-29 12:17   ` Christoph Hellwig
2014-06-26 19:12 ` [PATCH v2 026/117] nfsd: Move the delegation reference counter into the struct nfs4_stid Jeff Layton
2014-06-26 19:12 ` [PATCH v2 027/117] nfsd4: use cl_lock to synchronize all stateid idr calls Jeff Layton
2014-06-26 19:12 ` [PATCH v2 028/117] nfsd: Add fine grained protection for the nfs4_file->fi_stateids list Jeff Layton
2014-06-26 19:12 ` [PATCH v2 029/117] nfsd: Add a mutex to protect the NFSv4.0 open owner replay cache Jeff Layton
2014-06-26 19:12 ` [PATCH v2 030/117] nfsd: Add locking to the nfs4_file->fi_fds[] array Jeff Layton
2014-06-26 19:12 ` [PATCH v2 031/117] nfsd: refactor nfs4_file_get_access and nfs4_file_put_access Jeff Layton
2014-06-26 19:12 ` [PATCH v2 032/117] nfsd: remove nfs4_file_put_fd Jeff Layton
2014-06-26 19:12 ` [PATCH v2 033/117] nfsd: ensure that nfs4_file_get_access enforces deny modes Jeff Layton
2014-06-27 19:59   ` Jeff Layton [this message]
2014-06-26 19:12 ` [PATCH v2 034/117] nfsd: cleanup nfs4_check_open Jeff Layton
2014-06-26 19:12 ` [PATCH v2 035/117] locks: add file_has_lease to prevent delegation break races Jeff Layton
2014-06-26 19:12 ` [PATCH v2 036/117] nfsd: Protect the nfs4_file delegation fields using the fi_lock Jeff Layton
2014-06-26 19:12 ` [PATCH v2 037/117] nfsd: clean up helper __release_lock_stateid Jeff Layton
2014-06-30 10:40   ` Christoph Hellwig
2014-06-30 10:53     ` Jeff Layton
2014-06-26 19:12 ` [PATCH v2 038/117] nfsd: Simplify stateid management Jeff Layton
2014-06-26 19:12 ` [PATCH v2 039/117] nfsd: Fix delegation revocation Jeff Layton
2014-06-26 19:12 ` [PATCH v2 040/117] nfsd: Add reference counting to the lock and open stateids Jeff Layton
2014-06-26 19:12 ` [PATCH v2 041/117] nfsd: Add a struct nfs4_file field to struct nfs4_stid Jeff Layton
2014-06-26 19:12 ` [PATCH v2 042/117] nfsd: Replace nfs4_ol_stateid->st_file with the st_stid.sc_file Jeff Layton
2014-06-26 19:12 ` [PATCH v2 043/117] nfsd: Ensure stateids remain unique until they are freed Jeff Layton
2014-06-26 19:12 ` [PATCH v2 044/117] nfsd: Ensure atomicity of stateid destruction and idr tree removal Jeff Layton
2014-06-26 19:12 ` [PATCH v2 045/117] nfsd: Cleanup the freeing of stateids Jeff Layton
2014-06-26 19:12 ` [PATCH v2 046/117] nfsd: do filp_close in sc_free callback for lock stateids Jeff Layton
2014-06-26 19:12 ` [PATCH v2 047/117] nfsd: Add locking to protect the state owner lists Jeff Layton
2014-06-26 19:12 ` [PATCH v2 048/117] nfsd: clean up races in lock stateid searching and creation Jeff Layton
2014-06-26 19:12 ` [PATCH v2 049/117] nfsd: Convert delegation counter to an atomic_long_t type Jeff Layton
2014-06-26 19:12 ` [PATCH v2 050/117] nfsd: Slight cleanup of find_stateid() Jeff Layton
2014-06-26 19:12 ` [PATCH v2 051/117] nfsd: ensure atomicity in nfsd4_free_stateid and nfsd4_validate_stateid Jeff Layton
2014-06-26 19:12 ` [PATCH v2 052/117] nfsd: Add reference counting to lock stateids Jeff Layton
2014-06-26 19:12 ` [PATCH v2 053/117] nfsd: nfsd4_locku() must reference the lock stateid Jeff Layton
2014-06-26 19:12 ` [PATCH v2 054/117] nfsd: Ensure that nfs4_open_delegation() references the delegation stateid Jeff Layton
2014-06-26 19:12 ` [PATCH v2 055/117] nfsd: nfsd4_process_open2() must reference " Jeff Layton
2014-06-26 19:12 ` [PATCH v2 056/117] nfsd: nfsd4_process_open2() must reference the open stateid Jeff Layton
2014-06-26 19:12 ` [PATCH v2 057/117] nfsd: Prepare nfsd4_close() for open stateid referencing Jeff Layton
2014-06-26 19:12 ` [PATCH v2 058/117] nfsd: nfsd4_open_confirm() must reference the open stateid Jeff Layton
2014-06-26 19:12 ` [PATCH v2 059/117] nfsd: Add reference counting to nfs4_preprocess_confirmed_seqid_op Jeff Layton
2014-06-26 19:12 ` [PATCH v2 060/117] nfsd: Migrate the stateid reference into nfs4_preprocess_seqid_op Jeff Layton
2014-06-26 19:12 ` [PATCH v2 061/117] nfsd: Migrate the stateid reference into nfs4_lookup_stateid() Jeff Layton
2014-06-26 19:12 ` [PATCH v2 062/117] nfsd: Migrate the stateid reference into nfs4_find_stateid_by_type() Jeff Layton
2014-06-26 19:12 ` [PATCH v2 063/117] nfsd: Add reference counting to state owners Jeff Layton
2014-06-26 19:12 ` [PATCH v2 064/117] nfsd: Keep a reference to the open stateid for the NFSv4.0 replay cache Jeff Layton
2014-06-26 19:12 ` [PATCH v2 065/117] nfsd: clean up lockowner refcounting when finding them Jeff Layton
2014-06-26 19:12 ` [PATCH v2 066/117] nfsd: add an operation for unhashing a stateowner Jeff Layton
2014-06-26 19:12 ` [PATCH v2 067/117] nfsd: Make lock stateid take a reference to the lockowner Jeff Layton
2014-06-26 19:12 ` [PATCH v2 068/117] nfsd: clean up refcounting for lockowners Jeff Layton
2014-06-26 19:12 ` [PATCH v2 069/117] nfsd: make openstateids hold references to their openowners Jeff Layton
2014-06-26 19:12 ` [PATCH v2 070/117] nfsd: don't allow CLOSE to proceed until refcount on stateid drops Jeff Layton
2014-06-26 19:12 ` [PATCH v2 071/117] nfsd: Protect adding/removing open state owners using client_lock Jeff Layton
2014-06-26 19:12 ` [PATCH v2 072/117] nfsd: Protect adding/removing lock " Jeff Layton
2014-06-26 19:12 ` [PATCH v2 073/117] nfsd: Move the open owner hash table into struct nfs4_client Jeff Layton
2014-06-26 19:12 ` [PATCH v2 074/117] lockdep: add lockdep_assert_not_held Jeff Layton
2014-06-26 19:12 ` [PATCH v2 075/117] nfsd: add locking to stateowner release Jeff Layton
2014-06-26 19:12 ` [PATCH v2 076/117] nfsd: optimize destroy_lockowner cl_lock thrashing Jeff Layton
2014-06-26 19:12 ` [PATCH v2 077/117] nfsd: close potential race in nfsd4_free_stateid Jeff Layton
2014-06-26 19:12 ` [PATCH v2 078/117] nfsd: reduce cl_lock thrashing in release_openowner Jeff Layton
2014-06-26 19:12 ` [PATCH v2 079/117] nfsd: don't thrash the cl_lock while freeing an open stateid Jeff Layton
2014-06-26 19:13 ` [PATCH v2 080/117] nfsd: Ensure struct nfs4_client is unhashed before we try to destroy it Jeff Layton
2014-06-26 19:13 ` [PATCH v2 081/117] nfsd: Ensure that the laundromat unhashes the client before releasing locks Jeff Layton
2014-06-26 19:13 ` [PATCH v2 082/117] nfsd: Don't require client_lock in free_client Jeff Layton
2014-06-26 19:13 ` [PATCH v2 083/117] nfsd: Move create_client() call outside the lock Jeff Layton
2014-06-26 19:20 ` [PATCH v2 084/117] nfsd: Protect unconfirmed client creation using client_lock Jeff Layton
2014-06-26 19:20 ` [PATCH v2 085/117] nfsd: Protect session creation and client confirm " Jeff Layton
2014-06-26 19:20 ` [PATCH v2 086/117] nfsd: Protect nfsd4_destroy_clientid " Jeff Layton
2014-06-26 19:20 ` [PATCH v2 087/117] nfsd: Ensure lookup_clientid() takes client_lock Jeff Layton
2014-06-26 19:20 ` [PATCH v2 088/117] nfsd: Add lockdep assertions to document the nfs4_client/session locking Jeff Layton
2014-06-26 19:20 ` [PATCH v2 089/117] nfsd: protect the close_lru list and oo_last_closed_stid with client_lock Jeff Layton
2014-06-26 19:20 ` [PATCH v2 090/117] nfsd: ensure that clp->cl_revoked list is protected by clp->cl_lock Jeff Layton
2014-06-26 19:20 ` [PATCH v2 091/117] nfsd: move unhash_client_locked call into mark_client_expired_locked Jeff Layton
2014-06-26 19:21 ` [PATCH v2 092/117] nfsd: don't destroy client if mark_client_expired_locked fails Jeff Layton
2014-06-26 19:21 ` [PATCH v2 093/117] nfsd: don't destroy clients that are busy Jeff Layton
2014-06-26 19:21 ` [PATCH v2 094/117] nfsd: protect clid and verifier generation with client_lock Jeff Layton
2014-06-26 19:21 ` [PATCH v2 095/117] nfsd: abstract out the get and set routines into the fault injection ops Jeff Layton
2014-06-26 19:21 ` [PATCH v2 096/117] nfsd: add a forget_clients "get" routine with proper locking Jeff Layton
2014-06-26 19:21 ` [PATCH v2 097/117] nfsd: add a forget_client set_clnt routine Jeff Layton
2014-06-26 19:21 ` [PATCH v2 098/117] nfsd: add nfsd_inject_forget_clients Jeff Layton
2014-06-26 19:21 ` [PATCH v2 099/117] nfsd: add a list_head arg to nfsd_foreach_client_lock Jeff Layton
2014-06-26 19:21 ` [PATCH v2 100/117] nfsd: add more granular locking to forget_locks fault injector Jeff Layton
2014-06-26 19:21 ` [PATCH v2 101/117] nfsd: add more granular locking to forget_openowners " Jeff Layton
2014-06-26 19:21 ` [PATCH v2 102/117] nfsd: add more granular locking to *_delegations fault injectors Jeff Layton
2014-06-26 19:21 ` [PATCH v2 103/117] nfsd: remove old fault injection infrastructure Jeff Layton
2014-06-26 19:21 ` [PATCH v2 104/117] nfsd: Remove nfs4_lock_state(): nfs4_preprocess_stateid_op() Jeff Layton
2014-06-26 19:21 ` [PATCH v2 105/117] nfsd: Remove nfs4_lock_state(): nfsd4_test_stateid/nfsd4_free_stateid Jeff Layton
2014-06-26 19:21 ` [PATCH v2 106/117] nfsd: Remove nfs4_lock_state(): nfsd4_release_lockowner Jeff Layton
2014-06-26 19:21 ` [PATCH v2 107/117] nfsd: Remove nfs4_lock_state(): nfsd4_lock/locku/lockt() Jeff Layton
2014-06-26 19:21 ` [PATCH v2 108/117] nfsd: Remove nfs4_lock_state(): nfsd4_open_downgrade + nfsd4_close Jeff Layton
2014-06-26 19:21 ` [PATCH v2 109/117] nfsd: Remove nfs4_lock_state(): nfsd4_delegreturn() Jeff Layton
2014-06-26 19:21 ` [PATCH v2 110/117] nfsd: Remove nfs4_lock_state(): nfsd4_open and nfsd4_open_confirm Jeff Layton
2014-06-26 19:21 ` [PATCH v2 111/117] nfsd: Remove nfs4_lock_state(): exchange_id, create/destroy_session() Jeff Layton
2014-06-26 19:21 ` [PATCH v2 112/117] nfsd: Remove nfs4_lock_state(): setclientid, setclientid_confirm, renew Jeff Layton
2014-06-26 19:21 ` [PATCH v2 113/117] nfsd: Remove nfs4_lock_state(): reclaim_complete() Jeff Layton
2014-06-26 19:21 ` [PATCH v2 114/117] nfsd: remove nfs4_lock_state: nfs4_laundromat Jeff Layton
2014-06-26 19:21 ` [PATCH v2 115/117] nfsd: remove nfs4_lock_state: nfs4_state_shutdown_net Jeff Layton
2014-06-26 19:21 ` [PATCH v2 116/117] nfsd: remove the client_mutex and the nfs4_lock/unlock_state wrappers Jeff Layton
2014-06-26 19:21 ` [PATCH v2 117/117] nfsd: add file documenting new state object model Jeff Layton
2014-06-27 16:22 ` [PATCH v2 000/117] nfsd: eliminate the client_mutex J. Bruce Fields
2014-06-27 19:08   ` Jeff Layton
2014-06-30 12:51 ` Christoph Hellwig
2014-06-30 12:59   ` Jeff Layton
2014-06-30 19:32     ` J. Bruce Fields
2014-06-30 19:39       ` Jeff Layton
2014-06-30 20:20       ` Jeff Layton
2014-06-30 20:31         ` Trond Myklebust
2014-06-30 20:36           ` Jeff Layton
2014-07-01 14:10             ` Jeff Layton
2014-07-01 14:21               ` Trond Myklebust
2014-07-01 18:46                 ` Jeff Layton
2014-07-01 20:01                   ` J. Bruce Fields
2014-07-01 20:13                     ` Jeff Layton
2014-07-01 20:24                       ` J. Bruce Fields

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140627155958.10a6420d@tlielax.poochiereds.net \
    --to=jeff.layton@primarydata.com \
    --cc=bfields@fieldses.org \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.