[PATCH 2/3] pnfs_post_submit: Restore "pnfs: pnfs_do_flush" part 2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Fred Isaman <iisaman@xxxxxxxxxxxxxx>

pnfs: pnfs_do_flush

Adds a hook into the "check if request needs flushed" routines.
This will be needed to allow driver the ability to prevent comingling
of layout driver handled requests and fallback nfs requests.

Signed-off-by: Fred Isaman <iisaman@xxxxxxxxxxxxxx>
[pnfs: prevent offset overflow in _pnfs_do_flush]
[pnfs: pnfs_has_layout take_ref parameter should be bool]
[pnfs: clean up put_unlock_current_layout's interface]
[pnfs: introduce lseg valid bit]
Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx>

Signed-off-by: Fred Isaman <iisaman@xxxxxxxxxx>
Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx>
Signed-off-by: Fred Isaman <iisaman@xxxxxxxxxx>
---
 fs/nfs/pnfs.c             |   14 ++++++++++++++
 fs/nfs/pnfs.h             |   24 ++++++++++++++++++++++++
 fs/nfs/write.c            |    4 ++--
 include/linux/nfs4_pnfs.h |    3 +++
 4 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 679171e..f60420c 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1693,6 +1693,20 @@ out:
 	return status;
 }
 
+/* Given an nfs request, determine if it should be flushed before proceeding.
+ * It should default to returning False, returning True only if there is a
+ * specific reason to flush.
+ */
+int _pnfs_do_flush(struct inode *inode, struct nfs_page *req)
+{
+	struct nfs_server *nfss = NFS_SERVER(inode);
+	int status = 0;
+
+	/* Note that lseg==NULL may be useful info for do_flush */
+	status = nfss->pnfs_curr_ld->ld_policy_ops->do_flush(req->wb_lseg, req);
+	return status;
+}
+
 enum pnfs_try_status
 _pnfs_try_to_write_data(struct nfs_write_data *data,
 			const struct rpc_call_ops *call_ops, int how)
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index df5668d..23cd4c3 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -75,6 +75,7 @@ int _pnfs_write_begin(struct inode *inode, struct page *page,
 		      loff_t pos, unsigned len,
 		      struct pnfs_layout_segment *lseg,
 		      struct pnfs_fsdata **fsdata);
+int _pnfs_do_flush(struct inode *inode, struct nfs_page *req);
 
 #define PNFS_EXISTS_LDIO_OP(srv, opname) ((srv)->pnfs_curr_ld &&	\
 				     (srv)->pnfs_curr_ld->ld_io_ops &&	\
@@ -181,6 +182,24 @@ static inline int pnfs_write_begin(struct file *filp, struct page *page,
 	return status;
 }
 
+/* req may not be locked, so we have to be prepared for req->wb_page being
+ * set to NULL at any time.
+ */
+static inline int pnfs_do_flush(struct nfs_page *req)
+{
+	struct page *page = req->wb_page;
+	struct inode *inode;
+
+	if (!page)
+		return 1;
+	inode = page->mapping->host;
+
+	if (PNFS_EXISTS_LDPOLICY_OP(NFS_SERVER(inode), do_flush))
+		return _pnfs_do_flush(inode, req);
+	else
+		return 0;
+}
+
 static inline void pnfs_write_end_cleanup(struct file *filp, void *fsdata)
 {
 	if (fsdata) {
@@ -291,6 +310,11 @@ pnfs_try_to_commit(struct nfs_write_data *data,
 	return PNFS_NOT_ATTEMPTED;
 }
 
+static inline int pnfs_do_flush(struct nfs_page *req)
+{
+	return 0;
+}
+
 static inline int pnfs_write_begin(struct file *filp, struct page *page,
 				   loff_t pos, unsigned len,
 				   struct pnfs_layout_segment *lseg,
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index e575f7a..bd1115f 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -603,7 +603,7 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode,
 		 * have flushed out requests having wrong owners.
 		 */
 		if (offset > rqend || end < req->wb_offset ||
-		    req->wb_lseg != lseg)
+		    req->wb_lseg != lseg || pnfs_do_flush(req))
 			goto out_flushme;
 
 		if (nfs_set_page_tag_locked(req))
@@ -710,7 +710,7 @@ int nfs_flush_incompatible(struct file *file, struct page *page,
 		if (req == NULL)
 			return 0;
 		do_flush = req->wb_page != page || req->wb_context != ctx ||
-			req->wb_lseg != lseg;
+			req->wb_lseg != lseg || pnfs_do_flush(req);
 		nfs_release_request(req);
 		if (!do_flush)
 			return 0;
diff --git a/include/linux/nfs4_pnfs.h b/include/linux/nfs4_pnfs.h
index 0880a2e..e2e6cd0 100644
--- a/include/linux/nfs4_pnfs.h
+++ b/include/linux/nfs4_pnfs.h
@@ -199,6 +199,9 @@ struct layoutdriver_policy_operations {
 	/* test for nfs page cache coalescing */
 	int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *);
 
+	/* Test for pre-write request flushing */
+	int (*do_flush)(struct pnfs_layout_segment *lseg, struct nfs_page *req);
+
 	/* Retreive the block size of the file system.
 	 * If gather_across_stripes == 1, then the file system will gather
 	 * requests into the block size.
-- 
1.6.6.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux