Commit c829013d authored by Peng Tao's avatar Peng Tao Committed by Tom Haynes

nfs41: add NFS_LAYOUT_RETRY_LAYOUTGET to layout header flags

Use it to indicate that LD wants to retry layoutget. LD can set
it whenever it wants the common pnfs code to return and retry
pnfs path through a new layout.

The bit gets cleared when client does a new layoutget, when client
closes the file (ROC case), or when kernel needs to evict the inode
(non-ROC case).
Signed-off-by: default avatarPeng Tao <tao.peng@primarydata.com>
parent 27b6f539
...@@ -615,6 +615,7 @@ pnfs_destroy_layout(struct nfs_inode *nfsi) ...@@ -615,6 +615,7 @@ pnfs_destroy_layout(struct nfs_inode *nfsi)
pnfs_get_layout_hdr(lo); pnfs_get_layout_hdr(lo);
pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED); pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED);
pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED); pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED);
pnfs_clear_retry_layoutget(lo);
spin_unlock(&nfsi->vfs_inode.i_lock); spin_unlock(&nfsi->vfs_inode.i_lock);
pnfs_free_lseg_list(&tmp_list); pnfs_free_lseg_list(&tmp_list);
pnfs_put_layout_hdr(lo); pnfs_put_layout_hdr(lo);
...@@ -1066,6 +1067,7 @@ bool pnfs_roc(struct inode *ino) ...@@ -1066,6 +1067,7 @@ bool pnfs_roc(struct inode *ino)
if (!lo || !test_and_clear_bit(NFS_LAYOUT_ROC, &lo->plh_flags) || if (!lo || !test_and_clear_bit(NFS_LAYOUT_ROC, &lo->plh_flags) ||
test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags)) test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags))
goto out_nolayout; goto out_nolayout;
pnfs_clear_retry_layoutget(lo);
list_for_each_entry_safe(lseg, tmp, &lo->plh_segs, pls_list) list_for_each_entry_safe(lseg, tmp, &lo->plh_segs, pls_list)
if (test_bit(NFS_LSEG_ROC, &lseg->pls_flags)) { if (test_bit(NFS_LSEG_ROC, &lseg->pls_flags)) {
mark_lseg_invalid(lseg, &tmp_list); mark_lseg_invalid(lseg, &tmp_list);
...@@ -1491,6 +1493,7 @@ pnfs_update_layout(struct inode *ino, ...@@ -1491,6 +1493,7 @@ pnfs_update_layout(struct inode *ino,
arg.length = PAGE_CACHE_ALIGN(arg.length); arg.length = PAGE_CACHE_ALIGN(arg.length);
lseg = send_layoutget(lo, ctx, &arg, gfp_flags); lseg = send_layoutget(lo, ctx, &arg, gfp_flags);
pnfs_clear_retry_layoutget(lo);
atomic_dec(&lo->plh_outstanding); atomic_dec(&lo->plh_outstanding);
out_put_layout_hdr: out_put_layout_hdr:
if (first) { if (first) {
......
...@@ -99,6 +99,7 @@ enum { ...@@ -99,6 +99,7 @@ enum {
NFS_LAYOUT_RETURN_BEFORE_CLOSE, /* Return this layout before close */ NFS_LAYOUT_RETURN_BEFORE_CLOSE, /* Return this layout before close */
NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */ NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */
NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */ NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */
NFS_LAYOUT_RETRY_LAYOUTGET, /* Retry layoutget */
}; };
enum layoutdriver_policy_flags { enum layoutdriver_policy_flags {
...@@ -350,6 +351,23 @@ nfs4_get_deviceid(struct nfs4_deviceid_node *d) ...@@ -350,6 +351,23 @@ nfs4_get_deviceid(struct nfs4_deviceid_node *d)
return d; return d;
} }
static inline void pnfs_set_retry_layoutget(struct pnfs_layout_hdr *lo)
{
if (!test_and_set_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags))
atomic_inc(&lo->plh_refcount);
}
static inline void pnfs_clear_retry_layoutget(struct pnfs_layout_hdr *lo)
{
if (test_and_clear_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags))
atomic_dec(&lo->plh_refcount);
}
static inline bool pnfs_should_retry_layoutget(struct pnfs_layout_hdr *lo)
{
return test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags);
}
static inline struct pnfs_layout_segment * static inline struct pnfs_layout_segment *
pnfs_get_lseg(struct pnfs_layout_segment *lseg) pnfs_get_lseg(struct pnfs_layout_segment *lseg)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment