mirror of
https://github.com/torvalds/linux.git
synced 2026-03-14 02:06:15 +01:00
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 <koevtushenko@yandex.com> Signed-off-by: Konstantin Evtushenko <koevtushenko@yandex.com> Signed-off-by: Sergey Bashirov <sergeybashirov@gmail.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
db155b7c7c
commit
e0963ce53b
1 changed files with 25 additions and 13 deletions
|
|
@ -2526,6 +2526,7 @@ static __be32
|
|||
nfsd4_layoutcommit(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
|
||||
{
|
||||
struct net *net = SVC_NET(rqstp);
|
||||
struct nfsd4_layoutcommit *lcp = &u->layoutcommit;
|
||||
const struct nfsd4_layout_seg *seg = &lcp->lc_seg;
|
||||
struct svc_fh *current_fh = &cstate->current_fh;
|
||||
|
|
@ -2561,23 +2562,34 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
|
|||
}
|
||||
}
|
||||
|
||||
nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lcp->lc_sid,
|
||||
false, lcp->lc_layout_type,
|
||||
&ls);
|
||||
if (nfserr) {
|
||||
trace_nfsd_layout_commit_lookup_fail(&lcp->lc_sid);
|
||||
/* fixup error code as per RFC5661 */
|
||||
if (nfserr == nfserr_bad_stateid)
|
||||
nfserr = nfserr_badlayout;
|
||||
nfserr = nfserr_grace;
|
||||
if (locks_in_grace(net) && !lcp->lc_reclaim)
|
||||
goto out;
|
||||
nfserr = nfserr_no_grace;
|
||||
if (!locks_in_grace(net) && lcp->lc_reclaim)
|
||||
goto out;
|
||||
|
||||
if (!lcp->lc_reclaim) {
|
||||
nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate,
|
||||
&lcp->lc_sid, false, lcp->lc_layout_type, &ls);
|
||||
if (nfserr) {
|
||||
trace_nfsd_layout_commit_lookup_fail(&lcp->lc_sid);
|
||||
/* fixup error code as per RFC5661 */
|
||||
if (nfserr == nfserr_bad_stateid)
|
||||
nfserr = nfserr_badlayout;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* LAYOUTCOMMIT does not require any serialization */
|
||||
mutex_unlock(&ls->ls_mutex);
|
||||
}
|
||||
|
||||
/* LAYOUTCOMMIT does not require any serialization */
|
||||
mutex_unlock(&ls->ls_mutex);
|
||||
|
||||
nfserr = ops->proc_layoutcommit(inode, rqstp, lcp);
|
||||
nfsd4_file_mark_deleg_written(ls->ls_stid.sc_file);
|
||||
nfs4_put_stid(&ls->ls_stid);
|
||||
|
||||
if (!lcp->lc_reclaim) {
|
||||
nfsd4_file_mark_deleg_written(ls->ls_stid.sc_file);
|
||||
nfs4_put_stid(&ls->ls_stid);
|
||||
}
|
||||
out:
|
||||
return nfserr;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue