diff options
author | Trond Myklebust <trondmy@gmail.com> | 2018-09-05 14:07:12 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2018-09-14 16:24:08 -0400 |
commit | d03360aaf5ccac49581960bd736258c62972b88b (patch) | |
tree | b997c8e159d9f979a5e24e950c5e7afd9476849b | |
parent | 2a534a7473bf4e7f1c12805113f80c795fc8e89a (diff) |
pNFS: Ensure we return the error if someone kills a waiting layoutget
If someone interrupts a wait on one or more outstanding layoutgets in
pnfs_update_layout() then return the ERESTARTSYS/EINTR error.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r-- | fs/nfs/pnfs.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index e8f232de484f..7d9a51e6b847 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -1740,16 +1740,16 @@ static bool pnfs_within_mdsthreshold(struct nfs_open_context *ctx, | |||
1740 | return ret; | 1740 | return ret; |
1741 | } | 1741 | } |
1742 | 1742 | ||
1743 | static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo) | 1743 | static int pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo) |
1744 | { | 1744 | { |
1745 | /* | 1745 | /* |
1746 | * send layoutcommit as it can hold up layoutreturn due to lseg | 1746 | * send layoutcommit as it can hold up layoutreturn due to lseg |
1747 | * reference | 1747 | * reference |
1748 | */ | 1748 | */ |
1749 | pnfs_layoutcommit_inode(lo->plh_inode, false); | 1749 | pnfs_layoutcommit_inode(lo->plh_inode, false); |
1750 | return !wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN, | 1750 | return wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN, |
1751 | nfs_wait_bit_killable, | 1751 | nfs_wait_bit_killable, |
1752 | TASK_UNINTERRUPTIBLE); | 1752 | TASK_KILLABLE); |
1753 | } | 1753 | } |
1754 | 1754 | ||
1755 | static void nfs_layoutget_begin(struct pnfs_layout_hdr *lo) | 1755 | static void nfs_layoutget_begin(struct pnfs_layout_hdr *lo) |
@@ -1830,7 +1830,9 @@ pnfs_update_layout(struct inode *ino, | |||
1830 | } | 1830 | } |
1831 | 1831 | ||
1832 | lookup_again: | 1832 | lookup_again: |
1833 | nfs4_client_recover_expired_lease(clp); | 1833 | lseg = ERR_PTR(nfs4_client_recover_expired_lease(clp)); |
1834 | if (IS_ERR(lseg)) | ||
1835 | goto out; | ||
1834 | first = false; | 1836 | first = false; |
1835 | spin_lock(&ino->i_lock); | 1837 | spin_lock(&ino->i_lock); |
1836 | lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags); | 1838 | lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags); |
@@ -1863,9 +1865,9 @@ lookup_again: | |||
1863 | if (list_empty(&lo->plh_segs) && | 1865 | if (list_empty(&lo->plh_segs) && |
1864 | atomic_read(&lo->plh_outstanding) != 0) { | 1866 | atomic_read(&lo->plh_outstanding) != 0) { |
1865 | spin_unlock(&ino->i_lock); | 1867 | spin_unlock(&ino->i_lock); |
1866 | if (wait_var_event_killable(&lo->plh_outstanding, | 1868 | lseg = ERR_PTR(wait_var_event_killable(&lo->plh_outstanding, |
1867 | atomic_read(&lo->plh_outstanding) == 0 | 1869 | atomic_read(&lo->plh_outstanding))); |
1868 | || !list_empty(&lo->plh_segs))) | 1870 | if (IS_ERR(lseg) || !list_empty(&lo->plh_segs)) |
1869 | goto out_put_layout_hdr; | 1871 | goto out_put_layout_hdr; |
1870 | pnfs_put_layout_hdr(lo); | 1872 | pnfs_put_layout_hdr(lo); |
1871 | goto lookup_again; | 1873 | goto lookup_again; |
@@ -1898,8 +1900,11 @@ lookup_again: | |||
1898 | if (test_and_set_bit(NFS_LAYOUT_FIRST_LAYOUTGET, | 1900 | if (test_and_set_bit(NFS_LAYOUT_FIRST_LAYOUTGET, |
1899 | &lo->plh_flags)) { | 1901 | &lo->plh_flags)) { |
1900 | spin_unlock(&ino->i_lock); | 1902 | spin_unlock(&ino->i_lock); |
1901 | wait_on_bit(&lo->plh_flags, NFS_LAYOUT_FIRST_LAYOUTGET, | 1903 | lseg = ERR_PTR(wait_on_bit(&lo->plh_flags, |
1902 | TASK_UNINTERRUPTIBLE); | 1904 | NFS_LAYOUT_FIRST_LAYOUTGET, |
1905 | TASK_KILLABLE)); | ||
1906 | if (IS_ERR(lseg)) | ||
1907 | goto out_put_layout_hdr; | ||
1903 | pnfs_put_layout_hdr(lo); | 1908 | pnfs_put_layout_hdr(lo); |
1904 | dprintk("%s retrying\n", __func__); | 1909 | dprintk("%s retrying\n", __func__); |
1905 | goto lookup_again; | 1910 | goto lookup_again; |
@@ -1925,7 +1930,8 @@ lookup_again: | |||
1925 | if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) { | 1930 | if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) { |
1926 | spin_unlock(&ino->i_lock); | 1931 | spin_unlock(&ino->i_lock); |
1927 | dprintk("%s wait for layoutreturn\n", __func__); | 1932 | dprintk("%s wait for layoutreturn\n", __func__); |
1928 | if (pnfs_prepare_to_retry_layoutget(lo)) { | 1933 | lseg = ERR_PTR(pnfs_prepare_to_retry_layoutget(lo)); |
1934 | if (!IS_ERR(lseg)) { | ||
1929 | if (first) | 1935 | if (first) |
1930 | pnfs_clear_first_layoutget(lo); | 1936 | pnfs_clear_first_layoutget(lo); |
1931 | pnfs_put_layout_hdr(lo); | 1937 | pnfs_put_layout_hdr(lo); |