diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2017-11-05 15:45:22 -0500 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2017-11-17 16:43:52 -0500 |
commit | c05cefcc72416a37eba5a2b35f0704ed758a9145 (patch) | |
tree | 74afd3e29a68c0b319610d0c7a83dbe5b3a9a982 | |
parent | fd53dde83978ba5f7db3183ce56b3a1c39f448b0 (diff) |
nfs: Fix ugly referral attributes
Before traversing a referral and performing a mount, the mounted-on
directory looks strange:
dr-xr-xr-x. 2 4294967294 4294967294 0 Dec 31 1969 dir.0
nfs4_get_referral is wiping out any cached attributes with what was
returned via GETATTR(fs_locations), but the bit mask for that
operation does not request any file attributes.
Retrieve owner and timestamp information so that the memcpy in
nfs4_get_referral fills in more attributes.
Changes since v1:
- Don't request attributes that the client unconditionally replaces
- Request only MOUNTED_ON_FILEID or FILEID attribute, not both
- encode_fs_locations() doesn't use the third bitmask word
Fixes: 6b97fd3da1ea ("NFSv4: Follow a referral")
Suggested-by: Pradeep Thomas <pradeepthomas@gmail.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Cc: stable@vger.kernel.org
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r-- | fs/nfs/nfs4proc.c | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2c9c22579610..6b23a032ee1e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -258,15 +258,12 @@ const u32 nfs4_fsinfo_bitmap[3] = { FATTR4_WORD0_MAXFILESIZE | |||
258 | }; | 258 | }; |
259 | 259 | ||
260 | const u32 nfs4_fs_locations_bitmap[3] = { | 260 | const u32 nfs4_fs_locations_bitmap[3] = { |
261 | FATTR4_WORD0_TYPE | 261 | FATTR4_WORD0_CHANGE |
262 | | FATTR4_WORD0_CHANGE | ||
263 | | FATTR4_WORD0_SIZE | 262 | | FATTR4_WORD0_SIZE |
264 | | FATTR4_WORD0_FSID | 263 | | FATTR4_WORD0_FSID |
265 | | FATTR4_WORD0_FILEID | 264 | | FATTR4_WORD0_FILEID |
266 | | FATTR4_WORD0_FS_LOCATIONS, | 265 | | FATTR4_WORD0_FS_LOCATIONS, |
267 | FATTR4_WORD1_MODE | 266 | FATTR4_WORD1_OWNER |
268 | | FATTR4_WORD1_NUMLINKS | ||
269 | | FATTR4_WORD1_OWNER | ||
270 | | FATTR4_WORD1_OWNER_GROUP | 267 | | FATTR4_WORD1_OWNER_GROUP |
271 | | FATTR4_WORD1_RAWDEV | 268 | | FATTR4_WORD1_RAWDEV |
272 | | FATTR4_WORD1_SPACE_USED | 269 | | FATTR4_WORD1_SPACE_USED |
@@ -6907,9 +6904,7 @@ static int _nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir, | |||
6907 | struct page *page) | 6904 | struct page *page) |
6908 | { | 6905 | { |
6909 | struct nfs_server *server = NFS_SERVER(dir); | 6906 | struct nfs_server *server = NFS_SERVER(dir); |
6910 | u32 bitmask[3] = { | 6907 | u32 bitmask[3]; |
6911 | [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, | ||
6912 | }; | ||
6913 | struct nfs4_fs_locations_arg args = { | 6908 | struct nfs4_fs_locations_arg args = { |
6914 | .dir_fh = NFS_FH(dir), | 6909 | .dir_fh = NFS_FH(dir), |
6915 | .name = name, | 6910 | .name = name, |
@@ -6928,12 +6923,15 @@ static int _nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir, | |||
6928 | 6923 | ||
6929 | dprintk("%s: start\n", __func__); | 6924 | dprintk("%s: start\n", __func__); |
6930 | 6925 | ||
6926 | bitmask[0] = nfs4_fattr_bitmap[0] | FATTR4_WORD0_FS_LOCATIONS; | ||
6927 | bitmask[1] = nfs4_fattr_bitmap[1]; | ||
6928 | |||
6931 | /* Ask for the fileid of the absent filesystem if mounted_on_fileid | 6929 | /* Ask for the fileid of the absent filesystem if mounted_on_fileid |
6932 | * is not supported */ | 6930 | * is not supported */ |
6933 | if (NFS_SERVER(dir)->attr_bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) | 6931 | if (NFS_SERVER(dir)->attr_bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) |
6934 | bitmask[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID; | 6932 | bitmask[0] &= ~FATTR4_WORD0_FILEID; |
6935 | else | 6933 | else |
6936 | bitmask[0] |= FATTR4_WORD0_FILEID; | 6934 | bitmask[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; |
6937 | 6935 | ||
6938 | nfs_fattr_init(&fs_locations->fattr); | 6936 | nfs_fattr_init(&fs_locations->fattr); |
6939 | fs_locations->server = server; | 6937 | fs_locations->server = server; |