aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@hammerspace.com>2018-06-07 14:31:25 -0400
committerTrond Myklebust <trond.myklebust@hammerspace.com>2018-06-08 16:36:10 -0400
commitce5624f7e6675ae0425f0041bbad703ea41c784c (patch)
tree254a950e0cfce4255ddc7bf502e9c5e2aebe6d90
parent6c342655022d5189c45e4f7ed0cc8048c9ad9815 (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.c26
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
131restart:
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
169restart:
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
195static struct inode *nfs_layout_find_inode(struct nfs_client *clp, 193static 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);
305out: 306out:
307 nfs_iput_and_deactive(ino);
308out_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