diff options
author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2018-06-07 14:31:25 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2018-06-08 16:36:10 -0400 |
commit | ce5624f7e6675ae0425f0041bbad703ea41c784c (patch) | |
tree | 254a950e0cfce4255ddc7bf502e9c5e2aebe6d90 | |
parent | 6c342655022d5189c45e4f7ed0cc8048c9ad9815 (diff) |
NFSv4: Return NFS4ERR_DELAY when a layout recall fails due to igrab()
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
-rw-r--r-- | fs/nfs/callback_proc.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index eacd09dcdad1..3a49bb19ef07 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -128,7 +128,6 @@ static struct inode *nfs_layout_find_inode_by_stateid(struct nfs_client *clp, | |||
128 | struct inode *inode; | 128 | struct inode *inode; |
129 | struct pnfs_layout_hdr *lo; | 129 | struct pnfs_layout_hdr *lo; |
130 | 130 | ||
131 | restart: | ||
132 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { | 131 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { |
133 | list_for_each_entry(lo, &server->layouts, plh_layouts) { | 132 | list_for_each_entry(lo, &server->layouts, plh_layouts) { |
134 | if (stateid != NULL && | 133 | if (stateid != NULL && |
@@ -136,20 +135,20 @@ restart: | |||
136 | continue; | 135 | continue; |
137 | inode = igrab(lo->plh_inode); | 136 | inode = igrab(lo->plh_inode); |
138 | if (!inode) | 137 | if (!inode) |
139 | continue; | 138 | return ERR_PTR(-EAGAIN); |
140 | if (!nfs_sb_active(inode->i_sb)) { | 139 | if (!nfs_sb_active(inode->i_sb)) { |
141 | rcu_read_unlock(); | 140 | rcu_read_unlock(); |
142 | spin_unlock(&clp->cl_lock); | 141 | spin_unlock(&clp->cl_lock); |
143 | iput(inode); | 142 | iput(inode); |
144 | spin_lock(&clp->cl_lock); | 143 | spin_lock(&clp->cl_lock); |
145 | rcu_read_lock(); | 144 | rcu_read_lock(); |
146 | goto restart; | 145 | return ERR_PTR(-EAGAIN); |
147 | } | 146 | } |
148 | return inode; | 147 | return inode; |
149 | } | 148 | } |
150 | } | 149 | } |
151 | 150 | ||
152 | return NULL; | 151 | return ERR_PTR(-ENOENT); |
153 | } | 152 | } |
154 | 153 | ||
155 | /* | 154 | /* |
@@ -166,7 +165,6 @@ static struct inode *nfs_layout_find_inode_by_fh(struct nfs_client *clp, | |||
166 | struct inode *inode; | 165 | struct inode *inode; |
167 | struct pnfs_layout_hdr *lo; | 166 | struct pnfs_layout_hdr *lo; |
168 | 167 | ||
169 | restart: | ||
170 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { | 168 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { |
171 | list_for_each_entry(lo, &server->layouts, plh_layouts) { | 169 | list_for_each_entry(lo, &server->layouts, plh_layouts) { |
172 | nfsi = NFS_I(lo->plh_inode); | 170 | nfsi = NFS_I(lo->plh_inode); |
@@ -176,20 +174,20 @@ restart: | |||
176 | continue; | 174 | continue; |
177 | inode = igrab(lo->plh_inode); | 175 | inode = igrab(lo->plh_inode); |
178 | if (!inode) | 176 | if (!inode) |
179 | continue; | 177 | return ERR_PTR(-EAGAIN); |
180 | if (!nfs_sb_active(inode->i_sb)) { | 178 | if (!nfs_sb_active(inode->i_sb)) { |
181 | rcu_read_unlock(); | 179 | rcu_read_unlock(); |
182 | spin_unlock(&clp->cl_lock); | 180 | spin_unlock(&clp->cl_lock); |
183 | iput(inode); | 181 | iput(inode); |
184 | spin_lock(&clp->cl_lock); | 182 | spin_lock(&clp->cl_lock); |
185 | rcu_read_lock(); | 183 | rcu_read_lock(); |
186 | goto restart; | 184 | return ERR_PTR(-EAGAIN); |
187 | } | 185 | } |
188 | return inode; | 186 | return inode; |
189 | } | 187 | } |
190 | } | 188 | } |
191 | 189 | ||
192 | return NULL; | 190 | return ERR_PTR(-ENOENT); |
193 | } | 191 | } |
194 | 192 | ||
195 | static struct inode *nfs_layout_find_inode(struct nfs_client *clp, | 193 | static struct inode *nfs_layout_find_inode(struct nfs_client *clp, |
@@ -201,7 +199,7 @@ static struct inode *nfs_layout_find_inode(struct nfs_client *clp, | |||
201 | spin_lock(&clp->cl_lock); | 199 | spin_lock(&clp->cl_lock); |
202 | rcu_read_lock(); | 200 | rcu_read_lock(); |
203 | inode = nfs_layout_find_inode_by_stateid(clp, stateid); | 201 | inode = nfs_layout_find_inode_by_stateid(clp, stateid); |
204 | if (!inode) | 202 | if (inode == ERR_PTR(-ENOENT)) |
205 | inode = nfs_layout_find_inode_by_fh(clp, fh); | 203 | inode = nfs_layout_find_inode_by_fh(clp, fh); |
206 | rcu_read_unlock(); | 204 | rcu_read_unlock(); |
207 | spin_unlock(&clp->cl_lock); | 205 | spin_unlock(&clp->cl_lock); |
@@ -256,8 +254,11 @@ static u32 initiate_file_draining(struct nfs_client *clp, | |||
256 | LIST_HEAD(free_me_list); | 254 | LIST_HEAD(free_me_list); |
257 | 255 | ||
258 | ino = nfs_layout_find_inode(clp, &args->cbl_fh, &args->cbl_stateid); | 256 | ino = nfs_layout_find_inode(clp, &args->cbl_fh, &args->cbl_stateid); |
259 | if (!ino) | 257 | if (IS_ERR(ino)) { |
260 | goto out; | 258 | if (ino == ERR_PTR(-EAGAIN)) |
259 | rv = NFS4ERR_DELAY; | ||
260 | goto out_noput; | ||
261 | } | ||
261 | 262 | ||
262 | pnfs_layoutcommit_inode(ino, false); | 263 | pnfs_layoutcommit_inode(ino, false); |
263 | 264 | ||
@@ -303,9 +304,10 @@ unlock: | |||
303 | nfs_commit_inode(ino, 0); | 304 | nfs_commit_inode(ino, 0); |
304 | pnfs_put_layout_hdr(lo); | 305 | pnfs_put_layout_hdr(lo); |
305 | out: | 306 | out: |
307 | nfs_iput_and_deactive(ino); | ||
308 | out_noput: | ||
306 | trace_nfs4_cb_layoutrecall_file(clp, &args->cbl_fh, ino, | 309 | trace_nfs4_cb_layoutrecall_file(clp, &args->cbl_fh, ino, |
307 | &args->cbl_stateid, -rv); | 310 | &args->cbl_stateid, -rv); |
308 | nfs_iput_and_deactive(ino); | ||
309 | return rv; | 311 | return rv; |
310 | } | 312 | } |
311 | 313 | ||