Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
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_network_partition_recovery_ops;
+2 −2
Original line number Diff line number Diff line
@@ -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,
		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);
	u32 bitmask[2] = {
@@ -3587,7 +3587,7 @@ int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry,
	struct rpc_message msg = {
		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
		.rpc_argp = &args,
		.rpc_resp = &fs_locations,
		.rpc_resp = fs_locations,
	};
	int status;

+71 −9
Original line number Diff line number Diff line
@@ -2377,7 +2377,43 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin
	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;
	uint32_t *p;
@@ -2388,7 +2424,8 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
	status = 0;
	if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS)))
		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))
		goto out;
	READ_BUF(4);
@@ -2397,15 +2434,40 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
		goto out_eio;
	res->nlocations = 0;
	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))
				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))
			goto out_eio;
		if (res->nlocations < NFS_FS_LOCATIONS_MAXENTRIES)
		if (res->nlocations < NFS4_FS_LOCATIONS_MAXENTRIES)
			res->nlocations++;
	}
out:
@@ -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)
		goto xdr_error;
	if ((status = decode_attr_fs_locations(xdr, bitmap, container_of(fattr,
						struct nfs_fs_locations,
						struct nfs4_fs_locations,
						fattr))) != 0)
		goto xdr_error;
	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
/*
 * 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 compound_hdr hdr;
+20 −10
Original line number Diff line number Diff line
@@ -679,21 +679,31 @@ struct nfs4_server_caps_res {
	u32				has_symlinks;
};

struct nfs_fs_location {
	unsigned int serverlen;
	char * server;
	unsigned int rootpathlen;
	char * rootpath;
struct nfs4_string {
	unsigned int len;
	char *data;
};

#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
struct nfs_fs_locations {
#define NFS4_FS_LOCATIONS_MAXENTRIES 10
struct nfs4_fs_locations {
	struct nfs_fattr fattr;
	const struct nfs_server *server;
	unsigned int fs_pathlen;
	char * fs_path;
	struct nfs4_pathname fs_path;
	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 {