diff options
| author | Chuck Lever <chuck.lever@oracle.com> | 2012-03-01 17:01:57 -0500 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-02 17:18:09 -0500 |
| commit | 81934ddb8eb62a85b8015c0f2b824a88510965a2 (patch) | |
| tree | db5988884f8a0309b488cba6623b1ed2c31af983 | |
| parent | bb4dae5e5b5a92f0ffbcc6ac10c5e8afcd87934d (diff) | |
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>
| -rw-r--r-- | fs/nfs/nfs4proc.c | 6 | ||||
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 2 | ||||
| -rw-r--r-- | include/linux/nfs_xdr.h | 11 |
3 files changed, 10 insertions, 9 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 54767dd66cf9..281c2def2b19 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -79,6 +79,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data); | |||
| 79 | static int _nfs4_recover_proc_open(struct nfs4_opendata *data); | 79 | static int _nfs4_recover_proc_open(struct nfs4_opendata *data); |
| 80 | static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); | 80 | static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); |
| 81 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); | 81 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); |
| 82 | static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); | ||
| 82 | static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); | 83 | static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); |
| 83 | static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, | 84 | static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, |
| 84 | struct nfs_fattr *fattr, struct iattr *sattr, | 85 | 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, | |||
| 2340 | return nfs4_map_errors(status); | 2341 | return nfs4_map_errors(status); |
| 2341 | } | 2342 | } |
| 2342 | 2343 | ||
| 2343 | static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); | ||
| 2344 | /* | 2344 | /* |
| 2345 | * Get locations and (maybe) other attributes of a referral. | 2345 | * Get locations and (maybe) other attributes of a referral. |
| 2346 | * Note that we'll actually follow the referral later when | 2346 | * Note that we'll actually follow the referral later when |
| @@ -4797,11 +4797,11 @@ static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr) | |||
| 4797 | if (!(((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) || | 4797 | if (!(((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) || |
| 4798 | (fattr->valid & NFS_ATTR_FATTR_FILEID)) && | 4798 | (fattr->valid & NFS_ATTR_FATTR_FILEID)) && |
| 4799 | (fattr->valid & NFS_ATTR_FATTR_FSID) && | 4799 | (fattr->valid & NFS_ATTR_FATTR_FSID) && |
| 4800 | (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL))) | 4800 | (fattr->valid & NFS_ATTR_FATTR_V4_LOCATIONS))) |
| 4801 | return; | 4801 | return; |
| 4802 | 4802 | ||
| 4803 | fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE | | 4803 | fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE | |
| 4804 | NFS_ATTR_FATTR_NLINK; | 4804 | NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_V4_REFERRAL; |
| 4805 | fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO; | 4805 | fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO; |
| 4806 | fattr->nlink = 2; | 4806 | fattr->nlink = 2; |
| 4807 | } | 4807 | } |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 48f539314f25..a6fb55da874c 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
| @@ -3660,7 +3660,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
| 3660 | res->nlocations++; | 3660 | res->nlocations++; |
| 3661 | } | 3661 | } |
| 3662 | if (res->nlocations != 0) | 3662 | if (res->nlocations != 0) |
| 3663 | status = NFS_ATTR_FATTR_V4_REFERRAL; | 3663 | status = NFS_ATTR_FATTR_V4_LOCATIONS; |
| 3664 | out: | 3664 | out: |
| 3665 | dprintk("%s: fs_locations done, error = %d\n", __func__, status); | 3665 | dprintk("%s: fs_locations done, error = %d\n", __func__, status); |
| 3666 | return status; | 3666 | return status; |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 046c1bfddc33..210da5dc4f17 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
| @@ -88,11 +88,12 @@ struct nfs_fattr { | |||
| 88 | #define NFS_ATTR_FATTR_PRECTIME (1U << 16) | 88 | #define NFS_ATTR_FATTR_PRECTIME (1U << 16) |
| 89 | #define NFS_ATTR_FATTR_CHANGE (1U << 17) | 89 | #define NFS_ATTR_FATTR_CHANGE (1U << 17) |
| 90 | #define NFS_ATTR_FATTR_PRECHANGE (1U << 18) | 90 | #define NFS_ATTR_FATTR_PRECHANGE (1U << 18) |
| 91 | #define NFS_ATTR_FATTR_V4_REFERRAL (1U << 19) /* NFSv4 referral */ | 91 | #define NFS_ATTR_FATTR_V4_LOCATIONS (1U << 19) |
| 92 | #define NFS_ATTR_FATTR_MOUNTPOINT (1U << 20) /* Treat as mountpoint */ | 92 | #define NFS_ATTR_FATTR_V4_REFERRAL (1U << 20) |
| 93 | #define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 21) | 93 | #define NFS_ATTR_FATTR_MOUNTPOINT (1U << 21) |
| 94 | #define NFS_ATTR_FATTR_OWNER_NAME (1U << 22) | 94 | #define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 22) |
| 95 | #define NFS_ATTR_FATTR_GROUP_NAME (1U << 23) | 95 | #define NFS_ATTR_FATTR_OWNER_NAME (1U << 23) |
| 96 | #define NFS_ATTR_FATTR_GROUP_NAME (1U << 24) | ||
| 96 | 97 | ||
| 97 | #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \ | 98 | #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \ |
| 98 | | NFS_ATTR_FATTR_MODE \ | 99 | | NFS_ATTR_FATTR_MODE \ |
