Commit 5e138c4a authored by Chuck Lever's avatar Chuck Lever
Browse files

NFSD: NFSv4 CLOSE should release an nfsd_file immediately



The last close of a file should enable other accessors to open and
use that file immediately. Leaving the file open in the filecache
prevents other users from accessing that file until the filecache
garbage-collects the file -- sometimes that takes several seconds.

Reported-by: default avatarWang Yugui <wangyugui@e16-tech.com>
Link: https://bugzilla.linux-nfs.org/show_bug.cgi?387


Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent b40a2839
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -452,6 +452,24 @@ nfsd_file_put(struct nfsd_file *nf)
		nfsd_file_put_noref(nf);
}

/**
 * nfsd_file_close - Close an nfsd_file
 * @nf: nfsd_file to close
 *
 * If this is the final reference for @nf, free it immediately.
 * This reflects an on-the-wire CLOSE or DELEGRETURN into the
 * VFS and exported filesystem.
 */
void nfsd_file_close(struct nfsd_file *nf)
{
	nfsd_file_put(nf);
	if (refcount_dec_if_one(&nf->nf_ref)) {
		nfsd_file_unhash(nf);
		nfsd_file_lru_remove(nf);
		nfsd_file_free(nf);
	}
}

struct nfsd_file *
nfsd_file_get(struct nfsd_file *nf)
{
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ void nfsd_file_cache_shutdown(void);
int nfsd_file_cache_start_net(struct net *net);
void nfsd_file_cache_shutdown_net(struct net *net);
void nfsd_file_put(struct nfsd_file *nf);
void nfsd_file_close(struct nfsd_file *nf);
struct nfsd_file *nfsd_file_get(struct nfsd_file *nf);
void nfsd_file_close_inode_sync(struct inode *inode);
bool nfsd_file_is_cached(struct inode *inode);
+2 −2
Original line number Diff line number Diff line
@@ -820,9 +820,9 @@ static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag)
			swap(f2, fp->fi_fds[O_RDWR]);
		spin_unlock(&fp->fi_lock);
		if (f1)
			nfsd_file_put(f1);
			nfsd_file_close(f1);
		if (f2)
			nfsd_file_put(f2);
			nfsd_file_close(f2);
	}
}