diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-03-25 20:10:20 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-03-27 12:39:35 -0400 |
commit | 29559b11aef072f893cd32280dcec9d7380ca011 (patch) | |
tree | ad46d8aeb9c4154208f7a565aaeb1241d8ee6b8c /fs/nfs | |
parent | 415320fc14eca40b564d1797e68895d15b51ac49 (diff) |
NFSv4.1/pnfs: Fix setting of layoutcommit last write byte
If the NFS_INO_LAYOUTCOMMIT flag was unset, then we _must_ ensure that
we also reset the last write byte (lwb) for that layout. The current
code depends on us clearing the lwb when we clear NFS_INO_LAYOUTCOMMIT,
which is not the case when we call pnfs_clear_layoutcommit().
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/pnfs.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 4f802b02fbb9..b96736df98e8 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -2108,16 +2108,16 @@ pnfs_set_layoutcommit(struct nfs_pgio_header *hdr) | |||
2108 | 2108 | ||
2109 | spin_lock(&inode->i_lock); | 2109 | spin_lock(&inode->i_lock); |
2110 | if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { | 2110 | if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { |
2111 | nfsi->layout->plh_lwb = end_pos; | ||
2111 | mark_as_dirty = true; | 2112 | mark_as_dirty = true; |
2112 | dprintk("%s: Set layoutcommit for inode %lu ", | 2113 | dprintk("%s: Set layoutcommit for inode %lu ", |
2113 | __func__, inode->i_ino); | 2114 | __func__, inode->i_ino); |
2114 | } | 2115 | } else if (end_pos > nfsi->layout->plh_lwb) |
2116 | nfsi->layout->plh_lwb = end_pos; | ||
2115 | if (!test_and_set_bit(NFS_LSEG_LAYOUTCOMMIT, &hdr->lseg->pls_flags)) { | 2117 | if (!test_and_set_bit(NFS_LSEG_LAYOUTCOMMIT, &hdr->lseg->pls_flags)) { |
2116 | /* references matched in nfs4_layoutcommit_release */ | 2118 | /* references matched in nfs4_layoutcommit_release */ |
2117 | pnfs_get_lseg(hdr->lseg); | 2119 | pnfs_get_lseg(hdr->lseg); |
2118 | } | 2120 | } |
2119 | if (end_pos > nfsi->layout->plh_lwb) | ||
2120 | nfsi->layout->plh_lwb = end_pos; | ||
2121 | spin_unlock(&inode->i_lock); | 2121 | spin_unlock(&inode->i_lock); |
2122 | dprintk("%s: lseg %p end_pos %llu\n", | 2122 | dprintk("%s: lseg %p end_pos %llu\n", |
2123 | __func__, hdr->lseg, nfsi->layout->plh_lwb); | 2123 | __func__, hdr->lseg, nfsi->layout->plh_lwb); |
@@ -2137,16 +2137,16 @@ void pnfs_commit_set_layoutcommit(struct nfs_commit_data *data) | |||
2137 | 2137 | ||
2138 | spin_lock(&inode->i_lock); | 2138 | spin_lock(&inode->i_lock); |
2139 | if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { | 2139 | if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { |
2140 | nfsi->layout->plh_lwb = data->lwb; | ||
2140 | mark_as_dirty = true; | 2141 | mark_as_dirty = true; |
2141 | dprintk("%s: Set layoutcommit for inode %lu ", | 2142 | dprintk("%s: Set layoutcommit for inode %lu ", |
2142 | __func__, inode->i_ino); | 2143 | __func__, inode->i_ino); |
2143 | } | 2144 | } else if (data->lwb > nfsi->layout->plh_lwb) |
2145 | nfsi->layout->plh_lwb = data->lwb; | ||
2144 | if (!test_and_set_bit(NFS_LSEG_LAYOUTCOMMIT, &data->lseg->pls_flags)) { | 2146 | if (!test_and_set_bit(NFS_LSEG_LAYOUTCOMMIT, &data->lseg->pls_flags)) { |
2145 | /* references matched in nfs4_layoutcommit_release */ | 2147 | /* references matched in nfs4_layoutcommit_release */ |
2146 | pnfs_get_lseg(data->lseg); | 2148 | pnfs_get_lseg(data->lseg); |
2147 | } | 2149 | } |
2148 | if (data->lwb > nfsi->layout->plh_lwb) | ||
2149 | nfsi->layout->plh_lwb = data->lwb; | ||
2150 | spin_unlock(&inode->i_lock); | 2150 | spin_unlock(&inode->i_lock); |
2151 | dprintk("%s: lseg %p end_pos %llu\n", | 2151 | dprintk("%s: lseg %p end_pos %llu\n", |
2152 | __func__, data->lseg, nfsi->layout->plh_lwb); | 2152 | __func__, data->lseg, nfsi->layout->plh_lwb); |
@@ -2216,7 +2216,6 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync) | |||
2216 | pnfs_list_write_lseg(inode, &data->lseg_list); | 2216 | pnfs_list_write_lseg(inode, &data->lseg_list); |
2217 | 2217 | ||
2218 | end_pos = nfsi->layout->plh_lwb; | 2218 | end_pos = nfsi->layout->plh_lwb; |
2219 | nfsi->layout->plh_lwb = 0; | ||
2220 | 2219 | ||
2221 | nfs4_stateid_copy(&data->args.stateid, &nfsi->layout->plh_stateid); | 2220 | nfs4_stateid_copy(&data->args.stateid, &nfsi->layout->plh_stateid); |
2222 | spin_unlock(&inode->i_lock); | 2221 | spin_unlock(&inode->i_lock); |
@@ -2233,11 +2232,11 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync) | |||
2233 | status = ld->prepare_layoutcommit(&data->args); | 2232 | status = ld->prepare_layoutcommit(&data->args); |
2234 | if (status) { | 2233 | if (status) { |
2235 | spin_lock(&inode->i_lock); | 2234 | spin_lock(&inode->i_lock); |
2236 | if (end_pos < nfsi->layout->plh_lwb) | 2235 | set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags); |
2236 | if (end_pos > nfsi->layout->plh_lwb) | ||
2237 | nfsi->layout->plh_lwb = end_pos; | 2237 | nfsi->layout->plh_lwb = end_pos; |
2238 | spin_unlock(&inode->i_lock); | 2238 | spin_unlock(&inode->i_lock); |
2239 | put_rpccred(data->cred); | 2239 | put_rpccred(data->cred); |
2240 | set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags); | ||
2241 | goto clear_layoutcommitting; | 2240 | goto clear_layoutcommitting; |
2242 | } | 2241 | } |
2243 | } | 2242 | } |