Commit 7663e963 authored by Jeff Layton's avatar Jeff Layton Committed by Chuck Lever
Browse files

nfsd: track original timestamps in nfs4_delegation

As Trond points out [1], the "original time" mentioned in RFC 9754
refers to the timestamps on the files at the time that the delegation
was granted, and not the current timestamp of the file on the server.

Store the current timestamps for the file in the nfs4_delegation when
granting one. Add STATX_ATIME and STATX_MTIME to the request mask in
nfs4_delegation_stat(). When granting OPEN_DELEGATE_READ_ATTRS_DELEG, do
a nfs4_delegation_stat() and save the correct atime. If the stat() fails
for any reason, fall back to granting a normal read deleg.

[1]: https://lore.kernel.org/linux-nfs/47a4e40310e797f21b5137e847b06bb203d99e66.camel@kernel.org/



Fixes: 7e13f4f8 ("nfsd: handle delegated timestamps in SETATTR")
Signed-off-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent c066ff58
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -6157,7 +6157,8 @@ nfs4_delegation_stat(struct nfs4_delegation *dp, struct svc_fh *currentfh,
	path.dentry = file_dentry(nf->nf_file);

	rc = vfs_getattr(&path, stat,
			 (STATX_MODE | STATX_SIZE | STATX_CTIME | STATX_CHANGE_COOKIE),
			 STATX_MODE | STATX_SIZE | STATX_ATIME |
			 STATX_MTIME | STATX_CTIME | STATX_CHANGE_COOKIE,
			 AT_STATX_SYNC_AS_STAT);

	nfsd_file_put(nf);
@@ -6274,10 +6275,14 @@ nfs4_open_delegation(struct svc_rqst *rqstp, struct nfsd4_open *open,
						    OPEN_DELEGATE_WRITE;
		dp->dl_cb_fattr.ncf_cur_fsize = stat.size;
		dp->dl_cb_fattr.ncf_initial_cinfo = nfsd4_change_attribute(&stat);
		dp->dl_atime = stat.atime;
		dp->dl_ctime = stat.ctime;
		dp->dl_mtime = stat.mtime;
		trace_nfsd_deleg_write(&dp->dl_stid.sc_stateid);
	} else {
		open->op_delegate_type = deleg_ts ? OPEN_DELEGATE_READ_ATTRS_DELEG :
						    OPEN_DELEGATE_READ;
		open->op_delegate_type = deleg_ts && nfs4_delegation_stat(dp, currentfh, &stat) ?
					 OPEN_DELEGATE_READ_ATTRS_DELEG : OPEN_DELEGATE_READ;
		dp->dl_atime = stat.atime;
		trace_nfsd_deleg_read(&dp->dl_stid.sc_stateid);
	}
	nfs4_put_stid(&dp->dl_stid);
+5 −0
Original line number Diff line number Diff line
@@ -224,6 +224,11 @@ struct nfs4_delegation {

	/* for CB_GETATTR */
	struct nfs4_cb_fattr    dl_cb_fattr;

	/* For delegated timestamps */
	struct timespec64	dl_atime;
	struct timespec64	dl_mtime;
	struct timespec64	dl_ctime;
};

static inline bool deleg_is_read(u32 dl_type)