Use s_dev number and the server's fsid to report f_fsid in statfs(2). The server's fsid could be zero for NFSv4 root export and is not unique across different servers, so we use the s_dev number to avoid local f_fsid collisions. The s_dev number could be easily recycled, so we use a 32bit hash of the server's fsid to try to avoid the recycling of same local f_fsid for different remote fs. The anon bdev number is only 20 bits (major is 0), so we could use more bits for the server's fsid hash, but avoiding f_fsid recycling is not critical, so 32bit hash is enough. This allows nfs client to be monitored by fanotify filesystem watch for local client access if nfs supports re-export. For example, with inotify-tools 4.23.8.0, the following command can be used to watch local client access over entire nfs filesystem: fsnotifywatch --filesystem /mnt/nfs Note that fanotify filesystem watch does not report remote changes on server. It provides the same notifications as inotify, but it watches over the entire filesystem and reports file handle of objects and fsid with events. Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx> --- Anna, Trond, I have changed v2 according to feedback from Ben. I would like to refer you to the documentation of f_fsid in statfs(2): "Nobody knows what f_fsid is supposed to contain... The general idea is that f_fsid contains some random stuff such that the pair (f_fsid,ino) uniquely determines a file. Some operating systems use (a variation on) the device number, or the device number combined with the filesystem type..." This definition leaves a lot of room for interpretations. I chose f_fsid format {dev_num, fsid_hash}, because I think that it nicely extends f_fsid format {dev_num, 0}, used by many fs without persistent fsid. Thanks, Amir. Changes since v1: - Use d_sev number to avoid collisions (bcodding) fs/nfs/super.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 0d6473cb00cb..30bcd53da3bc 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -295,6 +295,15 @@ int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_ffree = res.afiles; buf->f_namelen = server->namelen; + /* + * Using the anon bdev number to avoid local f_fsid collisions. + * Server's fsid could be zero for NFSv4 root export and is not unique + * across different servers, but we use it as best effort to try to + * avoid the recycling of same local f_fsid for different remote fs. + */ + buf->f_fsid.val[0] = new_encode_dev(server->s_dev); + buf->f_fsid.val[1] = hash_64(server->fsid.major, 32) ^ + hash_64(server->fsid.minor, 32); return 0; -- 2.34.1