NFS: Introduce NFS_ATTR_FATTR_V4_LOCATIONS
authorChuck Lever <chuck.lever@oracle.com>
Thu, 1 Mar 2012 22:01:57 +0000 (17:01 -0500)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Fri, 2 Mar 2012 22:18:09 +0000 (17:18 -0500)
The Linux NFS client must distinguish between referral events (which
it currently supports) and migration events (which it does not yet
support).

In both types of events, an fs_locations array is returned.  But upper
layers, not the XDR layer, should make the distinction between a
referral and a migration.  There really isn't a way for an XDR decoder
function to distinguish the two, in general.

Slightly adjust the FATTR flags returned by decode_fs_locations()
to set NFS_ATTR_FATTR_V4_LOCATIONS only if a non-empty locations
array was returned from the server.  Then have logic in nfs4proc.c
distinguish whether the locations array is for a referral or
something else.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
include/linux/nfs_xdr.h

index 54767dd66cf974236178391a6866bddae3ac3753..281c2def2b193648f04b20b77254edeab224587f 100644 (file)
@@ -79,6 +79,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data);
 static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
 static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
 static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
+static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
 static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
 static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
                            struct nfs_fattr *fattr, struct iattr *sattr,
@@ -2340,7 +2341,6 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
        return nfs4_map_errors(status);
 }
 
-static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
 /*
  * Get locations and (maybe) other attributes of a referral.
  * Note that we'll actually follow the referral later when
@@ -4797,11 +4797,11 @@ static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr)
        if (!(((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) ||
               (fattr->valid & NFS_ATTR_FATTR_FILEID)) &&
              (fattr->valid & NFS_ATTR_FATTR_FSID) &&
-             (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)))
+             (fattr->valid & NFS_ATTR_FATTR_V4_LOCATIONS)))
                return;
 
        fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE |
-               NFS_ATTR_FATTR_NLINK;
+               NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_V4_REFERRAL;
        fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO;
        fattr->nlink = 2;
 }
index 48f539314f257dc5bad20564285563b453ee8e18..a6fb55da874cb4d26d60ca5596f648842a1c1dc8 100644 (file)
@@ -3660,7 +3660,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
                        res->nlocations++;
        }
        if (res->nlocations != 0)
-               status = NFS_ATTR_FATTR_V4_REFERRAL;
+               status = NFS_ATTR_FATTR_V4_LOCATIONS;
 out:
        dprintk("%s: fs_locations done, error = %d\n", __func__, status);
        return status;
index 046c1bfddc3348fc7b56e3fca6d507b03fe275d5..210da5dc4f17570db9c5183b7ef9ed17d736320e 100644 (file)
@@ -88,11 +88,12 @@ struct nfs_fattr {
 #define NFS_ATTR_FATTR_PRECTIME                (1U << 16)
 #define NFS_ATTR_FATTR_CHANGE          (1U << 17)
 #define NFS_ATTR_FATTR_PRECHANGE       (1U << 18)
-#define NFS_ATTR_FATTR_V4_REFERRAL     (1U << 19)      /* NFSv4 referral */
-#define NFS_ATTR_FATTR_MOUNTPOINT      (1U << 20)      /* Treat as mountpoint */
-#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID               (1U << 21)
-#define NFS_ATTR_FATTR_OWNER_NAME      (1U << 22)
-#define NFS_ATTR_FATTR_GROUP_NAME      (1U << 23)
+#define NFS_ATTR_FATTR_V4_LOCATIONS    (1U << 19)
+#define NFS_ATTR_FATTR_V4_REFERRAL     (1U << 20)
+#define NFS_ATTR_FATTR_MOUNTPOINT      (1U << 21)
+#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 22)
+#define NFS_ATTR_FATTR_OWNER_NAME      (1U << 23)
+#define NFS_ATTR_FATTR_GROUP_NAME      (1U << 24)
 
 #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
                | NFS_ATTR_FATTR_MODE \