Skip to content

Commit dce7292

Browse files
Trond Myklebustamschuma-ntap
authored andcommitted
NFSv4.1: if referring calls are complete, trust the stateid argument
If the server is recalling a layout, and sends us a list of referring calls that we can see are complete, then we should just trust that the stateid argument is correct, even if the sequence id doesn't match the one we hold. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent e3fd54e commit dce7292

1 file changed

Lines changed: 24 additions & 20 deletions

File tree

fs/nfs/callback_proc.c

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,8 @@ static struct inode *nfs_layout_find_inode(struct nfs_client *clp,
207207
* Enforce RFC5661 section 12.5.5.2.1. (Layout Recall and Return Sequencing)
208208
*/
209209
static u32 pnfs_check_callback_stateid(struct pnfs_layout_hdr *lo,
210-
const nfs4_stateid *new)
210+
const nfs4_stateid *new,
211+
struct cb_process_state *cps)
211212
{
212213
u32 oldseq, newseq;
213214

@@ -221,28 +222,29 @@ static u32 pnfs_check_callback_stateid(struct pnfs_layout_hdr *lo,
221222

222223
newseq = be32_to_cpu(new->seqid);
223224
/* Are we already in a layout recall situation? */
224-
if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags) &&
225-
lo->plh_return_seq != 0) {
226-
if (newseq < lo->plh_return_seq)
227-
return NFS4ERR_OLD_STATEID;
228-
if (newseq > lo->plh_return_seq)
229-
return NFS4ERR_DELAY;
230-
goto out;
231-
}
225+
if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
226+
return NFS4ERR_DELAY;
232227

233-
/* Check that the stateid matches what we think it should be. */
228+
/*
229+
* Check that the stateid matches what we think it should be.
230+
* Note that if the server sent us a list of referring calls,
231+
* and we know that those have completed, then we trust the
232+
* stateid argument is correct.
233+
*/
234234
oldseq = be32_to_cpu(lo->plh_stateid.seqid);
235-
if (newseq > oldseq + 1)
235+
if (newseq > oldseq + 1 && !cps->referring_calls)
236236
return NFS4ERR_DELAY;
237+
237238
/* Crazy server! */
238239
if (newseq <= oldseq)
239240
return NFS4ERR_OLD_STATEID;
240-
out:
241+
241242
return NFS_OK;
242243
}
243244

244245
static u32 initiate_file_draining(struct nfs_client *clp,
245-
struct cb_layoutrecallargs *args)
246+
struct cb_layoutrecallargs *args,
247+
struct cb_process_state *cps)
246248
{
247249
struct inode *ino;
248250
struct pnfs_layout_hdr *lo;
@@ -266,7 +268,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
266268
goto out;
267269
}
268270
pnfs_get_layout_hdr(lo);
269-
rv = pnfs_check_callback_stateid(lo, &args->cbl_stateid);
271+
rv = pnfs_check_callback_stateid(lo, &args->cbl_stateid, cps);
270272
if (rv != NFS_OK)
271273
goto unlock;
272274

@@ -326,10 +328,11 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
326328
}
327329

328330
static u32 do_callback_layoutrecall(struct nfs_client *clp,
329-
struct cb_layoutrecallargs *args)
331+
struct cb_layoutrecallargs *args,
332+
struct cb_process_state *cps)
330333
{
331334
if (args->cbl_recall_type == RETURN_FILE)
332-
return initiate_file_draining(clp, args);
335+
return initiate_file_draining(clp, args, cps);
333336
return initiate_bulk_draining(clp, args);
334337
}
335338

@@ -340,19 +343,20 @@ __be32 nfs4_callback_layoutrecall(void *argp, void *resp,
340343
u32 res = NFS4ERR_OP_NOT_IN_SESSION;
341344

342345
if (cps->clp)
343-
res = do_callback_layoutrecall(cps->clp, args);
346+
res = do_callback_layoutrecall(cps->clp, args, cps);
344347
return cpu_to_be32(res);
345348
}
346349

347-
static void pnfs_recall_all_layouts(struct nfs_client *clp)
350+
static void pnfs_recall_all_layouts(struct nfs_client *clp,
351+
struct cb_process_state *cps)
348352
{
349353
struct cb_layoutrecallargs args;
350354

351355
/* Pretend we got a CB_LAYOUTRECALL(ALL) */
352356
memset(&args, 0, sizeof(args));
353357
args.cbl_recall_type = RETURN_ALL;
354358
/* FIXME we ignore errors, what should we do? */
355-
do_callback_layoutrecall(clp, &args);
359+
do_callback_layoutrecall(clp, &args, cps);
356360
}
357361

358362
__be32 nfs4_callback_devicenotify(void *argp, void *resp,
@@ -622,7 +626,7 @@ __be32 nfs4_callback_recallany(void *argp, void *resp,
622626
nfs_expire_unused_delegation_types(cps->clp, flags);
623627

624628
if (args->craa_type_mask & BIT(RCA4_TYPE_MASK_FILE_LAYOUT))
625-
pnfs_recall_all_layouts(cps->clp);
629+
pnfs_recall_all_layouts(cps->clp, cps);
626630

627631
if (args->craa_type_mask & BIT(PNFS_FF_RCA4_TYPE_MASK_READ)) {
628632
set_bit(NFS4CLNT_RECALL_ANY_LAYOUT_READ, &cps->clp->cl_state);

0 commit comments

Comments
 (0)