pnfs: allow LD to ask to resend read through pnfs
authorPeng Tao <tao.peng@primarydata.com>
Mon, 10 Nov 2014 00:35:38 +0000 (08:35 +0800)
committerTom Haynes <loghyr@primarydata.com>
Tue, 3 Feb 2015 19:06:48 +0000 (11:06 -0800)
If current IO cannot be completed due to some transient errors,
LD may want to ask generic layer to resend the request through
pnfs again.

Signed-off-by: Peng Tao <tao.peng@primarydata.com>
Signed-off-by: Tom Haynes <loghyr@primarydata.com>
fs/nfs/pnfs.c
fs/nfs/pnfs.h

index b822b1749643dcf485b5b2dd94eda17093e53676..685af4fb39cabd1f1d0c2f0187e0a495aab68844 100644 (file)
@@ -1880,15 +1880,28 @@ pnfs_try_to_read_data(struct nfs_pgio_header *hdr,
        return trypnfs;
 }
 
+/* Resend all requests through pnfs. */
+int pnfs_read_resend_pnfs(struct nfs_pgio_header *hdr)
+{
+       struct nfs_pageio_descriptor pgio;
+
+       nfs_pageio_init_read(&pgio, hdr->inode, false, hdr->completion_ops);
+       return nfs_pageio_resend(&pgio, hdr);
+}
+EXPORT_SYMBOL_GPL(pnfs_read_resend_pnfs);
+
 static void
 pnfs_do_read(struct nfs_pageio_descriptor *desc, struct nfs_pgio_header *hdr)
 {
        const struct rpc_call_ops *call_ops = desc->pg_rpc_callops;
        struct pnfs_layout_segment *lseg = desc->pg_lseg;
        enum pnfs_try_status trypnfs;
+       int err = 0;
 
        trypnfs = pnfs_try_to_read_data(hdr, call_ops, lseg);
-       if (trypnfs == PNFS_NOT_ATTEMPTED)
+       if (trypnfs == PNFS_TRY_AGAIN)
+               err = pnfs_read_resend_pnfs(hdr);
+       if (trypnfs == PNFS_NOT_ATTEMPTED || err)
                pnfs_read_through_mds(desc, hdr);
 }
 
index a0ab81cc9cf3724441fa431e4e0f21ba0a05b167..84c25cd476f85d8bfc905bd139fb89ebe4a19a69 100644 (file)
@@ -72,6 +72,7 @@ struct pnfs_layout_segment {
 enum pnfs_try_status {
        PNFS_ATTEMPTED     = 0,
        PNFS_NOT_ATTEMPTED = 1,
+       PNFS_TRY_AGAIN     = 2,
 };
 
 #ifdef CONFIG_NFS_V4_1
@@ -268,6 +269,7 @@ int _pnfs_return_layout(struct inode *);
 int pnfs_commit_and_return_layout(struct inode *);
 void pnfs_ld_write_done(struct nfs_pgio_header *);
 void pnfs_ld_read_done(struct nfs_pgio_header *);
+int pnfs_read_resend_pnfs(struct nfs_pgio_header *);
 struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
                                               struct nfs_open_context *ctx,
                                               loff_t pos,