diff options
Diffstat (limited to 'xlators/mount/fuse')
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 49 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.h | 7 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-resolve.c | 113 | 
3 files changed, 153 insertions, 16 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 12d1104d14a..041997151c6 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -4150,18 +4150,21 @@ fuse_first_lookup (xlator_t *this)  int -fuse_nameless_lookup (xlator_t *xl, uuid_t gfid, loc_t *loc) +fuse_nameless_lookup (xlator_t *xl, uuid_t gfid, loc_t *loc, +                      gf_boolean_t resolve_path)  {          int          ret          = -1;          dict_t      *xattr_req    = NULL;          struct iatt  iatt         = {0, };          inode_t     *linked_inode = NULL; +        inode_t     *inode        = NULL; +        char        *path         = NULL; +        dict_t      *xattr_ret    = NULL;          if ((loc == NULL) || (xl == NULL)) {                  ret = -EINVAL;                  goto out;          } -          if (loc->inode == NULL) {                  loc->inode = inode_new (xl->itable);                  if (loc->inode == NULL) { @@ -4171,6 +4174,9 @@ fuse_nameless_lookup (xlator_t *xl, uuid_t gfid, loc_t *loc)          }          gf_uuid_copy (loc->gfid, gfid); +        if (gf_uuid_is_null (loc->gfid)) { +                goto out; +        }          xattr_req = dict_new ();          if (xattr_req == NULL) { @@ -4178,20 +4184,42 @@ fuse_nameless_lookup (xlator_t *xl, uuid_t gfid, loc_t *loc)                  goto out;          } -        ret = syncop_lookup (xl, loc, &iatt, NULL, xattr_req, NULL); +        if (resolve_path) { +                /* +                 * setting virtual xattr glusterfs.ancestry.path to get +                 * the path of the parent directory. +                 */ +                ret = dict_set_int32 (xattr_req, GET_ANCESTRY_PATH_KEY, 42); +                if (ret) +                        goto out; +        } + +        ret = syncop_lookup (xl, loc, &iatt, NULL, xattr_req, &xattr_ret);          if (ret < 0)                  goto out; -        linked_inode = inode_link (loc->inode, NULL, NULL, &iatt); -        inode_unref (loc->inode); -        loc->inode = linked_inode; - +        if (resolve_path) { +                ret = dict_get_str (xattr_ret, GET_ANCESTRY_PATH_KEY, &path); +        } +        if (path) { +                inode = loc->inode; +                loc->inode = fuse_resolve_path (xl, path); +                inode_unref (inode); +        } else { +                linked_inode = inode_link (loc->inode, NULL, NULL, &iatt); +                inode_unref (loc->inode); +                loc->inode = linked_inode; +        }          ret = 0;  out:          if (xattr_req != NULL) {                  dict_unref (xattr_req);          } +        if (xattr_ret) { +                dict_unref (xattr_ret); +        } +          return ret;  } @@ -4222,8 +4250,13 @@ fuse_migrate_fd_open (xlator_t *this, fd_t *basefd, fd_t *oldfd,          loc.inode = inode_find (new_subvol->itable, basefd->inode->gfid);          if (loc.inode == NULL) { + +                /* setting the get_resolve_path to send lookup +                 * on parent directories +                 * */ +                  ret = fuse_nameless_lookup (new_subvol, basefd->inode->gfid, -                                            &loc); +                                            &loc, _gf_true);                  if (ret < 0) {                          gf_log ("glusterfs-fuse", GF_LOG_WARNING,                                  "name-less lookup of gfid (%s) failed (%s)" diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h index bc5ea2cd4d3..01a7a971dd0 100644 --- a/xlators/mount/fuse/src/fuse-bridge.h +++ b/xlators/mount/fuse/src/fuse-bridge.h @@ -406,6 +406,9 @@ int fuse_flip_xattr_ns (struct fuse_private *priv, char *okey, char **nkey);  fuse_fd_ctx_t * __fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd);  fuse_fd_ctx_t * fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd); +inode_t* +fuse_resolve_path (xlator_t *this, char *path); +  int fuse_resolve_and_resume (fuse_state_t *state, fuse_resume_fn_t fn);  int fuse_resolve_inode_init (fuse_state_t *state, fuse_resolve_t *resolve,  			     ino_t ino); @@ -413,6 +416,10 @@ int fuse_resolve_entry_init (fuse_state_t *state, fuse_resolve_t *resolve,  			     ino_t par, char *name);  int fuse_resolve_fd_init (fuse_state_t *state, fuse_resolve_t *resolve,  			  fd_t *fd); +int +fuse_nameless_lookup (xlator_t *xl, uuid_t gfid, loc_t *loc, +                      gf_boolean_t resolve_path); +  int fuse_ignore_xattr_set (fuse_private_t *priv, char *key);  void fuse_fop_resume (fuse_state_t *state);  int dump_history_fuse (circular_buffer_t *cb, void *data); diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c index a670f4f6dac..474dace5c04 100644 --- a/xlators/mount/fuse/src/fuse-resolve.c +++ b/xlators/mount/fuse/src/fuse-resolve.c @@ -82,16 +82,36 @@ out:  int -fuse_resolve_entry (fuse_state_t *state) +fuse_resolve_entry (fuse_state_t *state, gf_boolean_t resolve_path)  { -	fuse_resolve_t   *resolve = NULL; -	loc_t            *resolve_loc = NULL; +        fuse_resolve_t   *resolve        = NULL; +        loc_t            *resolve_loc    = NULL; +        loc_t             tmp_loc        = {0, }; +        uuid_t            gfid           = {0, }; +        inode_t          *parent         = NULL;  	resolve = state->resolve_now;  	resolve_loc = &resolve->resolve_loc; -	resolve_loc->parent = inode_ref (state->loc_now->parent); +        parent = resolve->parhint ? resolve->parhint : resolve->hint; +  	gf_uuid_copy (resolve_loc->pargfid, state->loc_now->pargfid); + +        if (parent && parent->table != state->itable && resolve_path) { +		/* graph switch happened */ +                if (!gf_uuid_is_null (resolve->pargfid)) { +                        gf_uuid_copy (gfid, resolve->pargfid); +                } else if (!gf_uuid_is_null (resolve->gfid)) { +                        gf_uuid_copy (gfid, resolve->gfid); +                } + +                /* sending lookup on parent directories */ +                fuse_nameless_lookup (state->active_subvol, +                                      gfid, +                                      &tmp_loc, _gf_true); +        } + +        resolve_loc->parent = inode_ref (state->loc_now->parent);          resolve_loc->name = resolve->bname;          resolve_loc->inode = inode_new (state->itable); @@ -113,7 +133,7 @@ fuse_resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          fuse_state_t   *state      = NULL;          fuse_resolve_t *resolve    = NULL;          inode_t        *link_inode = NULL; -        loc_t          *loc_now   = NULL; +        loc_t          *loc_now    = NULL;          state = frame->root->state;          resolve = state->resolve_now; @@ -160,7 +180,7 @@ fuse_resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,  	loc_now->parent = link_inode;          gf_uuid_copy (loc_now->pargfid, link_inode->gfid); -	fuse_resolve_entry (state); +	fuse_resolve_entry (state, _gf_false);          return 0;  out: @@ -168,6 +188,73 @@ out:          return 0;  } +inode_t* +fuse_resolve_path (xlator_t *this, char *path) +{ +        int             ret             = -1; +        dict_t         *xattr_req       = NULL; +        struct iatt     iatt            = {0, }; +        inode_t        *linked_inode    = NULL; +        loc_t           loc             = {0, }; +        char           *bname           = NULL; +        char           *save_ptr        = NULL; +        uuid_t          gfid            = {0, }; +        char           *tmp_path        = NULL; + + +        tmp_path = gf_strdup (path); + +        memset (gfid, 0, 16); +        gfid[15] = 1; + +        gf_uuid_copy (loc.pargfid, gfid); +        loc.parent = inode_ref (this->itable->root); + +        xattr_req = dict_new (); +        if (xattr_req == NULL) { +                ret = -ENOMEM; +                goto out; +        } + +        bname = strtok_r (tmp_path, "/",  &save_ptr); + +        /* sending a lookup on parent directory, +         * Eg:  if  path is like /a/b/c/d/e/f/g/ +         * then we will send a lookup on a first and then b,c,d,etc +         */ + +        while (bname) { +                loc.inode = inode_grep (this->itable, loc.parent, bname); +                if (loc.inode == NULL) { +                        loc.inode = inode_new (this->itable); +                        if (loc.inode == NULL) { +                                ret = -ENOMEM; +                                goto out; +                        } +                } + +                loc.name = bname; +                ret = loc_path (&loc, bname); + +                ret = syncop_lookup (this, &loc, &iatt, NULL, xattr_req, NULL); +                if (ret) +                        goto out; + +                linked_inode = inode_link (loc.inode, loc.parent, bname, &iatt); +                if (!linked_inode) +                        goto out; + +                loc_wipe (&loc); +                gf_uuid_copy (loc.pargfid, linked_inode->gfid); +                loc.inode = NULL; +                loc.parent = linked_inode; + +                bname = strtok_r (NULL, "/",  &save_ptr); +        } +        return linked_inode; +out: +        return NULL; +}  int  fuse_resolve_gfid (fuse_state_t *state) @@ -175,10 +262,13 @@ fuse_resolve_gfid (fuse_state_t *state)          fuse_resolve_t *resolve  = NULL;          loc_t          *resolve_loc = NULL;          int             ret      = 0; +        loc_t           tmp_loc = {0, }; +        inode_t        *inode = NULL;          resolve = state->resolve_now;          resolve_loc = &resolve->resolve_loc; +          if (!gf_uuid_is_null (resolve->pargfid)) {                  gf_uuid_copy (resolve_loc->gfid, resolve->pargfid);          } else if (!gf_uuid_is_null (resolve->gfid)) { @@ -190,14 +280,21 @@ fuse_resolve_gfid (fuse_state_t *state)  	resolve_loc->inode = inode_find (state->itable, resolve_loc->gfid);  	if (!resolve_loc->inode)  		resolve_loc->inode = inode_new (state->itable); -	ret = loc_path (resolve_loc, NULL); +	ret = loc_path (resolve_loc, NULL);          if (ret <= 0) {                  gf_log (THIS->name, GF_LOG_WARNING,                          "failed to get the path for inode %s",                          uuid_utoa (resolve->gfid));          } +        inode = resolve->parhint ? resolve->parhint : resolve->hint; +        if (inode && inode->table != state->itable) { +                /* sending lookup on parent directories */ +                fuse_nameless_lookup (state->active_subvol, resolve_loc->gfid, +                                      &tmp_loc, _gf_true); +        } +          FUSE_FOP (state, fuse_resolve_gfid_cbk, GF_FOP_LOOKUP,                    lookup, resolve_loc, NULL); @@ -288,7 +385,7 @@ fuse_resolve_parent (fuse_state_t *state)          }  	if (ret < 0) { -		fuse_resolve_entry (state); +                fuse_resolve_entry (state, _gf_true);  		return 0;  	}  | 
