NFS: Introduce NFS_ATTR_FATTR_V4_LOCATIONS
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>
This commit is contained in:
committed by
Trond Myklebust
parent
bb4dae5e5b
commit
81934ddb8e
@@ -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_recover_proc_open(struct nfs4_opendata *data);
|
||||||
static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
|
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 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_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,
|
static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
|
||||||
struct nfs_fattr *fattr, struct iattr *sattr,
|
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);
|
return nfs4_map_errors(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
|
|
||||||
/*
|
/*
|
||||||
* Get locations and (maybe) other attributes of a referral.
|
* Get locations and (maybe) other attributes of a referral.
|
||||||
* Note that we'll actually follow the referral later when
|
* 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) ||
|
if (!(((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) ||
|
||||||
(fattr->valid & NFS_ATTR_FATTR_FILEID)) &&
|
(fattr->valid & NFS_ATTR_FATTR_FILEID)) &&
|
||||||
(fattr->valid & NFS_ATTR_FATTR_FSID) &&
|
(fattr->valid & NFS_ATTR_FATTR_FSID) &&
|
||||||
(fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)))
|
(fattr->valid & NFS_ATTR_FATTR_V4_LOCATIONS)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE |
|
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->mode = S_IFDIR | S_IRUGO | S_IXUGO;
|
||||||
fattr->nlink = 2;
|
fattr->nlink = 2;
|
||||||
}
|
}
|
||||||
|
@@ -3660,7 +3660,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
|
|||||||
res->nlocations++;
|
res->nlocations++;
|
||||||
}
|
}
|
||||||
if (res->nlocations != 0)
|
if (res->nlocations != 0)
|
||||||
status = NFS_ATTR_FATTR_V4_REFERRAL;
|
status = NFS_ATTR_FATTR_V4_LOCATIONS;
|
||||||
out:
|
out:
|
||||||
dprintk("%s: fs_locations done, error = %d\n", __func__, status);
|
dprintk("%s: fs_locations done, error = %d\n", __func__, status);
|
||||||
return status;
|
return status;
|
||||||
|
@@ -88,11 +88,12 @@ struct nfs_fattr {
|
|||||||
#define NFS_ATTR_FATTR_PRECTIME (1U << 16)
|
#define NFS_ATTR_FATTR_PRECTIME (1U << 16)
|
||||||
#define NFS_ATTR_FATTR_CHANGE (1U << 17)
|
#define NFS_ATTR_FATTR_CHANGE (1U << 17)
|
||||||
#define NFS_ATTR_FATTR_PRECHANGE (1U << 18)
|
#define NFS_ATTR_FATTR_PRECHANGE (1U << 18)
|
||||||
#define NFS_ATTR_FATTR_V4_REFERRAL (1U << 19) /* NFSv4 referral */
|
#define NFS_ATTR_FATTR_V4_LOCATIONS (1U << 19)
|
||||||
#define NFS_ATTR_FATTR_MOUNTPOINT (1U << 20) /* Treat as mountpoint */
|
#define NFS_ATTR_FATTR_V4_REFERRAL (1U << 20)
|
||||||
#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 21)
|
#define NFS_ATTR_FATTR_MOUNTPOINT (1U << 21)
|
||||||
#define NFS_ATTR_FATTR_OWNER_NAME (1U << 22)
|
#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 22)
|
||||||
#define NFS_ATTR_FATTR_GROUP_NAME (1U << 23)
|
#define NFS_ATTR_FATTR_OWNER_NAME (1U << 23)
|
||||||
|
#define NFS_ATTR_FATTR_GROUP_NAME (1U << 24)
|
||||||
|
|
||||||
#define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
|
#define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
|
||||||
| NFS_ATTR_FATTR_MODE \
|
| NFS_ATTR_FATTR_MODE \
|
||||||
|
Reference in New Issue
Block a user