Skip to content

Commit e0963ce

Browse files
sbashirochucklever
authored andcommitted
NFSD: Allow layoutcommit during grace period
If the loca_reclaim field is set to TRUE, this indicates that the client is attempting to commit changes to a layout after the restart of the metadata server during the metadata server's recovery grace period. This type of request may be necessary when the client has uncommitted writes to provisionally allocated byte-ranges of a file that were sent to the storage devices before the restart of the metadata server. See RFC 8881, section 18.42.3. Without this, the client is not able to increase the file size and commit preallocated extents when the block/scsi layout server is restarted during a write and is in a grace period. And when the grace period ends, the client also cannot perform layoutcommit because the old layout state becomes invalid, resulting in file corruption. Co-developed-by: Konstantin Evtushenko <[email protected]> Signed-off-by: Konstantin Evtushenko <[email protected]> Signed-off-by: Sergey Bashirov <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent db155b7 commit e0963ce

File tree

1 file changed

+25
-13
lines changed

1 file changed

+25
-13
lines changed

fs/nfsd/nfs4proc.c

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2526,6 +2526,7 @@ static __be32
25262526
nfsd4_layoutcommit(struct svc_rqst *rqstp,
25272527
struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
25282528
{
2529+
struct net *net = SVC_NET(rqstp);
25292530
struct nfsd4_layoutcommit *lcp = &u->layoutcommit;
25302531
const struct nfsd4_layout_seg *seg = &lcp->lc_seg;
25312532
struct svc_fh *current_fh = &cstate->current_fh;
@@ -2561,23 +2562,34 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
25612562
}
25622563
}
25632564

2564-
nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lcp->lc_sid,
2565-
false, lcp->lc_layout_type,
2566-
&ls);
2567-
if (nfserr) {
2568-
trace_nfsd_layout_commit_lookup_fail(&lcp->lc_sid);
2569-
/* fixup error code as per RFC5661 */
2570-
if (nfserr == nfserr_bad_stateid)
2571-
nfserr = nfserr_badlayout;
2565+
nfserr = nfserr_grace;
2566+
if (locks_in_grace(net) && !lcp->lc_reclaim)
2567+
goto out;
2568+
nfserr = nfserr_no_grace;
2569+
if (!locks_in_grace(net) && lcp->lc_reclaim)
25722570
goto out;
2573-
}
25742571

2575-
/* LAYOUTCOMMIT does not require any serialization */
2576-
mutex_unlock(&ls->ls_mutex);
2572+
if (!lcp->lc_reclaim) {
2573+
nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate,
2574+
&lcp->lc_sid, false, lcp->lc_layout_type, &ls);
2575+
if (nfserr) {
2576+
trace_nfsd_layout_commit_lookup_fail(&lcp->lc_sid);
2577+
/* fixup error code as per RFC5661 */
2578+
if (nfserr == nfserr_bad_stateid)
2579+
nfserr = nfserr_badlayout;
2580+
goto out;
2581+
}
2582+
2583+
/* LAYOUTCOMMIT does not require any serialization */
2584+
mutex_unlock(&ls->ls_mutex);
2585+
}
25772586

25782587
nfserr = ops->proc_layoutcommit(inode, rqstp, lcp);
2579-
nfsd4_file_mark_deleg_written(ls->ls_stid.sc_file);
2580-
nfs4_put_stid(&ls->ls_stid);
2588+
2589+
if (!lcp->lc_reclaim) {
2590+
nfsd4_file_mark_deleg_written(ls->ls_stid.sc_file);
2591+
nfs4_put_stid(&ls->ls_stid);
2592+
}
25812593
out:
25822594
return nfserr;
25832595
}

0 commit comments

Comments
 (0)