In addition to the filename, send attributes about the inode in a
CB_NOTIFY event. This patch just adds a the basic inode information that
can be acquired via GETATTR.

Signed-off-by: Jeff Layton <[email protected]>
---
 fs/nfsd/nfs4xdr.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 
d1eba4bd8be243022f89f6ac58067c5469a8feba..1db2bd974bfa9d899f590f4b4e869115ab73aff6
 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3758,12 +3758,22 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct 
xdr_stream *xdr,
        goto out;
 }
 
+#define CB_NOTIFY_STATX_REQUEST_MASK (STATX_BASIC_STATS   | \
+                                     STATX_BTIME         | \
+                                     STATX_CHANGE_COOKIE)
+
 static bool
 nfsd4_setup_notify_entry4(struct notify_entry4 *ne, struct xdr_stream *xdr,
                          struct dentry *dentry, struct nfs4_delegation *dp,
                          char *name, u32 namelen)
 {
+       struct nfs4_file *fi = dp->dl_stid.sc_file;
+       struct path path =  { .mnt = fi->fi_deleg_file->nf_file->f_path.mnt,
+                             .dentry = dentry };
+       struct nfsd4_fattr_args args = { };
        uint32_t *attrmask;
+       __be32 status;
+       int ret;
 
        /* Reserve space for attrmask */
        attrmask = xdr_reserve_space(xdr, 3 * sizeof(uint32_t));
@@ -3774,6 +3784,41 @@ nfsd4_setup_notify_entry4(struct notify_entry4 *ne, 
struct xdr_stream *xdr,
        ne->ne_file.len = namelen;
        ne->ne_attrs.attrmask.element = attrmask;
 
+       /* FIXME: d_find_alias for inode ? */
+       if (!path.dentry || !d_inode(path.dentry))
+               goto noattrs;
+
+       /*
+        * It is possible that the client was granted a delegation when a file
+        * was created. Note that we don't issue a CB_GETATTR here since stale
+        * attributes are presumably ok.
+        */
+       ret = vfs_getattr(&path, &args.stat, CB_NOTIFY_STATX_REQUEST_MASK, 
AT_STATX_SYNC_AS_STAT);
+       if (ret)
+               goto noattrs;
+
+       args.change_attr = nfsd4_change_attribute(&args.stat);
+
+       attrmask[0] = FATTR4_WORD0_TYPE | FATTR4_WORD0_CHANGE |
+                     FATTR4_WORD0_SIZE | FATTR4_WORD0_FILEID;
+       attrmask[1] = FATTR4_WORD1_MODE | FATTR4_WORD1_NUMLINKS | 
FATTR4_WORD1_RAWDEV |
+                     FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS |
+                     FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY;
+       attrmask[2] = 0;
+
+       if (args.stat.result_mask & STATX_BTIME)
+               attrmask[1] |= FATTR4_WORD1_TIME_CREATE;
+
+       ne->ne_attrs.attrmask.count = 2;
+       ne->ne_attrs.attr_vals.data = (u8 *)xdr->p;
+
+       status = nfsd4_encode_attr_vals(xdr, attrmask, &args);
+       if (status != nfs_ok)
+               goto noattrs;
+
+       ne->ne_attrs.attr_vals.len = (u8 *)xdr->p - ne->ne_attrs.attr_vals.data;
+       return true;
+noattrs:
        attrmask[0] = 0;
        attrmask[1] = 0;
        attrmask[2] = 0;

-- 
2.51.0


Reply via email to