Skip to content

Commit 7e13f4f

Browse files
jtlaytonchucklever
authored andcommitted
nfsd: handle delegated timestamps in SETATTR
Allow SETATTR to handle delegated timestamps. This patch assumes that only the delegation holder has the ability to set the timestamps in this way, so we allow this only if the SETATTR stateid refers to a *_ATTRS_DELEG delegation. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 6ae30d6 commit 7e13f4f

File tree

4 files changed

+53
-5
lines changed

4 files changed

+53
-5
lines changed

fs/nfsd/nfs4proc.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,18 +1135,43 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
11351135
.na_iattr = &setattr->sa_iattr,
11361136
.na_seclabel = &setattr->sa_label,
11371137
};
1138+
bool save_no_wcc, deleg_attrs;
1139+
struct nfs4_stid *st = NULL;
11381140
struct inode *inode;
11391141
__be32 status = nfs_ok;
1140-
bool save_no_wcc;
11411142
int err;
11421143

1143-
if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
1144+
deleg_attrs = setattr->sa_bmval[2] & (FATTR4_WORD2_TIME_DELEG_ACCESS |
1145+
FATTR4_WORD2_TIME_DELEG_MODIFY);
1146+
1147+
if (deleg_attrs || (setattr->sa_iattr.ia_valid & ATTR_SIZE)) {
1148+
int flags = WR_STATE;
1149+
1150+
if (setattr->sa_bmval[2] & FATTR4_WORD2_TIME_DELEG_ACCESS)
1151+
flags |= RD_STATE;
1152+
11441153
status = nfs4_preprocess_stateid_op(rqstp, cstate,
11451154
&cstate->current_fh, &setattr->sa_stateid,
1146-
WR_STATE, NULL, NULL);
1155+
flags, NULL, &st);
11471156
if (status)
11481157
return status;
11491158
}
1159+
1160+
if (deleg_attrs) {
1161+
status = nfserr_bad_stateid;
1162+
if (st->sc_type & SC_TYPE_DELEG) {
1163+
struct nfs4_delegation *dp = delegstateid(st);
1164+
1165+
/* Only for *_ATTRS_DELEG flavors */
1166+
if (deleg_attrs_deleg(dp->dl_type))
1167+
status = nfs_ok;
1168+
}
1169+
}
1170+
if (st)
1171+
nfs4_put_stid(st);
1172+
if (status)
1173+
return status;
1174+
11501175
err = fh_want_write(&cstate->current_fh);
11511176
if (err)
11521177
return nfserrno(err);

fs/nfsd/nfs4state.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5595,7 +5595,7 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,
55955595
static inline __be32
55965596
nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
55975597
{
5598-
if ((flags & WR_STATE) && deleg_is_read(dp->dl_type))
5598+
if (!(flags & RD_STATE) && deleg_is_read(dp->dl_type))
55995599
return nfserr_openmode;
56005600
else
56015601
return nfs_ok;

fs/nfsd/nfs4xdr.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,26 @@ nfsd4_decode_fattr4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen,
521521
*umask = mask & S_IRWXUGO;
522522
iattr->ia_valid |= ATTR_MODE;
523523
}
524+
if (bmval[2] & FATTR4_WORD2_TIME_DELEG_ACCESS) {
525+
fattr4_time_deleg_access access;
526+
527+
if (!xdrgen_decode_fattr4_time_deleg_access(argp->xdr, &access))
528+
return nfserr_bad_xdr;
529+
iattr->ia_atime.tv_sec = access.seconds;
530+
iattr->ia_atime.tv_nsec = access.nseconds;
531+
iattr->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET | ATTR_DELEG;
532+
}
533+
if (bmval[2] & FATTR4_WORD2_TIME_DELEG_MODIFY) {
534+
fattr4_time_deleg_modify modify;
535+
536+
if (!xdrgen_decode_fattr4_time_deleg_modify(argp->xdr, &modify))
537+
return nfserr_bad_xdr;
538+
iattr->ia_mtime.tv_sec = modify.seconds;
539+
iattr->ia_mtime.tv_nsec = modify.nseconds;
540+
iattr->ia_ctime.tv_sec = modify.seconds;
541+
iattr->ia_ctime.tv_nsec = modify.seconds;
542+
iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME | ATTR_MTIME_SET | ATTR_DELEG;
543+
}
524544

525545
/* request sanity: did attrlist4 contain the expected number of words? */
526546
if (attrlist4_count != xdr_stream_pos(argp->xdr) - starting_pos)

fs/nfsd/nfsd.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,10 @@ static inline bool nfsd_attrs_supported(u32 minorversion, const u32 *bmval)
528528
#endif
529529
#define NFSD_WRITEABLE_ATTRS_WORD2 \
530530
(FATTR4_WORD2_MODE_UMASK \
531-
| MAYBE_FATTR4_WORD2_SECURITY_LABEL)
531+
| MAYBE_FATTR4_WORD2_SECURITY_LABEL \
532+
| FATTR4_WORD2_TIME_DELEG_ACCESS \
533+
| FATTR4_WORD2_TIME_DELEG_MODIFY \
534+
)
532535

533536
#define NFSD_SUPPATTR_EXCLCREAT_WORD0 \
534537
NFSD_WRITEABLE_ATTRS_WORD0

0 commit comments

Comments
 (0)