-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;
- if (n == 0)
- goto root_path;
- 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;
-root_path:
-/* a root pathname is sent as a zero component4 */
- path->ncomponents = 1;
- path->components[0].len=0;
- path->components[0].data=NULL;
- dprintk("path /\n");
- goto out;
-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;
- int status = -EIO;
-
- if (unlikely(bitmap[0] & (FATTR4_WORD0_FS_LOCATIONS -1U)))
- goto out;
- status = 0;
- if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS)))
- goto out;
- dprintk("%s: fsroot ", __FUNCTION__);
- status = decode_pathname(xdr, &res->fs_path);
- if (unlikely(status != 0))
- goto out;
- READ_BUF(4);
- READ32(n);
- if (n <= 0)
- goto out_eio;
- res->nlocations = 0;
- while (res->nlocations < n) {
- int m;
- struct nfs4_fs_location *loc = &res->locations[res->nlocations];
-
- READ_BUF(4);
- READ32(m);
- if (m <= 0)
- goto out_eio;
-
- 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;
- 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 < NFS4_FS_LOCATIONS_MAXENTRIES)
- res->nlocations++;
- }
-out:
- dprintk("%s: fs_locations done, error = %d\n", __FUNCTION__, status);
- return status;
-out_eio:
- status = -EIO;
- goto out;
-}
-