Commit 7aaa0b3b authored by Manoj Naik's avatar Manoj Naik Committed by Trond Myklebust

NFSv4: convert fs-locations-components to conform to RFC3530

Use component4-style formats for decoding list of servers and pathnames in
fs_locations.
Signed-off-by: default avatarManoj Naik <manoj@almaden.ibm.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 683b57b4
...@@ -219,7 +219,7 @@ extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct n ...@@ -219,7 +219,7 @@ extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct n
extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
extern int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry, extern int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry,
struct nfs_fs_locations *fs_locations, struct page *page); struct nfs4_fs_locations *fs_locations, struct page *page);
extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops; extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops; extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;
......
...@@ -3571,7 +3571,7 @@ ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen) ...@@ -3571,7 +3571,7 @@ ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen)
} }
int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry, int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry,
struct nfs_fs_locations *fs_locations, struct page *page) struct nfs4_fs_locations *fs_locations, struct page *page)
{ {
struct nfs_server *server = NFS_SERVER(dir); struct nfs_server *server = NFS_SERVER(dir);
u32 bitmask[2] = { u32 bitmask[2] = {
...@@ -3587,7 +3587,7 @@ int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry, ...@@ -3587,7 +3587,7 @@ int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry,
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS], .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
.rpc_argp = &args, .rpc_argp = &args,
.rpc_resp = &fs_locations, .rpc_resp = fs_locations,
}; };
int status; int status;
......
...@@ -2377,7 +2377,43 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin ...@@ -2377,7 +2377,43 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin
return status; return status;
} }
static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fs_locations *res) static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path)
{
int n;
uint32_t *p;
int status = 0;
READ_BUF(4);
READ32(n);
if (n <= 0)
goto out_eio;
dprintk("path ");
path->ncomponents = 0;
while (path->ncomponents < n) {
struct nfs4_string *component = &path->components[path->ncomponents];
status = decode_opaque_inline(xdr, &component->len, &component->data);
if (unlikely(status != 0))
goto out_eio;
if (path->ncomponents != n)
dprintk("/");
dprintk("%s", component->data);
if (path->ncomponents < NFS4_PATHNAME_MAXCOMPONENTS)
path->ncomponents++;
else {
dprintk("cannot parse %d components in path\n", n);
goto out_eio;
}
}
out:
dprintk("\n");
return status;
out_eio:
dprintk(" status %d", status);
status = -EIO;
goto out;
}
static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res)
{ {
int n; int n;
uint32_t *p; uint32_t *p;
...@@ -2388,7 +2424,8 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st ...@@ -2388,7 +2424,8 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
status = 0; status = 0;
if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS))) if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS)))
goto out; goto out;
status = decode_opaque_inline(xdr, &res->fs_pathlen, &res->fs_path); dprintk("%s: fsroot ", __FUNCTION__);
status = decode_pathname(xdr, &res->fs_path);
if (unlikely(status != 0)) if (unlikely(status != 0))
goto out; goto out;
READ_BUF(4); READ_BUF(4);
...@@ -2397,15 +2434,40 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st ...@@ -2397,15 +2434,40 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
goto out_eio; goto out_eio;
res->nlocations = 0; res->nlocations = 0;
while (res->nlocations < n) { while (res->nlocations < n) {
struct nfs_fs_location *loc = &res->locations[res->nlocations]; int m;
struct nfs4_fs_location *loc = &res->locations[res->nlocations];
READ_BUF(4);
READ32(m);
if (m <= 0)
goto out_eio;
status = decode_opaque_inline(xdr, &loc->serverlen, &loc->server); loc->nservers = 0;
dprintk("%s: servers ", __FUNCTION__);
while (loc->nservers < m) {
struct nfs4_string *server = &loc->servers[loc->nservers];
status = decode_opaque_inline(xdr, &server->len, &server->data);
if (unlikely(status != 0)) if (unlikely(status != 0))
goto out_eio; goto out_eio;
status = decode_opaque_inline(xdr, &loc->rootpathlen, &loc->rootpath); dprintk("%s ", server->data);
if (loc->nservers < NFS4_FS_LOCATION_MAXSERVERS)
loc->nservers++;
else {
int i;
dprintk("%s: using first %d of %d servers returned for location %d\n", __FUNCTION__, NFS4_FS_LOCATION_MAXSERVERS, m, res->nlocations);
for (i = loc->nservers; i < m; i++) {
int len;
char *data;
status = decode_opaque_inline(xdr, &len, &data);
if (unlikely(status != 0))
goto out_eio;
}
}
}
status = decode_pathname(xdr, &loc->rootpath);
if (unlikely(status != 0)) if (unlikely(status != 0))
goto out_eio; goto out_eio;
if (res->nlocations < NFS_FS_LOCATIONS_MAXENTRIES) if (res->nlocations < NFS4_FS_LOCATIONS_MAXENTRIES)
res->nlocations++; res->nlocations++;
} }
out: out:
...@@ -2948,7 +3010,7 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons ...@@ -2948,7 +3010,7 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons
if ((status = decode_attr_fileid(xdr, bitmap, &fattr->fileid)) != 0) if ((status = decode_attr_fileid(xdr, bitmap, &fattr->fileid)) != 0)
goto xdr_error; goto xdr_error;
if ((status = decode_attr_fs_locations(xdr, bitmap, container_of(fattr, if ((status = decode_attr_fs_locations(xdr, bitmap, container_of(fattr,
struct nfs_fs_locations, struct nfs4_fs_locations,
fattr))) != 0) fattr))) != 0)
goto xdr_error; goto xdr_error;
if ((status = decode_attr_mode(xdr, bitmap, &fattr->mode)) != 0) if ((status = decode_attr_mode(xdr, bitmap, &fattr->mode)) != 0)
...@@ -4297,7 +4359,7 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, struct ...@@ -4297,7 +4359,7 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, struct
/* /*
* FS_LOCATIONS request * FS_LOCATIONS request
*/ */
static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, uint32_t *p, struct nfs_fs_locations *res) static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, uint32_t *p, struct nfs4_fs_locations *res)
{ {
struct xdr_stream xdr; struct xdr_stream xdr;
struct compound_hdr hdr; struct compound_hdr hdr;
......
...@@ -679,21 +679,31 @@ struct nfs4_server_caps_res { ...@@ -679,21 +679,31 @@ struct nfs4_server_caps_res {
u32 has_symlinks; u32 has_symlinks;
}; };
struct nfs_fs_location { struct nfs4_string {
unsigned int serverlen; unsigned int len;
char * server; char *data;
unsigned int rootpathlen; };
char * rootpath;
#define NFS4_PATHNAME_MAXCOMPONENTS 512
struct nfs4_pathname {
unsigned int ncomponents;
struct nfs4_string components[NFS4_PATHNAME_MAXCOMPONENTS];
};
#define NFS4_FS_LOCATION_MAXSERVERS 10
struct nfs4_fs_location {
unsigned int nservers;
struct nfs4_string servers[NFS4_FS_LOCATION_MAXSERVERS];
struct nfs4_pathname rootpath;
}; };
#define NFS_FS_LOCATIONS_MAXENTRIES 10 #define NFS4_FS_LOCATIONS_MAXENTRIES 10
struct nfs_fs_locations { struct nfs4_fs_locations {
struct nfs_fattr fattr; struct nfs_fattr fattr;
const struct nfs_server *server; const struct nfs_server *server;
unsigned int fs_pathlen; struct nfs4_pathname fs_path;
char * fs_path;
int nlocations; int nlocations;
struct nfs_fs_location locations[NFS_FS_LOCATIONS_MAXENTRIES]; struct nfs4_fs_location locations[NFS4_FS_LOCATIONS_MAXENTRIES];
}; };
struct nfs4_fs_locations_arg { struct nfs4_fs_locations_arg {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment