diff options
Diffstat (limited to 'xlators/nfs/server/src/nfs3.c')
| -rw-r--r-- | xlators/nfs/server/src/nfs3.c | 467 | 
1 files changed, 349 insertions, 118 deletions
diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index 057ccb60e25..c4aaef3c308 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -67,11 +67,86 @@                  }                                                       \          } while (0);                                                    \ -#define nfs3_export_access(nfs3state, xlid) ((nfs3state)->exports[xlid]).access -#define nfs3_check_rw_volaccess(nfs3state, xlid, status, label)          \ -        do {                                                             \ -                if (nfs3_export_access (nfs3state,xlid)!=GF_NFS3_VOLACCESS_RW){\ +struct nfs3_export * +__nfs3_get_export_by_index (struct nfs3_state *nfs3, uuid_t exportid) +{ +        struct nfs3_export      *exp = NULL; +        int                     index = 0; +        int                     searchindex = 0; + +        searchindex = nfs3_fh_exportid_to_index (exportid); +        list_for_each_entry (exp, &nfs3->exports, explist) { +                if (searchindex == index) +                        goto found; + +                ++index; +        } + +        exp = NULL; +found: +        return exp; +} + + +struct nfs3_export * +__nfs3_get_export_by_volumeid (struct nfs3_state *nfs3, uuid_t exportid) +{ +        struct nfs3_export      *exp = NULL; + +        list_for_each_entry (exp, &nfs3->exports, explist) { +                if (!uuid_compare (exportid, exp->volumeid)) +                        goto found; +        } + +        exp = NULL; +found: +        return exp; +} + + +struct nfs3_export * +__nfs3_get_export_by_exportid (struct nfs3_state *nfs3, uuid_t exportid) +{ +        struct nfs3_export      *exp = NULL; + +        if (!nfs3) +                return exp; + +        if (gf_nfs_dvm_off (nfs_state(nfs3->nfsx))) +                exp = __nfs3_get_export_by_index (nfs3, exportid); +        else +                exp = __nfs3_get_export_by_volumeid (nfs3, exportid); + +        return exp; +} + + +int +nfs3_export_access (struct nfs3_state *nfs3, uuid_t exportid) +{ +        int                     ret = GF_NFS3_VOLACCESS_RO; +        struct nfs3_export      *exp = NULL; + +        if (!nfs3) +                return ret; + +        exp = __nfs3_get_export_by_exportid (nfs3, exportid); + +        if (!exp) { +                gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to get export by ID"); +                goto err; +        } + +        ret = exp->access; + +err: +        return ret; +} + +#define nfs3_check_rw_volaccess(nfs3state, exid, status, label)         \ +        do {                                                            \ +                if (nfs3_export_access (nfs3state,exid)!=GF_NFS3_VOLACCESS_RW){\                          gf_log (GF_NFS3, GF_LOG_TRACE, "No read-write access");\                          status = NFS3ERR_ROFS;                          \                          goto label;                                     \ @@ -80,9 +155,28 @@ +xlator_t * +nfs3_fh_to_xlator (struct nfs3_state *nfs3, struct nfs3_fh *fh) +{ +        xlator_t                *vol = NULL; +        struct nfs3_export      *exp = NULL; + +        if ((!nfs3) || (!fh)) +                return vol; + +        exp = __nfs3_get_export_by_exportid (nfs3, fh->exportid); +        if (!exp) +                goto out; + +        vol = exp->subvol; +out: +        return vol; +} + +  #define nfs3_map_fh_to_volume(nfs3state, handle, rqst, volume, status, label) \          do {                                                            \ -                volume = nfs3_fh_to_xlator ((nfs3state)->exportslist, handle); \ +                volume = nfs3_fh_to_xlator ((nfs3state), handle);       \                  if (!volume) {                                          \                          gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to map " \                                  "FH to vol");                           \ @@ -124,6 +218,29 @@          } while (0)                                                     \ +int +__nfs3_get_volume_id (struct nfs3_state *nfs3, xlator_t *xl, +                      uuid_t volumeid) +{ +        int                     ret = -1; +        struct nfs3_export      *exp = NULL; + +        if ((!nfs3) || (!xl)) +                return ret; + +        list_for_each_entry (exp, &nfs3->exports, explist) { +                if (exp->subvol == xl) { +                        uuid_copy (volumeid, exp->volumeid); +                        ret = 0; +                        goto out; +                } +        } + +out: +        return ret; +} + +  #define nfs3_funge_solaris_zerolen_fh(nfs3st, fhd, enam, nfsst, erl)    \          do {                                                            \                  xlator_t        *fungexl = NULL;                        \ @@ -133,16 +250,56 @@                          goto erl;                                       \                  }                                                       \                                                                          \ -                (fhd)->xlatorid = nfs_xlator_to_xlid ((nfs3st)->exportslist, \ -                                                      fungexl);         \ -                (fhd)->gen = 0;                                         \ -                (fhd)->ino = 1;                                         \ -                (enam) = NULL;                                          \ +                if ((gf_nfs_dvm_off (nfs_state (nfs3st->nfsx)))) {      \ +                        (fhd)->exportid[15] = nfs_xlator_to_xlid ((nfs3st)->exportslist, fungexl);                                                 \ +                        (fhd)->gfid[15] = 1;                            \ +                        (enam) = NULL;                                  \ +                } else {                                                \ +                        if(!__nfs3_get_volume_id ((nfs3st), fungexl, (fhd)->exportid)) { \ +                                (nfsst) = NFS3ERR_STALE;                \ +                                goto erl;                               \ +                        }                                               \ +                }                                                       \          } while (0)                                                     \ -#define nfs3_export_sync_trusted(nf3stt, xlid) ((nf3stt)->exports[xlid]).trusted_sync -#define nfs3_export_write_trusted(nf3stt, xlid) ((nf3stt)->exports[xlid]).trusted_write + +int +nfs3_export_sync_trusted (struct nfs3_state *nfs3, uuid_t exportid) +{ +        struct nfs3_export      *exp = NULL; +        int                     ret = 0; + +        if (!nfs3) +                return ret; + +        exp = __nfs3_get_export_by_exportid (nfs3, exportid); +        if (!exp) +                goto err; + +        ret = exp->trusted_sync; +err: +        return ret; +} + + +int +nfs3_export_write_trusted (struct nfs3_state *nfs3, uuid_t exportid) +{ +        struct nfs3_export      *exp = NULL; +        int                     ret = 0; + +        if (!nfs3) +                return ret; + +        exp = __nfs3_get_export_by_exportid (nfs3, exportid); +        if (!exp) +                goto err; + +        ret = exp->trusted_write; +err: +        return ret; +}  int  nfs3_solaris_zerolen_fh (struct nfs3_fh *fh, int fhlen) @@ -355,18 +512,27 @@ err:  } -uint16_t -nfs3_request_xlator_id (rpcsvc_request_t *rq) +uint64_t +nfs3_request_xlator_deviceid (rpcsvc_request_t *rq)  {          struct nfs3_state       *nfs3 = NULL;          xlator_t                *xl = NULL; +        uint64_t                devid = 0; +        uuid_t                  volumeid = {0, };          if (!rq)                  return 0;          xl = nfs_rpcsvc_request_private (rq);          nfs3 = nfs_rpcsvc_request_program_private (rq); -        return nfs_xlator_to_xlid (nfs3->exportslist, xl); +        if (gf_nfs_dvm_off (nfs_state (nfs3->nfsx))) +                devid = (uint64_t)nfs_xlator_to_xlid (nfs3->exportslist, xl); +        else { +                __nfs3_get_volume_id (nfs3, xl, volumeid); +                memcpy (&devid, &volumeid[15], sizeof (devid)); +        } + +        return devid;  } @@ -386,10 +552,10 @@ int  nfs3_getattr_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *buf)  {          getattr3res     res; -        uint16_t        xlid = 0; +        uint64_t        deviceid = 0; -        xlid = nfs3_request_xlator_id (req); -        nfs3_fill_getattr3res (&res, status, buf, xlid); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_getattr3res (&res, status, buf, deviceid);          nfs3svc_submit_reply (req, &res,                                (nfs3_serializer)xdr_serialize_getattr3res); @@ -558,10 +724,10 @@ nfs3_setattr_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preop,                      struct iatt *postop)  {          setattr3res     res = {0, }; -        uint16_t        xlid = 0; +        uint64_t        deviceid = 0; -        xlid = nfs3_request_xlator_id (req); -        nfs3_fill_setattr3res (&res, stat, preop, postop, xlid); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_setattr3res (&res, stat, preop, postop, deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer) xdr_serialize_setattr3res);          return 0; @@ -761,7 +927,7 @@ nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr,          nfs3_validate_gluster_fh (fh, stat, nfs3err);          nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);          nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); -        nfs3_check_rw_volaccess (nfs3, fh->xlatorid, stat, nfs3err); +        nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);          nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);          cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf, @@ -837,8 +1003,10 @@ nfs3_lookup_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *newfh,                     struct iatt *stbuf, struct iatt *postparent)  {          lookup3res      res = {0, }; +        uint64_t        deviceid = 0; -        nfs3_fill_lookup3res (&res, stat, newfh, stbuf, postparent); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_lookup3res (&res, stat, newfh, stbuf, postparent, deviceid);          return nfs3svc_submit_reply (req, &res,                                       (nfs3_serializer)xdr_serialize_lookup3res);  } @@ -880,6 +1048,8 @@ nfs3svc_lookup_parentdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          struct nfs3_fh                  newfh = {{0}, };          nfsstat3                        status = NFS3_OK;          nfs3_call_state_t               *cs = NULL; +        uuid_t                          volumeid = {0, }; +        struct nfs3_state               *nfs3 = NULL;          cs = frame->local;          if (op_ret == -1) { @@ -887,15 +1057,23 @@ nfs3svc_lookup_parentdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto xmit_res;          } +        nfs3 = cs->nfs3state;          /* If the buf inode shows that this is a root dir's buf, then the file           * handle needs to be specially crafted, in all other cases, we'll just           * create the handle normally using the buffer of the parent dir.           */ -        if (buf->ia_ino != 1) +        if (buf->ia_ino != 1) {                  nfs3_fh_build_parent_fh (&cs->fh, buf, &newfh); -        else -                newfh = nfs3_fh_build_root_fh (cs->nfs3state->exportslist, -                                               cs->vol); +                goto xmit_res; +        } + +        if (gf_nfs_dvm_off (nfs_state (nfs3->nfsx))) +                newfh = nfs3_fh_build_indexed_root_fh (nfs3->exportslist, +                                                       cs->vol); +        else { +                __nfs3_get_volume_id (nfs3, cs->vol, volumeid); +                newfh = nfs3_fh_build_uuid_root_fh (volumeid); +        }  xmit_res:          nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP", status, @@ -1095,13 +1273,12 @@ nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *buf,                     uint32_t accbits)  {          access3res      res; -        uint16_t        xlid = 0; +        uint64_t        deviceid = 0; -        xlid = nfs3_request_xlator_id (req); +        deviceid = nfs3_request_xlator_deviceid (req);          nfs3_fill_access3res (&res, status, buf, accbits,                                nfs_rpcsvc_request_uid (req), -                              nfs_rpcsvc_request_gid (req) -                              , xlid); +                              nfs_rpcsvc_request_gid (req), deviceid);          nfs3svc_submit_reply (req, &res,                                (nfs3_serializer)xdr_serialize_access3res);          return 0; @@ -1231,10 +1408,10 @@ nfs3_readlink_reply (rpcsvc_request_t *req, nfsstat3 stat, char *path,                       struct iatt *buf)  {          readlink3res    res = {0, }; -        uint16_t        xlid = 0; +        uint64_t        deviceid = 0; -        xlid = nfs3_request_xlator_id (req); -        nfs3_fill_readlink3res (&res, stat, path, buf, xlid); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_readlink3res (&res, stat, path, buf, deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer)xdr_serialize_readlink3res); @@ -1374,10 +1551,10 @@ nfs3_read_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count,                   struct iatt *poststat, int is_eof)  {          read3res                res = {0, }; -        uint16_t                xlid = 0; +        uint64_t                deviceid = 0; -        xlid = nfs3_request_xlator_id (req); -        nfs3_fill_read3res (&res, stat, count, poststat, is_eof, xlid); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_read3res (&res, stat, count, poststat, is_eof, deviceid);          if (stat == NFS3_OK) {                  nfs_xdr_vector_round_up (vec, vcount, count);                  /* iob can be zero if the file size was zero. If so, op_ret @@ -1564,11 +1741,11 @@ nfs3_write_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count,                    struct iatt *poststat)  {          write3res       res = {0, }; -        uint16_t        xlid = 0; +        uint64_t        deviceid = 0; -        xlid = nfs3_request_xlator_id (req); +        deviceid = nfs3_request_xlator_deviceid (req);          nfs3_fill_write3res (&res, stat, count, stable, wverf, prestat, -                             poststat, xlid); +                             poststat, deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer)xdr_serialize_write3res); @@ -1692,9 +1869,9 @@ nfs3svc_write_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          cs->maxcount = op_ret;          write_trusted = nfs3_export_write_trusted (cs->nfs3state, -                                                   cs->resolvefh.xlatorid); +                                                   cs->resolvefh.exportid);          sync_trusted = nfs3_export_sync_trusted (cs->nfs3state, -                                                 cs->resolvefh.xlatorid); +                                                 cs->resolvefh.exportid);          ret = nfs3_write_how (&cs->writetype, write_trusted, sync_trusted);          if (ret == -1)                  goto err; @@ -1831,7 +2008,7 @@ nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,          nfs3_validate_gluster_fh (fh, stat, nfs3err);          nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);          nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); -        nfs3_check_rw_volaccess (nfs3, fh->xlatorid, stat, nfs3err); +        nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);          nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);          cs->datacount = count;          cs->dataoffset = offset; @@ -1983,8 +2160,11 @@ nfs3_create_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *newfh,                     struct iatt *postparent)  {          create3res      res = {0, }; +        uint64_t        deviceid = 0; -        nfs3_fill_create3res (&res, stat, newfh, newbuf, preparent, postparent); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_create3res (&res, stat, newfh, newbuf, preparent, postparent, +                              deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer)xdr_serialize_create3res);          return 0; @@ -2219,7 +2399,7 @@ nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,          nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);          nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret);          nfs3_map_fh_to_volume (nfs3, dirfh, req, vol, stat, nfs3err); -        nfs3_check_rw_volaccess (nfs3, dirfh->xlatorid, stat, nfs3err); +        nfs3_check_rw_volaccess (nfs3, dirfh->exportid, stat, nfs3err);          nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);          cs->cookieverf = cverf; @@ -2284,8 +2464,11 @@ nfs3_mkdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh,                    struct iatt *postparent)  {          mkdir3res       res = {0, }; +        uint64_t        deviceid = 0; -        nfs3_fill_mkdir3res (&res, stat, fh, buf, preparent, postparent); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_mkdir3res (&res, stat, fh, buf, preparent, postparent, +                             deviceid);          nfs3svc_submit_reply (req, &res,                                (nfs3_serializer)xdr_serialize_mkdir3res);          return 0; @@ -2423,7 +2606,7 @@ nfs3_mkdir (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,          nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);          nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret);          nfs3_map_fh_to_volume (nfs3, dirfh, req, vol, stat, nfs3err); -        nfs3_check_rw_volaccess (nfs3, dirfh->xlatorid, stat, nfs3err); +        nfs3_check_rw_volaccess (nfs3, dirfh->exportid, stat, nfs3err);          nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);          cs->parent = *dirfh; @@ -2481,8 +2664,11 @@ nfs3_symlink_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh,                      struct iatt *postparent)  {          symlink3res     res = {0, }; +        uint64_t        deviceid = 0; -        nfs3_fill_symlink3res (&res, stat, fh, buf, preparent, postparent); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_symlink3res (&res, stat, fh, buf, preparent, postparent, +                               deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer)xdr_serialize_symlink3res); @@ -2570,7 +2756,7 @@ nfs3_symlink (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,          nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);          nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret);          nfs3_map_fh_to_volume (nfs3, dirfh, req, vol, stat, nfs3err); -        nfs3_check_rw_volaccess (nfs3, dirfh->xlatorid, stat, nfs3err); +        nfs3_check_rw_volaccess (nfs3, dirfh->exportid, stat, nfs3err);          nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);          cs->parent = *dirfh; @@ -2638,7 +2824,11 @@ nfs3_mknod_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh,                    struct iatt *postparent)  {          mknod3res       res = {0, }; -        nfs3_fill_mknod3res (&res, stat, fh, buf, preparent, postparent); +        uint64_t        deviceid = 0; + +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_mknod3res (&res, stat, fh, buf, preparent, postparent, +                             deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer)xdr_serialize_mknod3res); @@ -2838,7 +3028,7 @@ nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name,          nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);          nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret);          nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); -        nfs3_check_rw_volaccess (nfs3, fh->xlatorid, stat, nfs3err); +        nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);          nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);          cs->mknodtype = nodedata->type; @@ -2915,10 +3105,10 @@ nfs3_remove_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preparent                     , struct iatt *postparent)  {          remove3res      res = {0, }; -        uint16_t        xlid = 0; +        uint64_t        deviceid = 0; -        xlid = nfs3_request_xlator_id (req); -        nfs3_fill_remove3res (&res, stat, preparent, postparent, xlid); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_remove3res (&res, stat, preparent, postparent, deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer)xdr_serialize_remove3res);          return 0; @@ -3037,7 +3227,7 @@ nfs3_remove (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name)          nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);          nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret);          nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); -        nfs3_check_rw_volaccess (nfs3, fh->xlatorid, stat, nfs3err); +        nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);          nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);          ret = nfs3_fh_resolve_and_resume (cs, fh, name, nfs3_remove_resume); @@ -3094,10 +3284,10 @@ nfs3_rmdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preparent,                    struct iatt *postparent)  {          rmdir3res       res = {0, }; -        uint16_t        xlid = 0; +        uint64_t        deviceid = 0; -        xlid = nfs3_request_xlator_id (req); -        nfs3_fill_rmdir3res (&res, stat, preparent, postparent, xlid); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_rmdir3res (&res, stat, preparent, postparent, deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer)xdr_serialize_rmdir3res);          return 0; @@ -3180,7 +3370,7 @@ nfs3_rmdir (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name)          nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);          nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret);          nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); -        nfs3_check_rw_volaccess (nfs3, fh->xlatorid, stat, nfs3err); +        nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);          nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);          ret = nfs3_fh_resolve_and_resume (cs, fh, name, nfs3_rmdir_resume); @@ -3238,11 +3428,11 @@ nfs3_rename_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *buf,                     struct iatt *prenewparent, struct iatt *postnewparent)  {          rename3res      res = {0, }; -        uint16_t        xlid = 0; +        uint64_t        deviceid = 0; -        xlid = nfs3_request_xlator_id (req); +        deviceid = nfs3_request_xlator_deviceid (req);          nfs3_fill_rename3res (&res, stat, buf, preoldparent, postoldparent, -                              prenewparent, postnewparent, xlid); +                              prenewparent, postnewparent, deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer) xdr_serialize_rename3res); @@ -3383,7 +3573,7 @@ nfs3_rename (rpcsvc_request_t *req, struct nfs3_fh *olddirfh, char *oldname,          nfs3_validate_strlen_or_goto(oldname, NFS_NAME_MAX, nfs3err, stat, ret);          nfs3_validate_strlen_or_goto(newname, NFS_NAME_MAX, nfs3err, stat, ret);          nfs3_map_fh_to_volume (nfs3, olddirfh, req, vol, stat, nfs3err); -        nfs3_check_rw_volaccess (nfs3, olddirfh->xlatorid, stat, nfs3err); +        nfs3_check_rw_volaccess (nfs3, olddirfh->exportid, stat, nfs3err);          nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);          /* While we resolve the source (fh, name) pair, we need to keep a copy @@ -3454,10 +3644,10 @@ nfs3_link_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *buf,                   struct iatt *preparent, struct iatt *postparent)  {          link3res        res = {0, }; -        uint16_t        xlid = 0; +        uint64_t        deviceid = 0; -        xlid = nfs3_request_xlator_id (req); -        nfs3_fill_link3res (&res, stat, buf, preparent, postparent, xlid); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_link3res (&res, stat, buf, preparent, postparent, deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer)xdr_serialize_link3res); @@ -3572,7 +3762,7 @@ nfs3_link (rpcsvc_request_t *req, struct nfs3_fh *targetfh,          nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);          nfs3_validate_strlen_or_goto(newname, NFS_NAME_MAX, nfs3err, stat, ret);          nfs3_map_fh_to_volume (nfs3, dirfh, req, vol, stat, nfs3err); -        nfs3_check_rw_volaccess (nfs3, dirfh->xlatorid, stat, nfs3err); +        nfs3_check_rw_volaccess (nfs3, dirfh->exportid, stat, nfs3err);          nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);          cs->fh = *dirfh; @@ -3638,10 +3828,12 @@ nfs3_readdirp_reply (rpcsvc_request_t *req, nfsstat3 stat,struct nfs3_fh *dirfh,                       uint64_t cverf, struct iatt *dirstat, gf_dirent_t *entries,                       count3 dircount, count3 maxcount, int is_eof)  { -        readdirp3res     res = {0, }; +        readdirp3res    res = {0, }; +        uint64_t        deviceid = 0; +        deviceid = nfs3_request_xlator_deviceid (req);          nfs3_fill_readdirp3res (&res, stat, dirfh, cverf, dirstat, entries, -                                dircount, maxcount, is_eof); +                                dircount, maxcount, is_eof, deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer) xdr_serialize_readdirp3res);          nfs3_free_readdirp3res (&res); @@ -3656,9 +3848,11 @@ nfs3_readdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *dirfh,                      count3 count, int is_eof)  {          readdir3res     res = {0, }; +        uint64_t        deviceid = 0; +        deviceid = nfs3_request_xlator_deviceid (req);          nfs3_fill_readdir3res (&res, stat, dirfh, cverf, dirstat, entries, count -                               , is_eof); +                               , is_eof, deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer) xdr_serialize_readdir3res);          nfs3_free_readdir3res (&res); @@ -3987,10 +4181,10 @@ nfs3_fsstat_reply (rpcsvc_request_t *req, nfsstat3 stat, struct statvfs *fsbuf,                     struct iatt *postbuf)  {          fsstat3res      res = {0, }; -        uint16_t        xlid = 0; +        uint64_t        deviceid = 0; -        xlid = nfs3_request_xlator_id (req); -        nfs3_fill_fsstat3res (&res, stat, fsbuf, postbuf, xlid); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_fsstat3res (&res, stat, fsbuf, postbuf, deviceid);          return nfs3svc_submit_reply (req, &res,                                       (nfs3_serializer)xdr_serialize_fsstat3res); @@ -4162,11 +4356,11 @@ nfs3_fsinfo_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *fsroot)  {          fsinfo3res              res;          struct nfs3_state       *nfs3 = NULL; -        uint16_t                xlid = 0; +        uint64_t                deviceid = 0; -        xlid = nfs3_request_xlator_id (req); +        deviceid = nfs3_request_xlator_deviceid (req);          nfs3 = nfs_rpcsvc_request_program_private (req); -        nfs3_fill_fsinfo3res (nfs3, &res, status, fsroot, xlid); +        nfs3_fill_fsinfo3res (nfs3, &res, status, fsroot, deviceid);          nfs3svc_submit_reply (req, &res,                                (nfs3_serializer)xdr_serialize_fsinfo3res); @@ -4301,10 +4495,10 @@ int  nfs3_pathconf_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *buf)  {          pathconf3res    res = {0, }; -        uint16_t        xlid = 0; +        uint64_t        deviceid = 0; -        xlid = nfs3_request_xlator_id (req); -        nfs3_fill_pathconf3res (&res, stat, buf, xlid); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_pathconf3res (&res, stat, buf, deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer)xdr_serialize_pathconf3res);          return 0; @@ -4440,10 +4634,10 @@ nfs3_commit_reply (rpcsvc_request_t *req, nfsstat3 stat, uint64_t wverf,                     struct iatt *prestat, struct iatt *poststat)  {          commit3res      res = {0, }; -        uint16_t        xlid = 0; +        uint64_t        deviceid = 0; -        xlid = nfs3_request_xlator_id (req); -        nfs3_fill_commit3res (&res, stat, wverf, prestat, poststat, xlid); +        deviceid = nfs3_request_xlator_deviceid (req); +        nfs3_fill_commit3res (&res, stat, wverf, prestat, poststat, deviceid);          nfs3svc_submit_reply (req, (void *)&res,                                (nfs3_serializer)xdr_serialize_commit3res); @@ -4489,7 +4683,7 @@ nfs3_commit_resume (void *carg)          cs = (nfs3_call_state_t *)carg;          nfs3_check_fh_resolve_status (cs, stat, nfs3err); -        if (nfs3_export_sync_trusted (cs->nfs3state, cs->resolvefh.xlatorid)) { +        if (nfs3_export_sync_trusted (cs->nfs3state, cs->resolvefh.exportid)) {                  ret = -1;                  stat = NFS3_OK;                  goto nfs3err; @@ -4564,7 +4758,7 @@ nfs3_commit (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,          nfs3_validate_gluster_fh (fh, stat, nfs3err);          nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);          nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); -        nfs3_check_rw_volaccess (nfs3, fh->xlatorid, stat, nfs3err); +        nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);          nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);          cs->datacount = count; @@ -4753,18 +4947,60 @@ err:          return ret;  } +  int -nfs3_init_subvolume_options (struct nfs3_export *exp, dict_t *options) +nfs3_init_subvolume_options (struct nfs3_state *nfs3, struct nfs3_export *exp)  {          int             ret = -1;          char            *optstr = NULL;          char            searchkey[1024];          char            *name = NULL;          gf_boolean_t    boolt = _gf_false; +        uuid_t          volumeid = {0, }; +        dict_t          *options = NULL; -        if ((!exp) || (!options)) +        if ((!exp) || (!nfs3))                  return -1; +        options = nfs3->nfsx->options; +        uuid_clear (volumeid); +        if (gf_nfs_dvm_off (nfs_state (nfs3->nfsx))) +                goto no_dvm; + +        ret = snprintf (searchkey, 1024, "nfs3.%s.volume-id",exp->subvol->name); +        if (ret < 0) { +                gf_log (GF_MNT, GF_LOG_ERROR, "snprintf failed"); +                ret = -1; +                goto err; +        } + +        if (dict_get (options, searchkey)) { +                ret = dict_get_str (options, searchkey, &optstr); +                if (ret < 0) { +                        gf_log (GF_MNT, GF_LOG_ERROR, "Failed to read option" +                                ": %s", searchkey); +                        ret = -1; +                        goto err; +                } +        } else { +                gf_log (GF_MNT, GF_LOG_ERROR, "DVM is on but volume-id not " +                        "given for volume: %s", exp->subvol->name); +                ret = -1; +                goto err; +        } + +        if (optstr) { +                ret = uuid_parse (optstr, volumeid); +                if (ret < 0) { +                        gf_log (GF_MNT, GF_LOG_ERROR, "Failed to parse volume " +                                "UUID"); +                        ret = -1; +                        goto err; +                } +                uuid_copy (exp->volumeid, volumeid); +        } + +no_dvm:          /* Volume Access */          name = exp->subvol->name;          ret = snprintf (searchkey, 1024, "nfs3.%s.volume-access", name); @@ -4880,64 +5116,58 @@ err:  } -int -nfs3_init_subvolume (struct nfs3_state *nfs3, xlator_t *nfsx, xlator_t *subvol, -                     int xlid) +struct nfs3_export * +nfs3_init_subvolume (struct nfs3_state *nfs3, xlator_t *subvol)  {          int                     ret = -1;          struct nfs3_export      *exp = NULL; -        if ((!nfs3) || (!nfsx) || (!subvol)) -                return -1; +        if ((!nfs3) || (!subvol)) +                return NULL; -        exp = &nfs3->exports[xlid]; +        exp = GF_CALLOC (1, sizeof (*exp), gf_nfs_mt_nfs3_export);          exp->subvol = subvol; - +        INIT_LIST_HEAD (&exp->explist);          gf_log (GF_NFS3, GF_LOG_TRACE, "Initing state: %s", exp->subvol->name); -        ret = nfs3_init_subvolume_options (exp, nfsx->options); -        if (ret == -1) +        ret = nfs3_init_subvolume_options (nfs3, exp); +        if (ret == -1) {                  gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init subvol"); +                goto exp_free; +        } -        return ret; +        ret = 0; +exp_free: +        if (ret < 0) { +                GF_FREE (exp); +                exp = NULL; +        } + +        return exp;  }  int -nfs3_init_subvolumes (struct nfs3_state *nfs3, xlator_t *nfsx) +nfs3_init_subvolumes (struct nfs3_state *nfs3)  { -        int                     xl_count = 0;          int                     ret = -1;          struct xlator_list      *xl_list = NULL; +        struct nfs3_export      *exp = NULL; -        if ((!nfs3) || (!nfsx)) +        if (!nfs3)                  return -1; -        xl_list = nfsx->children; -        while (xl_list) { -                ++xl_count; -                xl_list = xl_list->next; -        } +        xl_list = nfs3->nfsx->children; -        nfs3->exports = GF_CALLOC (xl_count, sizeof (struct nfs3_export), -                                   gf_nfs_mt_nfs3_export); -        if (!nfs3->exports) { -                gf_log (GF_NFS3, GF_LOG_ERROR, "Memory allocation failed"); -                goto err; -        } - -        xl_list = nfsx->children; -        xl_count = 0;           /* Re-using xl_count. */          while (xl_list) { -                ret = nfs3_init_subvolume (nfs3, nfsx, xl_list->xlator, -                                           xl_count); -                if (ret == -1) { +                exp = nfs3_init_subvolume (nfs3, xl_list->xlator); +                if (!exp) {                          gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init subvol: "                                  "%s", xl_list->xlator->name);                          goto err;                  } +                list_add_tail (&exp->explist, &nfs3->exports);                  xl_list = xl_list->next; -                ++xl_count;          }          ret = 0; @@ -4983,7 +5213,8 @@ nfs3_init_state (xlator_t *nfsx)          nfs3->nfsx = nfsx;          nfs3->exportslist = nfsx->children; -        ret = nfs3_init_subvolumes (nfs3, nfsx); +        INIT_LIST_HEAD (&nfs3->exports); +        ret = nfs3_init_subvolumes (nfs3);          if (ret == -1) {                  gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init per-subvolume "                          "state");  | 
