All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@poochiereds.net>
To: bfields@fieldses.org
Cc: linux-nfs@vger.kernel.org, hch@lst.de, kinglongmee@gmail.com
Subject: [PATCH v3 10/20] nfsd: handle NFSD_MAY_NOT_BREAK_LEASE in open file cache
Date: Thu, 20 Aug 2015 07:17:10 -0400	[thread overview]
Message-ID: <1440069440-27454-11-git-send-email-jeff.layton@primarydata.com> (raw)
In-Reply-To: <1440069440-27454-1-git-send-email-jeff.layton@primarydata.com>

The NFSD_MAY_NOT_BREAK_LEASE flag needs special handling. If we open a
file in order to do (e.g.) a COMMIT then we don't want to break any
leases, but subsequent READ/WRITE operations must break the leases.

If we construct a new cache entry with a set of may flags that have
NFSD_MAY_NOT_BREAK_LEASE set, then set flags in the cache entry that
indicate that subsequent users of this file must break leases before
using it if they do not have NFSD_MAY_NOT_BREAK_LEASE set.

Note that because NFSD_MAY_READ opens do not break read leases, we
must track what sort of lease breaks have been done. If we're breaking
leases for read, then we still need to do a lease break for write if
it's a R/W open and a writer comes along. Lease breaks for write
however imply a read lease break so we can clear both flags in that
event.

Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
---
 fs/nfsd/filecache.c | 39 +++++++++++++++++++++++++++++++++++----
 fs/nfsd/filecache.h |  2 ++
 fs/nfsd/vfs.c       |  3 ++-
 fs/nfsd/vfs.h       |  1 +
 4 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
index 77041967d8ff..10aa698b6057 100644
--- a/fs/nfsd/filecache.c
+++ b/fs/nfsd/filecache.c
@@ -47,6 +47,12 @@ nfsd_file_alloc(struct inode *inode, unsigned int may, unsigned int hashval)
 		nf->nf_hashval = hashval;
 		atomic_set(&nf->nf_ref, 1);
 		nf->nf_may = NFSD_FILE_MAY_MASK & may;
+		if (may & NFSD_MAY_NOT_BREAK_LEASE) {
+			if (may & NFSD_MAY_WRITE)
+				__set_bit(NFSD_FILE_BREAK_WRITE, &nf->nf_flags);
+			if (may & NFSD_MAY_READ)
+				__set_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags);
+		}
 	}
 	return nf;
 }
@@ -286,9 +292,6 @@ nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
 	if (status != nfs_ok)
 		return status;
 
-	/* Mask off any extraneous bits */
-	may_flags &= NFSD_FILE_MAY_MASK;
-
 	inode = d_inode(fhp->fh_dentry);
 	hashval = (unsigned int)hash_ptr(inode, NFSD_FILE_HASH_BITS);
 retry:
@@ -331,7 +334,7 @@ wait_for_construction:
 		 * MAY flags are equal. Otherwise, we put the reference and try
 		 * again.
 		 */
-		if (may_flags != nf->nf_may) {
+		if ((may_flags & NFSD_FILE_MAY_MASK) != nf->nf_may) {
 			nfsd_file_put(nf);
 			goto retry;
 		}
@@ -339,6 +342,18 @@ wait_for_construction:
 		/* try to take over construction for this file */
 		if (test_and_set_bit(NFSD_FILE_PENDING, &nf->nf_flags))
 			goto wait_for_construction;
+
+		/* sync up the BREAK_* flags with our may_flags */
+		if (may_flags & NFSD_MAY_NOT_BREAK_LEASE) {
+			if (may_flags & NFSD_MAY_WRITE)
+				set_bit(NFSD_FILE_BREAK_WRITE, &nf->nf_flags);
+			if (may_flags & NFSD_MAY_READ)
+				set_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags);
+		} else {
+			clear_bit(NFSD_FILE_BREAK_WRITE, &nf->nf_flags);
+			clear_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags);
+		}
+
 		goto open_file;
 	}
 
@@ -349,6 +364,22 @@ wait_for_construction:
 	 */
 	status = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry,
 					may_flags|NFSD_MAY_OWNER_OVERRIDE);
+
+	if (status == nfs_ok && !(may_flags & NFSD_MAY_NOT_BREAK_LEASE)) {
+		bool write = (may_flags & NFSD_MAY_WRITE);
+
+		if (test_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags) ||
+		    (test_bit(NFSD_FILE_BREAK_WRITE, &nf->nf_flags) && write)) {
+			status = nfserrno(nfsd_open_break_lease(
+					file_inode(nf->nf_file), may_flags));
+			if (status == nfs_ok) {
+				clear_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags);
+				if (write)
+					clear_bit(NFSD_FILE_BREAK_WRITE,
+						  &nf->nf_flags);
+			}
+		}
+	}
 out:
 	if (status == nfs_ok)
 		*pnf = nf;
diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h
index e7da463446dd..debd558ef786 100644
--- a/fs/nfsd/filecache.h
+++ b/fs/nfsd/filecache.h
@@ -13,6 +13,8 @@ struct nfsd_file {
 	struct file		*nf_file;
 #define NFSD_FILE_HASHED	(0)
 #define NFSD_FILE_PENDING	(1)
+#define NFSD_FILE_BREAK_READ	(2)
+#define NFSD_FILE_BREAK_WRITE	(3)
 	unsigned long		nf_flags;
 	struct inode		*nf_inode;
 	unsigned int		nf_hashval;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index eb64597f3bde..81600bd06fef 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -618,7 +618,8 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor
 }
 #endif /* CONFIG_NFSD_V3 */
 
-static int nfsd_open_break_lease(struct inode *inode, int access)
+int
+nfsd_open_break_lease(struct inode *inode, int access)
 {
 	unsigned int mode;
 
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 78b5527cba93..a3ec59830297 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -69,6 +69,7 @@ __be32		do_nfsd_create(struct svc_rqst *, struct svc_fh *,
 __be32		nfsd_commit(struct svc_rqst *, struct svc_fh *,
 				loff_t, unsigned long);
 #endif /* CONFIG_NFSD_V3 */
+int		nfsd_open_break_lease(struct inode *, int);
 __be32		nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t,
 				int, struct file **);
 struct raparms;
-- 
2.4.3


  parent reply	other threads:[~2015-08-20 11:17 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-20 11:17 [PATCH v3 00/20] nfsd: open file caching Jeff Layton
2015-08-20 11:17 ` [PATCH v3 01/20] nfsd: allow more than one laundry job to run at a time Jeff Layton
2015-08-20 11:17 ` [PATCH v3 02/20] nfsd: add a new struct file caching facility to nfsd Jeff Layton
2015-08-20 23:11   ` Peng Tao
2015-08-20 23:43     ` Jeff Layton
2015-08-20 11:17 ` [PATCH v3 03/20] list_lru: add list_lru_rotate Jeff Layton
2015-08-20 11:17   ` Jeff Layton
2015-08-21  9:36   ` Vladimir Davydov
2015-08-21  9:36     ` Vladimir Davydov
2015-08-20 11:17 ` [PATCH v3 04/20] nfsd: add a LRU list for nfsd_files Jeff Layton
2015-08-20 11:17 ` [PATCH v3 05/20] nfsd: add a shrinker to the nfsd_file cache Jeff Layton
2015-08-20 11:17 ` [PATCH v3 06/20] locks/nfsd: create a new notifier chain for lease attempts Jeff Layton
2015-08-26 19:49   ` J. Bruce Fields
2015-08-26 22:39     ` Jeff Layton
2015-08-20 11:17 ` [PATCH v3 07/20] nfsd: hook up nfsd_write to the new nfsd_file cache Jeff Layton
2015-08-26 19:53   ` J. Bruce Fields
2015-08-26 22:40     ` Jeff Layton
2015-08-20 11:17 ` [PATCH v3 08/20] nfsd: hook up nfsd_read to the " Jeff Layton
2015-08-20 11:17 ` [PATCH v3 09/20] sunrpc: add a new cache_detail operation for when a cache is flushed Jeff Layton
2015-08-20 11:17 ` Jeff Layton [this message]
2015-08-20 11:17 ` [PATCH v3 11/20] nfsd: hook nfsd_commit up to the nfsd_file cache Jeff Layton
2015-08-20 11:17 ` [PATCH v3 12/20] nfsd: move include of state.h from trace.c to trace.h Jeff Layton
2015-08-20 11:17 ` [PATCH v3 13/20] nfsd: add new tracepoints for nfsd_file cache Jeff Layton
2015-08-20 11:17 ` [PATCH v3 14/20] nfsd: close cached files prior to a REMOVE or RENAME that would replace target Jeff Layton
2015-08-26 20:00   ` J. Bruce Fields
2015-08-26 22:53     ` Jeff Layton
2015-08-27 13:38       ` J. Bruce Fields
2015-08-28 12:19         ` Jeff Layton
2015-08-28 17:58           ` J. Bruce Fields
2015-08-31 16:50             ` Jeff Layton
2015-08-20 11:17 ` [PATCH v3 15/20] nfsd: call flush_delayed_fput from nfsd_file_close_fh Jeff Layton
2015-08-21  1:01   ` Peng Tao
2015-08-21  2:18     ` Peng Tao
2015-08-21 11:21       ` Jeff Layton
2015-08-20 11:17 ` [PATCH v3 16/20] nfsd: convert nfs4_file->fi_fds array to use nfsd_files Jeff Layton
2015-08-20 11:17 ` [PATCH v3 17/20] nfsd: have nfsd_test_lock use the nfsd_file cache Jeff Layton
2015-08-20 11:17 ` [PATCH v3 18/20] nfsd: convert fi_deleg_file and ls_file fields to nfsd_file Jeff Layton
2015-08-20 11:17 ` [PATCH v3 19/20] nfsd: hook up nfs4_preprocess_stateid_op to the nfsd_file cache Jeff Layton
2015-08-21  1:28   ` Peng Tao
2015-08-21 11:23     ` Jeff Layton
2015-08-20 11:17 ` [PATCH v3 20/20] nfsd: rip out the raparms cache Jeff Layton

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=1440069440-27454-11-git-send-email-jeff.layton@primarydata.com \
    --to=jlayton@poochiereds.net \
    --cc=bfields@fieldses.org \
    --cc=hch@lst.de \
    --cc=kinglongmee@gmail.com \
    --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.