diff options
| author | Anand Avati <avati@redhat.com> | 2012-01-30 15:03:56 +0530 | 
|---|---|---|
| committer | Anand Avati <avati@gluster.com> | 2012-02-08 03:13:08 -0800 | 
| commit | 8e81cbacc53adc77bc4eabb5a26d6d13012f5f86 (patch) | |
| tree | 4788e3a14fb2d276689c4423cc7542f0d72c3348 | |
| parent | aec6d5d89249868dc99d8fb432d8ab120bb38ef1 (diff) | |
fuse: fix resolver to handle graph switches properly
perform resolution on the latest graph by caching it in state->itable
and use fuse_nodeid as just a hint to the possible final resolved inode
(in case it was resolved off the latest graph). GFID is the primary key
for resolving inodes on the latest graph.
Change-Id: I3921c6f59c9ff80e4ff076bec3bd334423fc36cc
BUG: 785675
Reviewed-on: http://review.gluster.com/2703
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Amar Tumballi <amar@gluster.com>
Reviewed-by: Anand Avati <avati@gluster.com>
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 784 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.h | 36 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-helpers.c | 60 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-resolve.c | 431 | 
4 files changed, 544 insertions, 767 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 72bb1b157..6537c0bcc 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -199,6 +199,7 @@ send_fuse_err (xlator_t *this, fuse_in_header_t *finh, int error)          return send_fuse_iov (this, finh, &iov_out, 1);  } +  static int  fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  int32_t op_ret, int32_t op_errno, @@ -303,7 +304,7 @@ fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          prev  = cookie;          if (op_ret == -1 && state->is_revalidate == 1) { -                itable = state->loc.inode->table; +                itable = state->itable;                  inode_unref (state->loc.inode);                  state->loc.inode = inode_new (itable);                  state->is_revalidate = 2; @@ -357,28 +358,10 @@ fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg)          GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name); -        if (!state->loc.parent || (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": LOOKUP %"PRIu64"/%s (fuse_loc_fill() failed)", -                        finh->unique, finh->nodeid, name); -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } - -        if (state->loc.inode) { -                uuid_copy (state->resolve.gfid, state->loc.inode->gfid); -        } else { -                uuid_generate (state->gfid); -        } - -        uuid_copy (state->resolve.pargfid, state->loc.parent->gfid); -        state->resolve.bname = gf_strdup (name); -        state->resolve.path = gf_strdup (state->loc.path); +        ret = fuse_resolve_entry_init (state, &state->resolve, +				       finh->nodeid, name);          fuse_resolve_and_resume (state, fuse_lookup_resume); -  } @@ -529,7 +512,21 @@ fuse_root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,  void  fuse_getattr_resume (fuse_state_t *state)  { -        if (!state->fd || IA_ISDIR (state->loc.inode->ia_type)) { +        if (!state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_ERROR, +                        "%"PRIu64": GETATTR %"PRIu64" (%s) resolution failed", +                        state->finh->unique, state->finh->nodeid, +			uuid_utoa (state->resolve.gfid)); +                send_fuse_err (state->this, state->finh, ENOENT); +                free_fuse_state (state); +                return; +        } + +	if (!IA_ISDIR (state->loc.inode->ia_type)) { +		state->fd = fd_lookup (state->loc.inode, state->finh->pid); +	} + +        if (!state->fd) {                  gf_log ("glusterfs-fuse", GF_LOG_TRACE,                          "%"PRIu64": GETATTR %"PRIu64" (%s)",                          state->finh->unique, state->finh->nodeid, @@ -553,7 +550,6 @@ static void  fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg)  {          fuse_state_t *state; -        fd_t         *fd = NULL;          int32_t       ret = -1;          GET_STATE (this, finh, state); @@ -578,41 +574,7 @@ fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg)                  return;          } -        ret = fuse_loc_fill (&state->loc, state, state->finh->nodeid, 0, NULL); - -        if (!state->loc.inode) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": GETATTR %"PRIu64" (%s) (fuse_loc_fill() returned NULL inode)", -                        state->finh->unique, state->finh->nodeid, state->loc.path); -                send_fuse_err (state->this, state->finh, ENOENT); -                free_fuse_state (state); -                return; -        } - -        fd = fd_lookup (state->loc.inode, state->finh->pid); -        state->fd = fd; -        if (!fd || IA_ISDIR (state->loc.inode->ia_type)) { -                /* this is the @ret of fuse_loc_fill, checked here -                   to permit fstat() to happen even when fuse_loc_fill fails -                */ -                if (ret < 0) { -                        gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                                "%"PRIu64": GETATTR %"PRIu64" (fuse_loc_fill() failed)", -                                state->finh->unique, state->finh->nodeid); -                        send_fuse_err (state->this, state->finh, ENOENT); -                        free_fuse_state (state); -                        return; -                } - -                if (state->fd) -                        fd_unref (state->fd); - -                state->fd = NULL; -        } - -        uuid_copy (state->resolve.gfid, state->loc.inode->gfid); -        if (state->loc.path) -                state->resolve.path = gf_strdup (state->loc.path); +        fuse_resolve_inode_init (state, &state->resolve, state->finh->nodeid);          fuse_resolve_and_resume (state, fuse_getattr_resume);  } @@ -855,6 +817,26 @@ fattr_to_gf_set_attr (int32_t valid)  void  fuse_setattr_resume (fuse_state_t *state)  { +        if (!state->fd && !state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_ERROR, +                        "%"PRIu64": SETATTR %"PRIu64" (%s) resolution failed", +                        state->finh->unique, state->finh->nodeid, +			uuid_utoa (state->resolve.gfid)); +                send_fuse_err (state->this, state->finh, ENOENT); +                free_fuse_state (state); +                return; +        } + +        gf_log ("glusterfs-fuse", GF_LOG_TRACE, +                "%"PRIu64": SETATTR (%"PRIu64")%s", state->finh->unique, +                state->finh->nodeid, state->loc.path); + +#ifdef GF_TEST_FFOP +        /* this is for calls like 'fchmod()' */ +        if (!state->fd) +                state->fd = fd_lookup (state->loc.inode, state->finh->pid); +#endif /* GF_TEST_FFOP */ +          if ((state->valid & (FATTR_MASK)) != FATTR_SIZE) {                  if (state->fd &&                      !((state->valid & FATTR_ATIME) || @@ -885,18 +867,18 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)          fuse_private_t  *priv = NULL;          fuse_state_t *state = NULL; -        int32_t       ret   = -1;          GET_STATE (this, finh, state);          if (fsi->valid & FATTR_FH && -            !(fsi->valid & (FATTR_ATIME|FATTR_MTIME))) +            !(fsi->valid & (FATTR_ATIME|FATTR_MTIME))) {                  /* We need no loc if kernel sent us an fd and                   * we are not fiddling with times */ -                ret = 1; -        else -                ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, -                                     NULL); +                state->fd = FH_TO_FD (fsi->fh); +		fuse_resolve_fd_init (state, &state->resolve, state->fd); +	} else { +		fuse_resolve_inode_init (state, &state->resolve, finh->nodeid); +	}          /*           * This is just stub code demonstrating how to retrieve @@ -919,41 +901,6 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)          state->valid = fsi->valid; -        if (fsi->valid & FATTR_FH) { -                state->fd = FH_TO_FD (fsi->fh); -        } - -#ifdef GF_TEST_FFOP -        /* this is for calls like 'fchmod()' */ -        if (!state->fd) -                state->fd = fd_lookup (state->loc.inode, state->finh->pid); -#endif /* GF_TEST_FFOP */ - -        /* It is possible to get ftruncate without proper inode info from fuse */ -        if (ret && !state->fd) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": SETATTR %s (fuse_loc_fill() failed (%d))", -                        finh->unique, state->loc.path, ret); - -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); - -                return; -        } - -        if (!state->fd && !state->loc.inode) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": SETATTR %"PRIu64" (fuse_loc_fill() failed)", -                        state->finh->unique, state->finh->nodeid); -                send_fuse_err (state->this, state->finh, ENOENT); -                free_fuse_state (state); -                return; -        } - -        gf_log ("glusterfs-fuse", GF_LOG_TRACE, -                "%"PRIu64": SETATTR (%"PRIu64")%s", finh->unique, -                finh->nodeid, state->loc.path); -          if ((fsi->valid & (FATTR_MASK)) != FATTR_SIZE) {                  if (fsi->valid & FATTR_SIZE) {                          state->size            = fsi->size; @@ -973,11 +920,6 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)                  state->size = fsi->size;          } -        if (!state->fd) { -                uuid_copy (state->resolve.gfid, state->loc.inode->gfid); -                state->resolve.path = gf_strdup (state->loc.path); -        } -          fuse_resolve_and_resume (state, fuse_setattr_resume);  } @@ -1074,9 +1016,20 @@ fuse_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          return 0;  } +  void  fuse_access_resume (fuse_state_t *state)  { +        if (!state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_ERROR, +                        "%"PRIu64": ACCESS %"PRIu64" (%s) resolution failed", +                        state->finh->unique, state->finh->nodeid, +			uuid_utoa (state->resolve.gfid)); +                send_fuse_err (state->this, state->finh, ENOENT); +                free_fuse_state (state); +                return; +        } +          gf_log ("glusterfs-fuse", GF_LOG_TRACE,                  "%"PRIu64" ACCESS %s/%"PRIu64" mask=%d",                  state->finh->unique, state->loc.path, @@ -1084,36 +1037,23 @@ fuse_access_resume (fuse_state_t *state)          FUSE_FOP (state, fuse_err_cbk, GF_FOP_ACCESS, access,                    &state->loc, state->mask); -  } +  static void  fuse_access (xlator_t *this, fuse_in_header_t *finh, void *msg)  {          struct fuse_access_in *fai = msg; -          fuse_state_t *state = NULL; -        int32_t       ret = -1;          GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL); -        if ((state->loc.inode == NULL) || -            (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": ACCESS %"PRIu64" (%s) (fuse_loc_fill() failed)", -                        finh->unique, finh->nodeid, state->loc.path); -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } +        fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);          state->mask = fai->mask; -        uuid_copy (state->resolve.gfid, state->loc.inode->gfid); -        state->resolve.path = gf_strdup (state->loc.path); -          fuse_resolve_and_resume (state, fuse_access_resume); +          return;  } @@ -1151,50 +1091,51 @@ fuse_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          return 0;  } +  void  fuse_readlink_resume (fuse_state_t *state)  { +        if (!state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_ERROR, +                        "READLINK %"PRIu64" (%s) resolution failed", +                        state->finh->unique, uuid_utoa (state->resolve.gfid)); +                send_fuse_err (state->this, state->finh, ENOENT); +                free_fuse_state (state); +                return; +        } +          gf_log ("glusterfs-fuse", GF_LOG_TRACE,                  "%"PRIu64" READLINK %s/%s", state->finh->unique,                  state->loc.path, uuid_utoa (state->loc.inode->gfid));          FUSE_FOP (state, fuse_readlink_cbk, GF_FOP_READLINK,                    readlink, &state->loc, 4096); -  } +  static void  fuse_readlink (xlator_t *this, fuse_in_header_t *finh, void *msg)  {          fuse_state_t *state = NULL; -        int32_t       ret = -1;          GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL); -        if ((state->loc.inode == NULL) || -            (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64" READLINK %s (fuse_loc_fill() returned NULL inode)", -                        finh->unique, state->loc.path); -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } -        uuid_copy (state->resolve.gfid, state->loc.inode->gfid); -        state->resolve.path = gf_strdup (state->loc.path); +	fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);          fuse_resolve_and_resume (state, fuse_readlink_resume);          return;  } +  void  fuse_mknod_resume (fuse_state_t *state)  {          if (!state->loc.parent) { -                gf_log ("fuse", GF_LOG_ERROR, "failed to resolve path %s", -                        state->loc.path); +                gf_log ("glusterfs-fuse", GF_LOG_ERROR, +			"MKNOD %"PRId64"/%s (%s/%s) resolution failed", +                        state->finh->nodeid, state->resolve.bname, +			uuid_utoa (state->resolve.gfid), state->resolve.bname);                  send_fuse_err (state->this, state->finh, ENOENT);                  free_fuse_state (state);                  return; @@ -1203,6 +1144,7 @@ fuse_mknod_resume (fuse_state_t *state)          if (state->loc.inode) {                  gf_log (state->this->name, GF_LOG_DEBUG, "inode already present");                  inode_unref (state->loc.inode); +		state->loc.inode = NULL;          }          state->loc.inode = inode_new (state->loc.parent->table); @@ -1213,9 +1155,9 @@ fuse_mknod_resume (fuse_state_t *state)          FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_MKNOD,                    mknod, &state->loc, state->mode, state->rdev, state->dict); -  } +  static void  fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)  { @@ -1236,15 +1178,7 @@ fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)          uuid_generate (state->gfid); -        ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name); -        if (!state->loc.parent || (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64" MKNOD %s (fuse_loc_fill() failed)", -                        finh->unique, state->loc.path); -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } +	fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);          state->mode = fmi->mode;          state->rdev = fmi->rdev; @@ -1283,21 +1217,20 @@ fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)          }  #endif -        uuid_copy (state->resolve.pargfid, state->loc.parent->gfid); -        state->resolve.bname = gf_strdup (name); -        state->resolve.path = gf_strdup (state->loc.path); -          fuse_resolve_and_resume (state, fuse_mknod_resume);          return;  } +  void  fuse_mkdir_resume (fuse_state_t *state)  {          if (!state->loc.parent) { -                gf_log ("fuse", GF_LOG_ERROR, "failed to resolve path %s", -                        state->loc.path); +                gf_log ("glusterfs-fuse", GF_LOG_ERROR, +			"MKDIR %"PRId64" (%s/%s) resolution failed", +                        state->finh->nodeid, uuid_utoa (state->resolve.gfid), +			state->resolve.bname);                  send_fuse_err (state->this, state->finh, ENOENT);                  free_fuse_state (state);                  return; @@ -1306,6 +1239,7 @@ fuse_mkdir_resume (fuse_state_t *state)          if (state->loc.inode) {                  gf_log (state->this->name, GF_LOG_DEBUG, "inode already present");                  inode_unref (state->loc.inode); +		state->loc.inode = NULL;          }          state->loc.inode = inode_new (state->loc.parent->table); @@ -1318,6 +1252,7 @@ fuse_mkdir_resume (fuse_state_t *state)                    mkdir, &state->loc, state->mode, state->dict);  } +  static void  fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg)  { @@ -1332,15 +1267,7 @@ fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg)          uuid_generate (state->gfid); -        ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name); -        if (!state->loc.parent || (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64" MKDIR %s (fuse_loc_fill() failed)", -                        finh->unique, state->loc.path); -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } +	fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);          state->mode = fmi->mode; @@ -1378,55 +1305,43 @@ fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg)          }  #endif -        uuid_copy (state->resolve.pargfid, state->loc.parent->gfid); -        state->resolve.bname = gf_strdup (name); -        state->resolve.path = gf_strdup (state->loc.path); -          fuse_resolve_and_resume (state, fuse_mkdir_resume);          return;  } +  void  fuse_unlink_resume (fuse_state_t *state)  { -        if (!state->loc.inode) { -                gf_log ("fuse", GF_LOG_WARNING, "path resolving failed"); +        if (!state->loc.parent || !state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_ERROR, +			"UNLINK %"PRId64" (%s/%s) resolution failed", +			state->finh->nodeid, uuid_utoa (state->resolve.gfid), +			state->resolve.bname);                  send_fuse_err (state->this, state->finh, ENOENT);                  free_fuse_state (state);                  return;          } +          gf_log ("glusterfs-fuse", GF_LOG_TRACE,                  "%"PRIu64": UNLINK %s", state->finh->unique,                  state->loc.path);          FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_UNLINK,                    unlink, &state->loc); -  } +  static void  fuse_unlink (xlator_t *this, fuse_in_header_t *finh, void *msg)  {          char         *name = msg; -          fuse_state_t *state = NULL; -        int32_t       ret = -1;          GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name); -        if (!state->loc.parent || (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": UNLINK %s (fuse_loc_fill() returned NULL inode)", -                        finh->unique, state->loc.path); -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } -        uuid_copy (state->resolve.pargfid, state->loc.parent->gfid); -        state->resolve.bname = gf_strdup (name); -        state->resolve.path = gf_strdup (state->loc.path); +	fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);          fuse_resolve_and_resume (state, fuse_unlink_resume); @@ -1436,8 +1351,11 @@ fuse_unlink (xlator_t *this, fuse_in_header_t *finh, void *msg)  void  fuse_rmdir_resume (fuse_state_t *state)  { -        if (!state->loc.inode) { -                gf_log ("fuse", GF_LOG_WARNING, "path resolving failed"); +        if (!state->loc.parent || !state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_ERROR, +			"RMDIR %"PRId64" (%s/%s) resolution failed", +			state->finh->nodeid, uuid_utoa (state->resolve.gfid), +			state->resolve.bname);                  send_fuse_err (state->this, state->finh, ENOENT);                  free_fuse_state (state);                  return; @@ -1451,39 +1369,31 @@ fuse_rmdir_resume (fuse_state_t *state)                    rmdir, &state->loc, 0);  } +  static void  fuse_rmdir (xlator_t *this, fuse_in_header_t *finh, void *msg)  {          char         *name = msg; -          fuse_state_t *state = NULL; -        int32_t       ret = -1;          GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name); -        if (!state->loc.parent || (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": RMDIR %s (fuse_loc_fill() failed)", -                        finh->unique, state->loc.path); -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } -        uuid_copy (state->resolve.pargfid, state->loc.parent->gfid); -        state->resolve.bname = gf_strdup (name); -        state->resolve.path = gf_strdup (state->loc.path); +	fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);          fuse_resolve_and_resume (state, fuse_rmdir_resume); +          return;  } +  void  fuse_symlink_resume (fuse_state_t *state)  {          if (!state->loc.parent) { -                gf_log ("fuse", GF_LOG_ERROR, "failed to resolve path %s", -                        state->loc.path); +                gf_log ("glusterfs-fuse", GF_LOG_ERROR, +			"SYMLINK %"PRId64" (%s/%s) -> %s resolution failed", +                        state->finh->nodeid, uuid_utoa (state->resolve.gfid), +			state->resolve.bname, state->name);                  send_fuse_err (state->this, state->finh, ENOENT);                  free_fuse_state (state);                  return; @@ -1492,6 +1402,7 @@ fuse_symlink_resume (fuse_state_t *state)          if (state->loc.inode) {                  gf_log (state->this->name, GF_LOG_DEBUG, "inode already present");                  inode_unref (state->loc.inode); +		state->loc.inode = NULL;          }          state->loc.inode = inode_new (state->loc.parent->table); @@ -1504,36 +1415,24 @@ fuse_symlink_resume (fuse_state_t *state)                    symlink, state->name, &state->loc, state->dict);  } +  static void  fuse_symlink (xlator_t *this, fuse_in_header_t *finh, void *msg)  { -        char *name = msg; -        char *linkname = name + strlen (name) + 1; - +        char         *name = msg; +        char         *linkname = name + strlen (name) + 1;          fuse_state_t *state = NULL; -        int32_t       ret = -1;          GET_STATE (this, finh, state);          uuid_generate (state->gfid); -        ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name); -        if (!state->loc.parent || (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64" SYMLINK %s -> %s (fuse_loc_fill() failed)", -                        finh->unique, state->loc.path, linkname); -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } +	fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);          state->name = gf_strdup (linkname); -        uuid_copy (state->resolve.pargfid, state->loc.parent->gfid); -        state->resolve.bname = gf_strdup (name); -        state->resolve.path = gf_strdup (state->loc.path); -          fuse_resolve_and_resume (state, fuse_symlink_resume); +          return;  } @@ -1589,17 +1488,33 @@ fuse_rename_resume (fuse_state_t *state)          char loc_uuid[64]  = {0,};          char loc2_uuid[64] = {0,}; -        if (!state->loc.inode) { +        if (!state->loc.parent || !state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_ERROR, +                        "RENAME %"PRIu64" %s/%s -> %s/%s src resolution failed", +			state->finh->unique, +			uuid_utoa_r (state->resolve.gfid, loc_uuid), +			state->resolve.bname, +			uuid_utoa_r (state->resolve2.gfid, loc2_uuid), +			state->resolve2.bname); +                  send_fuse_err (state->this, state->finh, ENOENT);                  free_fuse_state (state);                  return;          } -        uuid_utoa_r (state->loc.inode->gfid, loc_uuid); -        if (state->loc2.inode) -                uuid_utoa_r (state->loc2.inode->gfid, loc2_uuid); -        else -                strcpy (loc2_uuid, "0"); +        if (!state->loc2.parent) { +                gf_log ("glusterfs-fuse", GF_LOG_ERROR, +                        "RENAME %"PRIu64" %s/%s -> %s/%s dst resolution failed", +			state->finh->unique, +			uuid_utoa_r (state->resolve.gfid, loc_uuid), +			state->resolve.bname, +			uuid_utoa_r (state->resolve2.gfid, loc2_uuid), +			state->resolve2.bname); + +                send_fuse_err (state->this, state->finh, ENOENT); +                free_fuse_state (state); +                return; +        }          gf_log ("glusterfs-fuse", GF_LOG_TRACE,                  "%"PRIu64": RENAME `%s (%s)' -> `%s (%s)'", @@ -1610,64 +1525,44 @@ fuse_rename_resume (fuse_state_t *state)                    rename, &state->loc, &state->loc2);  } +  static void  fuse_rename (xlator_t *this, fuse_in_header_t *finh, void *msg)  {          struct fuse_rename_in  *fri = msg;          char *oldname = (char *)(fri + 1);          char *newname = oldname + strlen (oldname) + 1; -          fuse_state_t *state = NULL; -        int32_t       ret = -1;          GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, oldname); -        if (!state->loc.parent || (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "for %s %"PRIu64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)", -                        state->loc.path, finh->unique, state->loc.path, -                        state->loc2.path); - -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } - -        ret = fuse_loc_fill (&state->loc2, state, 0, fri->newdir, newname); -        if (!state->loc2.parent && (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "for %s %"PRIu64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)", -                        state->loc.path, finh->unique, state->loc.path, -                        state->loc2.path); - -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } - -        uuid_copy (state->resolve.pargfid, state->loc.parent->gfid); -        state->resolve.bname = gf_strdup (oldname); -        state->resolve.path = gf_strdup (state->loc.path); +	fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, oldname); -        uuid_copy (state->resolve2.pargfid, state->loc2.parent->gfid); -        state->resolve2.bname = gf_strdup (newname); -        state->resolve2.path = gf_strdup (state->loc2.path); +	fuse_resolve_entry_init (state, &state->resolve2, fri->newdir, newname);          fuse_resolve_and_resume (state, fuse_rename_resume);          return;  } +  void  fuse_link_resume (fuse_state_t *state)  { -        if (state->loc.inode) { -                gf_log (state->this->name, GF_LOG_DEBUG, "inode already present"); -                inode_unref (state->loc.inode); +        if (!state->loc2.inode || !state->loc.parent) { +                gf_log ("glusterfs-fuse", GF_LOG_WARNING, +                        "fuse_loc_fill() failed %"PRIu64": LINK %s %s", +                        state->finh->unique, state->loc2.path, state->loc.path); +                send_fuse_err (state->this, state->finh, ENOENT); +                free_fuse_state (state); +                return;          } -        state->loc.inode = inode_ref (state->loc2.inode); +	if (state->loc.inode) { +		inode_unref (state->loc.inode); +		state->loc.inode = NULL; +	} +	state->loc.inode = inode_ref (state->loc2.inode);          gf_log ("glusterfs-fuse", GF_LOG_TRACE,                  "%"PRIu64": LINK() %s -> %s", @@ -1678,37 +1573,19 @@ fuse_link_resume (fuse_state_t *state)                    link, &state->loc2, &state->loc);  } +  static void  fuse_link (xlator_t *this, fuse_in_header_t *finh, void *msg)  {          struct fuse_link_in *fli = msg;          char         *name = (char *)(fli + 1); -          fuse_state_t *state = NULL; -        int32_t       ret = -1;          GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name); -        if (ret == 0) -                ret = fuse_loc_fill (&state->loc2, state, fli->oldnodeid, 0, -                                     NULL); - -        if (!state->loc2.inode || (ret < 0) || !state->loc.parent) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "fuse_loc_fill() failed %"PRIu64": LINK %s %s", -                        finh->unique, state->loc2.path, state->loc.path); -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } +	fuse_resolve_inode_init (state, &state->resolve2, fli->oldnodeid); -        uuid_copy (state->resolve.pargfid, state->loc.parent->gfid); -        state->resolve.bname = gf_strdup (name); -        state->resolve.path = gf_strdup (state->loc.path); - -        uuid_copy (state->resolve2.gfid, state->loc2.inode->gfid); -        state->resolve2.path = gf_strdup (state->loc2.path); +	fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);          fuse_resolve_and_resume (state, fuse_link_resume); @@ -1812,14 +1689,17 @@ out:          return 0;  } +  void  fuse_create_resume (fuse_state_t *state)  {          fd_t *fd = NULL;          if (!state->loc.parent) { -                gf_log ("fuse", GF_LOG_ERROR, "failed to resolve path %s", -                        state->loc.path); +                gf_log ("glusterfs-fuse", GF_LOG_WARNING, +                        "%"PRIu64" CREATE %s/%s resolution failed", +                        state->finh->unique, uuid_utoa (state->resolve.gfid), +			state->resolve.bname);                  send_fuse_err (state->this, state->finh, ENOENT);                  free_fuse_state (state);                  return; @@ -1846,6 +1726,7 @@ fuse_create_resume (fuse_state_t *state)  } +  static void  fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)  { @@ -1870,15 +1751,7 @@ fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)          uuid_generate (state->gfid); -        ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name); -        if (!state->loc.parent || (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64" CREATE %s (fuse_loc_fill() failed)", -                        finh->unique, state->loc.path); -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } +	fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);          state->mode = fci->mode;          state->flags = fci->flags; @@ -1917,20 +1790,27 @@ fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)          }  #endif -        uuid_copy (state->resolve.pargfid, state->loc.parent->gfid); -        state->resolve.bname = gf_strdup (name); -        state->resolve.path = gf_strdup (state->loc.path); -          fuse_resolve_and_resume (state, fuse_create_resume);          return;  } +  void  fuse_open_resume (fuse_state_t *state)  {          fd_t *fd = NULL; +        if (!state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_ERROR, +                        "%"PRIu64": OPEN %s resolution failed", +                        state->finh->unique, uuid_utoa (state->resolve.gfid)); + +                send_fuse_err (state->this, state->finh, ENOENT); +                free_fuse_state (state); +                return; +        } +          fd = fd_create (state->loc.inode, state->finh->pid);          if (!fd) {                  gf_log ("fuse", GF_LOG_ERROR, @@ -1951,33 +1831,19 @@ fuse_open_resume (fuse_state_t *state)                    open, &state->loc, state->flags, fd, 0);  } +  static void  fuse_open (xlator_t *this, fuse_in_header_t *finh, void *msg)  {          struct fuse_open_in *foi = msg; -          fuse_state_t *state = NULL; -        int32_t       ret = -1;          GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL); -        if ((state->loc.inode == NULL) || -            (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": OPEN %s (fuse_loc_fill() failed)", -                        finh->unique, state->loc.path); - -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } +	fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);          state->flags = foi->flags; -        uuid_copy (state->resolve.gfid, state->loc.inode->gfid); -        state->resolve.path = gf_strdup (state->loc.path); -          fuse_resolve_and_resume (state, fuse_open_resume);          return; @@ -2050,10 +1916,11 @@ fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg)          GET_STATE (this, finh, state); -          fd = FH_TO_FD (fri->fh);          state->fd = fd; +	fuse_resolve_fd_init (state, &state->resolve, fd); +          /* See comment by similar code in fuse_settatr */          priv = this->private;  #if FUSE_KERNEL_MINOR_VERSION >= 9 @@ -2108,11 +1975,6 @@ fuse_write_resume (fuse_state_t *state)          struct iobref *iobref = NULL;          struct iobuf  *iobuf = NULL; -        if (!state->fd || !state->fd->inode) { -                send_fuse_err (state->this, state->finh, EBADFD); -                free_fuse_state (state); -                return; -        }          iobref = iobref_new ();          if (!iobref) { @@ -2128,6 +1990,10 @@ fuse_write_resume (fuse_state_t *state)          iobuf = ((fuse_private_t *) (state->this->private))->iobuf;          iobref_add (iobref, iobuf); +        gf_log ("glusterfs-fuse", GF_LOG_TRACE, +                "%"PRIu64": WRITE (%p, size=%"PRId64", offset=%"PRId64")", +                state->finh->unique, state->fd, state->size, state->off); +          FUSE_FOP (state, fuse_writev_cbk, GF_FOP_WRITE, writev, state->fd,                    &state->vector, 1, state->off, iobref); @@ -2155,6 +2021,8 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)          state->size = fwi->size;          state->off  = fwi->offset; +	fuse_resolve_fd_init (state, &state->resolve, fd); +          /* See comment by similar code in fuse_settatr */          priv = this->private;  #if FUSE_KERNEL_MINOR_VERSION >= 9 @@ -2162,10 +2030,6 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)                  state->lk_owner = fwi->lock_owner;  #endif -        gf_log ("glusterfs-fuse", GF_LOG_TRACE, -                "%"PRIu64": WRITE (%p, size=%"PRIu32", offset=%"PRId64")", -                finh->unique, fd, fwi->size, fwi->offset); -          state->vector.iov_base = msg;          state->vector.iov_len  = fwi->size; @@ -2174,6 +2038,7 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)          return;  } +  void  fuse_flush_resume (fuse_state_t *state)  { @@ -2181,6 +2046,7 @@ fuse_flush_resume (fuse_state_t *state)                    flush, state->fd);  } +  static void  fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg)  { @@ -2193,6 +2059,8 @@ fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg)          fd = FH_TO_FD (ffi->fh);          state->fd = fd; +	fuse_resolve_fd_init (state, &state->resolve, fd); +          state->lk_owner = ffi->lock_owner;          gf_log ("glusterfs-fuse", GF_LOG_TRACE, @@ -2203,6 +2071,7 @@ fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg)          return;  } +  static void  fuse_release (xlator_t *this, fuse_in_header_t *finh, void *msg)  { @@ -2241,14 +2110,20 @@ fuse_release (xlator_t *this, fuse_in_header_t *finh, void *msg)          return;  } +  void  fuse_fsync_resume (fuse_state_t *state)  { +        gf_log ("glusterfs-fuse", GF_LOG_TRACE, +                "%"PRIu64": FSYNC %p", state->finh->unique, +		state->fd); +          /* fsync_flags: 1 means "datasync" (no defines for this) */          FUSE_FOP (state, fuse_fsync_cbk, GF_FOP_FSYNC,                    fsync, state->fd, state->flags & 1);  } +  static void  fuse_fsync (xlator_t *this, fuse_in_header_t *finh, void *msg)  { @@ -2261,19 +2136,28 @@ fuse_fsync (xlator_t *this, fuse_in_header_t *finh, void *msg)          fd = FH_TO_FD (fsi->fh);          state->fd = fd; -        gf_log ("glusterfs-fuse", GF_LOG_TRACE, -                "%"PRIu64": FSYNC %p", finh->unique, fd); +	fuse_resolve_fd_init (state, &state->resolve, fd);          state->flags = fsi->fsync_flags;          fuse_resolve_and_resume (state, fuse_fsync_resume);          return;  } +  void  fuse_opendir_resume (fuse_state_t *state)  {          fd_t *fd = NULL; +        if (!state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_WARNING, +                        "%"PRIu64": OPENDIR (%s) resolution failed", +                        state->finh->unique, uuid_utoa (state->resolve.gfid)); +                send_fuse_err (state->this, state->finh, ENOENT); +                free_fuse_state (state); +                return; +        } +          fd = fd_create (state->loc.inode, state->finh->pid);          state->fd = fd; @@ -2285,6 +2169,7 @@ fuse_opendir_resume (fuse_state_t *state)                    opendir, &state->loc, fd);  } +  static void  fuse_opendir (xlator_t *this, fuse_in_header_t *finh, void *msg)  { @@ -2293,22 +2178,10 @@ fuse_opendir (xlator_t *this, fuse_in_header_t *finh, void *msg)           */          fuse_state_t *state = NULL; -        int32_t       ret = -1;          GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL); -        if ((state->loc.inode == NULL) || (ret < 0)) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": OPENDIR %s (fuse_loc_fill() failed)", -                        finh->unique, state->loc.path); - -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } -        uuid_copy (state->resolve.gfid, state->loc.inode->gfid); -        state->resolve.path = gf_strdup (state->loc.path); +        fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);          fuse_resolve_and_resume (state, fuse_opendir_resume);  } @@ -2413,6 +2286,7 @@ out:  } +  void  fuse_readdir_resume (fuse_state_t *state)  { @@ -2424,6 +2298,7 @@ fuse_readdir_resume (fuse_state_t *state)                    readdir, state->fd, state->size, state->off);  } +  static void  fuse_readdir (xlator_t *this, fuse_in_header_t *finh, void *msg)  { @@ -2438,6 +2313,8 @@ fuse_readdir (xlator_t *this, fuse_in_header_t *finh, void *msg)          fd = FH_TO_FD (fri->fh);          state->fd = fd; +	fuse_resolve_fd_init (state, &state->resolve, fd); +          fuse_resolve_and_resume (state, fuse_readdir_resume);  } @@ -2502,6 +2379,8 @@ fuse_fsyncdir (xlator_t *this, fuse_in_header_t *finh, void *msg)          GET_STATE (this, finh, state);          state->fd = fd; +	fuse_resolve_fd_init (state, &state->resolve, fd); +          state->flags = fsi->fsync_flags;          fuse_resolve_and_resume (state, fuse_fsyncdir_resume); @@ -2561,35 +2440,59 @@ fuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          return 0;  } -static void -fuse_statfs (xlator_t *this, fuse_in_header_t *finh, void *msg) -{ -        fuse_state_t *state = NULL; -        int32_t       ret = -1; -        GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL); -        if ((state->loc.inode == NULL) || -            (ret < 0)) { +void +fuse_statfs_resume (fuse_state_t *state) +{ +        if (!state->loc.inode) {                  gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": STATFS (fuse_loc_fill() fail)", -                        finh->unique); +                        "%"PRIu64": STATFS (%s) resolution fail", +                        state->finh->unique, uuid_utoa (state->resolve.gfid)); -                send_fuse_err (this, finh, ENOENT); +                send_fuse_err (state->this, state->finh, ENOENT);                  free_fuse_state (state);                  return;          }          gf_log ("glusterfs-fuse", GF_LOG_TRACE, -                "%"PRIu64": STATFS", finh->unique); +                "%"PRIu64": STATFS", state->finh->unique);          FUSE_FOP (state, fuse_statfs_cbk, GF_FOP_STATFS,                    statfs, &state->loc);  } + +static void +fuse_statfs (xlator_t *this, fuse_in_header_t *finh, void *msg) +{ +        fuse_state_t *state = NULL; + +        GET_STATE (this, finh, state); + +	fuse_resolve_inode_init (state, &state->resolve, finh->nodeid); + +	fuse_resolve_and_resume (state, fuse_statfs_resume); +} + +  void  fuse_setxattr_resume (fuse_state_t *state)  { +        if (!state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_WARNING, +                        "%"PRIu64": SETXATTR %s/%"PRIu64" (%s) " +                        "resolution failed", +                        state->finh->unique, uuid_utoa (state->resolve.gfid), +			state->finh->nodeid, state->name); +                send_fuse_err (state->this, state->finh, ENOENT); +                free_fuse_state (state); +                return; +        } + +#ifdef GF_TEST_FFOP +        state->fd = fd_lookup (state->loc.inode, state->finh->pid); +#endif /* GF_TEST_FFOP */ +          if (state->fd) {                  gf_log ("glusterfs-fuse", GF_LOG_TRACE,                          "%"PRIu64": SETXATTR %p/%"PRIu64" (%s)", state->finh->unique, @@ -2607,6 +2510,7 @@ fuse_setxattr_resume (fuse_state_t *state)          }  } +  static void  fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)  { @@ -2677,29 +2581,8 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)          GET_STATE (this, finh, state);          state->size = fsi->size; -        ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL); -        if (!state->loc.inode) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": SETXATTR %s/%"PRIu64" (%s) " -                        "(fuse_loc_fill() failed (%d))", -                        finh->unique, state->loc.path, finh->nodeid, name, ret); -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } - -#ifdef GF_TEST_FFOP -        state->fd = fd_lookup (state->loc.inode, state->finh->pid); -#endif /* GF_TEST_FFOP */ -        if (ret && !state->fd) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": SETXATTR %"PRIu64" (fuse_loc_fill() failed)", -                        state->finh->unique, state->finh->nodeid); -                send_fuse_err (state->this, state->finh, ENOENT); -                free_fuse_state (state); -                return; -        } +	fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);          state->dict = get_new_dict ();          if (!state->dict) { @@ -2732,16 +2615,12 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)          state->flags = fsi->flags;          state->name = newkey; -        if (!state->fd) { -                uuid_copy (state->resolve.gfid, state->loc.inode->gfid); -                state->resolve.path = gf_strdup (state->loc.path); -        } -          fuse_resolve_and_resume (state, fuse_setxattr_resume);          return;  } +  static void  send_fuse_xattr (xlator_t *this, fuse_in_header_t *finh, const char *value,                   size_t size, size_t expected) @@ -2765,6 +2644,7 @@ send_fuse_xattr (xlator_t *this, fuse_in_header_t *finh, const char *value,          }  } +  static int  fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  int32_t op_ret, int32_t op_errno, dict_t *dict) @@ -2858,9 +2738,27 @@ out:          return 0;  } +  void  fuse_getxattr_resume (fuse_state_t *state)  { +        if (!state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_WARNING, +                        "%"PRIu64": GETXATTR %s/%"PRIu64" (%s) " +			"resolution failed", +                        state->finh->unique, +			uuid_utoa (state->resolve.gfid), +			state->finh->nodeid, state->name); + +                send_fuse_err (state->this, state->finh, ENOENT); +                free_fuse_state (state); +                return; +        } + +#ifdef GF_TEST_FFOP +        state->fd = fd_lookup (state->loc.inode, state->finh->pid); +#endif /* GF_TEST_FFOP */ +          if (state->fd) {                  gf_log ("glusterfs-fuse", GF_LOG_TRACE,                          "%"PRIu64": GETXATTR %p/%"PRIu64" (%s)", state->finh->unique, @@ -2878,6 +2776,7 @@ fuse_getxattr_resume (fuse_state_t *state)          }  } +  static void  fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)  { @@ -2885,7 +2784,6 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)          char         *name = (char *)(fgxi + 1);          fuse_state_t *state = NULL; -        int32_t       ret = -1;          struct fuse_private *priv = NULL;          int rv = 0;          char *newkey = NULL; @@ -2931,29 +2829,7 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)          GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL); -        if (!state->loc.inode) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": GETXATTR %s/%"PRIu64" (%s) " -                        "(fuse_loc_fill() failed (%d))", -                        finh->unique, state->loc.path, finh->nodeid, name, ret); - -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } - -#ifdef GF_TEST_FFOP -        state->fd = fd_lookup (state->loc.inode, state->finh->pid); -#endif /* GF_TEST_FFOP */ -        if (ret && !state->fd) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": GETXATTR %"PRIu64" (fuse_loc_fill() failed)", -                        state->finh->unique, state->finh->nodeid); -                send_fuse_err (state->this, state->finh, ENOENT); -                free_fuse_state (state); -                return; -        } +	fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);          rv = fuse_flip_xattr_ns (priv, name, &newkey);          if (rv) { @@ -2965,19 +2841,30 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)          state->size = fgxi->size;          state->name = newkey; -        if (!state->fd) { -                uuid_copy (state->resolve.gfid, state->loc.inode->gfid); -                state->resolve.path = gf_strdup (state->loc.path); -        } -          fuse_resolve_and_resume (state, fuse_getxattr_resume);   out:          return;  } +  void  fuse_listxattr_resume (fuse_state_t *state)  { +        if (!state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_WARNING, +                        "%"PRIu64": LISTXATTR %s/%"PRIu64 +                        "resolution failed", state->finh->unique, +			uuid_utoa (state->resolve.gfid), state->finh->nodeid); + +                send_fuse_err (state->this, state->finh, ENOENT); +                free_fuse_state (state); +                return; +        } + +#ifdef GF_TEST_FFOP +        state->fd = fd_lookup (state->loc.inode, state->finh->pid); +#endif /* GF_TEST_FFOP */ +          if (state->fd) {                  gf_log ("glusterfs-fuse", GF_LOG_TRACE,                          "%"PRIu64": LISTXATTR %p/%"PRIu64, state->finh->unique, @@ -2995,54 +2882,44 @@ fuse_listxattr_resume (fuse_state_t *state)          }  } +  static void  fuse_listxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)  {          struct fuse_getxattr_in *fgxi = msg; -          fuse_state_t *state = NULL; -        int32_t       ret = -1;          GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL); -        if (!state->loc.inode) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": LISTXATTR %s/%"PRIu64 -                        " (fuse_loc_fill() failed (%d))", -                        finh->unique, state->loc.path, finh->nodeid, ret); - -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } - -#ifdef GF_TEST_FFOP -        state->fd = fd_lookup (state->loc.inode, state->finh->pid); -#endif /* GF_TEST_FFOP */ -        if (ret && !state->fd) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": LISTXATTR %"PRIu64" (fuse_loc_fill() failed)", -                        state->finh->unique, state->finh->nodeid); -                send_fuse_err (state->this, state->finh, ENOENT); -                free_fuse_state (state); -                return; -        } +	fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);          state->size = fgxi->size; -        if (!state->fd) { -                uuid_copy (state->resolve.gfid, state->loc.inode->gfid); -                state->resolve.path = gf_strdup (state->loc.path); -        }          fuse_resolve_and_resume (state, fuse_listxattr_resume);          return;  } +  void  fuse_removexattr_resume (fuse_state_t *state)  { +         if (!state->loc.inode) { +                gf_log ("glusterfs-fuse", GF_LOG_DEBUG, +                        "%"PRIu64": REMOVEXATTR %s/%"PRIu64" (%s) " +			"resolution failed", +                        state->finh->unique, uuid_utoa (state->resolve.gfid), +			state->finh->nodeid, state->name); + +                send_fuse_err (state->this, state->finh, ENOENT); +                free_fuse_state (state); +                return; +        } + +#ifdef GF_TEST_FFOP +        state->fd = fd_lookup (state->loc.inode, state->finh->pid); +#endif /* GF_TEST_FFOP */ +          if (state->fd) {                  gf_log ("glusterfs-fuse", GF_LOG_TRACE,                          "%"PRIu64": REMOVEXATTR %p/%"PRIu64" (%s)", state->finh->unique, @@ -3060,9 +2937,9 @@ fuse_removexattr_resume (fuse_state_t *state)          }  } +  static void  fuse_removexattr (xlator_t *this, fuse_in_header_t *finh, void *msg) -  {          char *name = msg; @@ -3074,29 +2951,8 @@ fuse_removexattr (xlator_t *this, fuse_in_header_t *finh, void *msg)          priv = this->private;          GET_STATE (this, finh, state); -        ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL); -        if (!state->loc.inode) { -                gf_log ("glusterfs-fuse", GF_LOG_DEBUG, -                        "%"PRIu64": REMOVEXATTR %s/%"PRIu64" (%s) " -                        "(fuse_loc_fill() failed (%d))", -                        finh->unique, state->loc.path, finh->nodeid, name, ret); - -                send_fuse_err (this, finh, ENOENT); -                free_fuse_state (state); -                return; -        } -#ifdef GF_TEST_FFOP -        state->fd = fd_lookup (state->loc.inode, state->finh->pid); -#endif /* GF_TEST_FFOP */ -        if (ret && !state->fd) { -                gf_log ("glusterfs-fuse", GF_LOG_WARNING, -                        "%"PRIu64": REMOVEXATTR %"PRIu64" (fuse_loc_fill() failed)", -                        state->finh->unique, state->finh->nodeid); -                send_fuse_err (state->this, state->finh, ENOENT); -                free_fuse_state (state); -                return; -        } +	fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);          ret = fuse_flip_xattr_ns (priv, name, &newkey);          if (ret) { @@ -3106,10 +2962,6 @@ fuse_removexattr (xlator_t *this, fuse_in_header_t *finh, void *msg)          }          state->name = newkey; -        if (!state->fd) { -                uuid_copy (state->resolve.gfid, state->loc.inode->gfid); -                state->resolve.path = gf_strdup (state->loc.path); -        }          fuse_resolve_and_resume (state, fuse_removexattr_resume);          return; @@ -3164,6 +3016,7 @@ fuse_getlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          return 0;  } +  void  fuse_getlk_resume (fuse_state_t *state)  { @@ -3174,6 +3027,7 @@ fuse_getlk_resume (fuse_state_t *state)                    lk, state->fd, F_GETLK, &state->lk_lock);  } +  static void  fuse_getlk (xlator_t *this, fuse_in_header_t *finh, void *msg)  { @@ -3185,6 +3039,9 @@ fuse_getlk (xlator_t *this, fuse_in_header_t *finh, void *msg)          fd = FH_TO_FD (fli->fh);          GET_STATE (this, finh, state);          state->fd = fd; + +	fuse_resolve_fd_init (state, &state->resolve, fd); +          convert_fuse_file_lock (&fli->lk, &state->lk_lock,                                  fli->owner); @@ -3254,6 +3111,7 @@ fuse_setlk_resume (fuse_state_t *state)                    &state->lk_lock);  } +  static void  fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)  { @@ -3266,6 +3124,9 @@ fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)          GET_STATE (this, finh, state);          state->finh = finh;          state->fd = fd; + +	fuse_resolve_fd_init (state, &state->resolve, fd); +          convert_fuse_file_lock (&fli->lk, &state->lk_lock,                                  fli->owner); @@ -3276,6 +3137,7 @@ fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)          return;  } +  static void *  notify_kernel_loop (void *data)  { diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h index 4d80af574..489e6d645 100644 --- a/xlators/mount/fuse/src/fuse-bridge.h +++ b/xlators/mount/fuse/src/fuse-bridge.h @@ -157,7 +157,7 @@ typedef struct fuse_private fuse_private_t;                  frame->root->op    = op_num;                            \                  frame->op          = op_num;                            \                                                                          \ -                xl = fuse_state_subvol (state);                         \ +                xl = state->active_subvol;				\                  if (!xl) {                                              \                          gf_log ("glusterfs-fuse", GF_LOG_ERROR,         \                                  "xl is NULL");                          \ @@ -217,6 +217,17 @@ typedef struct fuse_private fuse_private_t; +static inline xlator_t * +fuse_active_subvol (xlator_t *fuse) +{ +        fuse_private_t *priv = NULL; + +        priv = fuse->private; + +        return priv->active_subvol; +} + +  typedef enum {          RESOLVE_MUST = 1,          RESOLVE_NOT, @@ -225,35 +236,27 @@ typedef enum {          RESOLVE_EXACT  } fuse_resolve_type_t; -struct fuse_resolve_comp { -        char      *basename; -        ino_t      ino; -        uint64_t   gen; -        inode_t   *inode; -};  typedef struct {          fuse_resolve_type_t    type; -        ino_t                  ino; -        uint64_t               gen; -        ino_t                  par;          fd_t                  *fd;          char                  *path;          char                  *bname;          u_char                 gfid[16]; +	inode_t               *hint;          u_char                 pargfid[16]; +	inode_t               *parhint;  	char                  *resolved;          int                    op_ret;          int                    op_errno;          loc_t                  resolve_loc; -        struct fuse_resolve_comp *components; -        int                    comp_count;  } fuse_resolve_t;  typedef struct {          void             *pool;          xlator_t         *this; +	xlator_t         *active_subvol;          inode_table_t    *itable;          loc_t             loc;          loc_t             loc2; @@ -306,10 +309,8 @@ fuse_state_t *get_fuse_state (xlator_t *this, fuse_in_header_t *finh);  void free_fuse_state (fuse_state_t *state);  void gf_fuse_stat2attr (struct iatt *st, struct fuse_attr *fa);  uint64_t inode_to_fuse_nodeid (inode_t *inode); -xlator_t *fuse_state_subvol (fuse_state_t *state);  xlator_t *fuse_active_subvol (xlator_t *fuse);  inode_t *fuse_ino_to_inode (uint64_t ino, xlator_t *fuse); -int fuse_resolve_and_resume (fuse_state_t *state, fuse_resume_fn_t fn);  int send_fuse_err (xlator_t *this, fuse_in_header_t *finh, int error);  int fuse_gfid_set (fuse_state_t *state);  int fuse_flip_xattr_ns (struct fuse_private *priv, char *okey, char **nkey); @@ -318,4 +319,11 @@ int fuse_xattr_alloc_default (char *okey, char **nkey);  fuse_fd_ctx_t * __fuse_fd_ctx_check_n_create (fd_t *fd, xlator_t *this);  fuse_fd_ctx_t * fuse_fd_ctx_check_n_create (fd_t *fd, xlator_t *this); +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); +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);  #endif /* _GF_FUSE_BRIDGE_H_ */ diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c index 2070447fa..81994ad96 100644 --- a/xlators/mount/fuse/src/fuse-helpers.c +++ b/xlators/mount/fuse/src/fuse-helpers.c @@ -24,41 +24,10 @@  #include <sys/sysctl.h>  #endif -xlator_t * -fuse_state_subvol (fuse_state_t *state) -{ -        xlator_t *subvol = NULL; - -        if (!state) -                return NULL; - -        if (state->loc.inode) -                subvol = state->loc.inode->table->xl; - -        if (state->fd) -                subvol = state->fd->inode->table->xl; - -        return subvol; -} - - -xlator_t * -fuse_active_subvol (xlator_t *fuse) -{ -        fuse_private_t *priv = NULL; - -        priv = fuse->private; - -        return priv->active_subvol; -} - -  static void  fuse_resolve_wipe (fuse_resolve_t *resolve)  { -        struct fuse_resolve_comp *comp = NULL; -          if (resolve->path)                  GF_FREE ((void *)resolve->path); @@ -70,22 +39,18 @@ fuse_resolve_wipe (fuse_resolve_t *resolve)          loc_wipe (&resolve->resolve_loc); -        comp = resolve->components; - -        if (comp) { -                int                  i = 0; - -                for (i = 0; comp[i].basename; i++) { -                        if (comp[i].inode) { -                                inode_unref (comp[i].inode); -                                comp[i].inode = NULL; -                        } -                } +	if (resolve->hint) { +		inode_unref (resolve->hint); +		resolve->hint = 0; +	} -                GF_FREE ((void *)resolve->components); -        } +	if (resolve->parhint) { +		inode_unref (resolve->parhint); +		resolve->parhint = 0; +	}  } +  void  free_fuse_state (fuse_state_t *state)  { @@ -125,11 +90,18 @@ fuse_state_t *  get_fuse_state (xlator_t *this, fuse_in_header_t *finh)  {          fuse_state_t *state = NULL; +	xlator_t     *active_subvol = NULL;          state = (void *)GF_CALLOC (1, sizeof (*state),                                     gf_fuse_mt_fuse_state_t);          if (!state)                  return NULL; + +	state->this = THIS; +        active_subvol = fuse_active_subvol (state->this); +	state->active_subvol = active_subvol; +	state->itable = active_subvol->itable; +          state->pool = this->ctx->pool;          state->finh = finh;          state->this = this; diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c index 755e2f429..1af80b93c 100644 --- a/xlators/mount/fuse/src/fuse-resolve.c +++ b/xlators/mount/fuse/src/fuse-resolve.c @@ -46,8 +46,11 @@ fuse_resolve_loc_touchup (fuse_state_t *state)          if (!loc->path) {                  if (loc->parent && resolve->bname) {                          ret = inode_path (loc->parent, resolve->bname, &path); +			uuid_copy (loc->pargfid, loc->parent->gfid); +			loc->name = resolve->bname;                  } else if (loc->inode) {                          ret = inode_path (loc->inode, NULL, &path); +			uuid_copy (loc->gfid, loc->inode->gfid);                  }                  if (ret)                          gf_log (THIS->name, GF_LOG_TRACE, @@ -60,10 +63,10 @@ fuse_resolve_loc_touchup (fuse_state_t *state)  int -fuse_resolve_gfid_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                             int op_ret, int op_errno, inode_t *inode, -                             struct iatt *buf, dict_t *xattr, -                             struct iatt *postparent) +fuse_resolve_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +			int op_ret, int op_errno, inode_t *inode, +			struct iatt *buf, dict_t *xattr, +			struct iatt *postparent)  {          fuse_state_t   *state      = NULL;          fuse_resolve_t *resolve    = NULL; @@ -88,13 +91,7 @@ fuse_resolve_gfid_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          link_inode = inode_link (inode, resolve_loc->parent,                                   resolve_loc->name, buf); -        if (!link_inode) -                goto out; - -        inode_lookup (link_inode); - -        inode_unref (link_inode); - +	state->loc_now->inode = link_inode;  out:          loc_wipe (resolve_loc); @@ -104,6 +101,30 @@ out:  int +fuse_resolve_entry (fuse_state_t *state) +{ +	fuse_resolve_t   *resolve = NULL; +	loc_t            *resolve_loc = NULL; + +	resolve = state->resolve_now; +	resolve_loc = &resolve->resolve_loc; + +	resolve_loc->parent = inode_ref (state->loc_now->parent); +	uuid_copy (resolve_loc->pargfid, state->loc_now->pargfid); +        resolve_loc->name = resolve->bname; +        resolve_loc->inode = inode_new (state->itable); + +        inode_path (resolve_loc->parent, resolve_loc->name, +                    (char **) &resolve_loc->path); + +        FUSE_FOP (state, fuse_resolve_entry_cbk, GF_FOP_LOOKUP, +                  lookup, resolve_loc, NULL); + +	return 0; +} + + +int  fuse_resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                         int op_ret, int op_errno, inode_t *inode, struct iatt *buf,                         dict_t *xattr, struct iatt *postparent) @@ -111,11 +132,11 @@ 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          *resolve_loc   = NULL; +        loc_t          *loc_now   = NULL;          state = frame->root->state;          resolve = state->resolve_now; -        resolve_loc = &resolve->resolve_loc; +	loc_now = state->loc_now;          STACK_DESTROY (frame->root); @@ -123,36 +144,27 @@ fuse_resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :                                       GF_LOG_WARNING),                          "%s: failed to resolve (%s)", -                        uuid_utoa (resolve_loc->gfid), strerror (op_errno)); +                        uuid_utoa (resolve->resolve_loc.gfid), +			strerror (op_errno));                  loc_wipe (&resolve->resolve_loc);                  goto out;          } -        loc_wipe (resolve_loc); +        loc_wipe (&resolve->resolve_loc);          link_inode = inode_link (inode, NULL, NULL, buf);          if (!link_inode)                  goto out; -        inode_lookup (link_inode); - -        if (uuid_is_null (resolve->pargfid)) { -                inode_unref (link_inode); -                goto out; -        } - -        resolve_loc->parent = link_inode; -        uuid_copy (resolve_loc->pargfid, resolve_loc->parent->gfid); +	if (!uuid_is_null (resolve->gfid)) { +		loc_now->inode = link_inode; +		goto out; +	} -        resolve_loc->name = resolve->bname; - -        resolve_loc->inode = inode_new (state->itable); -        inode_path (resolve_loc->parent, resolve_loc->name, -                    (char **) &resolve_loc->path); +	loc_now->parent = link_inode; -        FUSE_FOP (state, fuse_resolve_gfid_entry_cbk, GF_FOP_LOOKUP, -                  lookup, &resolve->resolve_loc, NULL); +	fuse_resolve_entry (state);          return 0;  out: @@ -173,15 +185,14 @@ fuse_resolve_gfid (fuse_state_t *state)          if (!uuid_is_null (resolve->pargfid)) {                  uuid_copy (resolve_loc->gfid, resolve->pargfid); -                resolve_loc->inode = inode_new (state->itable); -                ret = inode_path (resolve_loc->inode, NULL, -                                  (char **)&resolve_loc->path);          } else if (!uuid_is_null (resolve->gfid)) {                  uuid_copy (resolve_loc->gfid, resolve->gfid); -                resolve_loc->inode = inode_new (state->itable); -                ret = inode_path (resolve_loc->inode, NULL, -                                  (char **)&resolve_loc->path);          } + +	resolve_loc->inode = inode_new (state->itable); +	ret = inode_path (resolve_loc->inode, NULL, +			  (char **)&resolve_loc->path); +          if (ret <= 0) {                  gf_log (THIS->name, GF_LOG_WARNING,                          "failed to get the path from inode %s", @@ -189,122 +200,83 @@ fuse_resolve_gfid (fuse_state_t *state)          }          FUSE_FOP (state, fuse_resolve_gfid_cbk, GF_FOP_LOOKUP, -                  lookup, &resolve->resolve_loc, NULL); - -        return 0; -} - - -int -fuse_resolve_continue (fuse_state_t *state) -{ -        fuse_resolve_t     *resolve = NULL; -        int                   ret = 0; - -        resolve = state->resolve_now; - -        resolve->op_ret   = 0; -        resolve->op_errno = 0; - -        /* TODO: should we handle 'fd' here ? */ -        if (!uuid_is_null (resolve->pargfid)) -                ret = fuse_resolve_entry_simple (state); -        else if (!uuid_is_null (resolve->gfid)) -                ret = fuse_resolve_inode_simple (state); -        if (ret) -                gf_log (THIS->name, GF_LOG_DEBUG, -                        "return value of resolve_*_simple %d", ret); - -        fuse_resolve_loc_touchup (state); - -        fuse_resolve_all (state); +                  lookup, resolve_loc, NULL);          return 0;  }  /* -  Check if the requirements are fulfilled by entries in the inode cache itself -  Return value: -  <= 0 - simple resolution was decisive and complete (either success or failure) -  > 0  - indecisive, need to perform deep resolution -*/ + * Return value: + * 0 - resolved parent and entry (as necessary) + * -1 - resolved parent but not entry (though necessary) + * 1 - resolved neither parent nor entry + */  int -fuse_resolve_entry_simple (fuse_state_t *state) +fuse_resolve_parent_simple (fuse_state_t *state)  {          fuse_resolve_t *resolve   = NULL; -        inode_t      *parent    = NULL; -        inode_t      *inode     = NULL; -        int           ret       = 0; +	loc_t          *loc       = NULL; +        inode_t        *parent    = NULL; +        inode_t        *inode     = NULL;          resolve = state->resolve_now; +	loc = state->loc_now; -        parent = inode_find (state->itable, resolve->pargfid); -        if (!parent) { -                /* simple resolution is indecisive. need to perform -                   deep resolution */ -                resolve->op_ret   = -1; -                resolve->op_errno = ENOENT; -                ret = 1; -                goto out; -        } - -        /* expected @parent was found from the inode cache */ -        if (state->loc_now->parent) { -                inode_unref (state->loc_now->parent); -        } - -        state->loc_now->parent = inode_ref (parent); +	loc->name = resolve->bname; -        inode = inode_grep (state->itable, parent, resolve->bname); -        if (!inode) { -                resolve->op_ret   = -1; -                resolve->op_errno = ENOENT; -                ret = 1; -                goto out; -        } - -        ret = 0; - -        if (state->loc_now->inode) { -                inode_unref (state->loc_now->inode); -                state->loc_now->inode = NULL; -        } +	parent = resolve->parhint; +	if (parent->table == state->itable) { +		/* no graph switches since */ +		loc->parent = inode_ref (parent); +		loc->inode = inode_grep (state->itable, parent, loc->name); +		/* decisive result - resolution success */ +		return 0; +	} -        state->loc_now->inode  = inode_ref (inode); -        uuid_copy (state->loc_now->gfid, resolve->gfid); - -out: -        if (parent) -                inode_unref (parent); - -        if (inode) -                inode_unref (inode); - -        return ret; +        parent = inode_find (state->itable, resolve->pargfid); +	if (!parent) { +		resolve->op_ret   = -1; +		resolve->op_errno = ENOENT; +		/* non decisive result - parent missing */ +		return 1; +	} + +	loc->parent = parent; + +	inode = inode_grep (state->itable, parent, loc->name); +	if (inode) { +		loc->inode = inode; +		/* decisive result - resolution success */ +		return 0; +	} + +	/* non decisive result - entry missing */ +        return -1;  }  int -fuse_resolve_entry (fuse_state_t *state) +fuse_resolve_parent (fuse_state_t *state)  {          int    ret = 0;          loc_t *loc = NULL;          loc  = state->loc_now; -        ret = fuse_resolve_entry_simple (state); +        ret = fuse_resolve_parent_simple (state);          if (ret > 0) { -                loc_wipe (loc);                  fuse_resolve_gfid (state);                  return 0;          } -        if (ret == 0) -                fuse_resolve_loc_touchup (state); +	if (ret < 0) { +		fuse_resolve_entry (state); +		return 0; +	} -        fuse_resolve_all (state); +        fuse_resolve_continue (state);          return 0;  } @@ -314,33 +286,29 @@ int  fuse_resolve_inode_simple (fuse_state_t *state)  {          fuse_resolve_t *resolve   = NULL; -        inode_t      *inode     = NULL; -        int           ret       = 0; +	loc_t          *loc = NULL; +        inode_t        *inode     = NULL;          resolve = state->resolve_now; +	loc = state->loc_now; -        inode = inode_find (state->itable, resolve->gfid); -        if (!inode) { -                resolve->op_ret   = -1; -                resolve->op_errno = ENOENT; -                ret = 1; -                goto out; -        } - -        ret = 0; - -        if (state->loc_now->inode) { -                inode_unref (state->loc_now->inode); -        } - -        state->loc_now->inode = inode_ref (inode); -        uuid_copy (state->loc_now->gfid, resolve->gfid); +	inode = resolve->hint; +	if (inode->table == state->itable) { +		inode_ref (inode); +		goto found; +	} -out: +        inode = inode_find (state->itable, resolve->gfid);          if (inode) -                inode_unref (inode); +		goto found; -        return ret; +	resolve->op_ret   = -1; +	resolve->op_errno = ENOENT; + +        return 1; +found: +	loc->inode = inode; +	return 0;  } @@ -355,15 +323,11 @@ fuse_resolve_inode (fuse_state_t *state)          ret = fuse_resolve_inode_simple (state);          if (ret > 0) { -                loc_wipe (loc);                  fuse_resolve_gfid (state);                  return 0;          } -        if (ret == 0) -                fuse_resolve_loc_touchup (state); - -        fuse_resolve_all (state); +        fuse_resolve_continue (state);          return 0;  } @@ -372,46 +336,87 @@ static int  fuse_resolve_fd (fuse_state_t *state)  {          fuse_resolve_t  *resolve    = NULL; -        fd_t          *fd         = NULL; -        int            ret        = 0; -        uint64_t       tmp_fd_ctx = 0; -        char          *path       = NULL; -        char          *name       = NULL; +	fd_t            *fd         = NULL; +	xlator_t        *active_subvol = NULL;          resolve = state->resolve_now;          fd = resolve->fd; +	active_subvol = fd->inode->table->xl; -        ret = fd_ctx_get (fd, state->this, &tmp_fd_ctx); -        if (!ret) { -                state->fd = (fd_t *)(long)tmp_fd_ctx; -                fd_ref (state->fd); -                fuse_resolve_all (state); +	state->active_subvol = active_subvol; + +        fuse_resolve_continue (state); + +        return 0; +} + + +int +fuse_gfid_set (fuse_state_t *state) +{ +        int   ret = 0; + +        if (uuid_is_null (state->gfid)) +                goto out; + +        if (!state->dict) +                state->dict = dict_new (); + +        if (!state->dict) { +                ret = -1;                  goto out;          } -        ret = inode_path (fd->inode, 0, &path); -        if (ret <= 0) -                gf_log ("", GF_LOG_WARNING, -                        "failed to do inode-path on fd %d %s", ret, path); +        ret = dict_set_static_bin (state->dict, "gfid-req", +                                   state->gfid, sizeof (state->gfid)); +out: +        return ret; +} -        name = strrchr (path, '/'); -        if (name) -                name++; -        resolve->path = path; -        resolve->bname = gf_strdup (name); +int +fuse_resolve_entry_init (fuse_state_t *state, fuse_resolve_t *resolve, +			 ino_t par, char *name) +{ +	inode_t       *parent = NULL; -        state->loc_now     = &state->loc; +	parent = fuse_ino_to_inode (par, state->this); +	uuid_copy (resolve->pargfid, parent->gfid); +	resolve->parhint = parent; +	resolve->bname = gf_strdup (name); -out: -        return 0; +	return 0; +} + + +int +fuse_resolve_inode_init (fuse_state_t *state, fuse_resolve_t *resolve, +			 ino_t ino) +{ +	inode_t       *inode = NULL; + +	inode = fuse_ino_to_inode (ino, state->this); +	uuid_copy (resolve->gfid, inode->gfid); +	resolve->hint = inode; + +	return 0; +} + + +int +fuse_resolve_fd_init (fuse_state_t *state, fuse_resolve_t *resolve, +		      fd_t *fd) +{ +	resolve->fd = fd_ref (fd); + +	return 0;  }  static int  fuse_resolve (fuse_state_t *state) - { +{          fuse_resolve_t   *resolve = NULL;          resolve = state->resolve_now; @@ -422,7 +427,7 @@ fuse_resolve (fuse_state_t *state)          } else if (!uuid_is_null (resolve->pargfid)) { -                fuse_resolve_entry (state); +                fuse_resolve_parent (state);          } else if (!uuid_is_null (resolve->gfid)) { @@ -445,17 +450,10 @@ fuse_resolve_done (fuse_state_t *state)  {          fuse_resume_fn_t fn = NULL; -        if (state->resolve.op_ret || state->resolve2.op_ret) { -                send_fuse_err (state->this, state->finh, -                               state->resolve.op_errno); -                free_fuse_state (state); -                goto out; -        }          fn = state->resume_fn; -        if (fn) -                fn (state); -out: +	fn (state); +          return 0;  } @@ -495,87 +493,24 @@ fuse_resolve_all (fuse_state_t *state)  int -fuse_gfid_set (fuse_state_t *state) +fuse_resolve_continue (fuse_state_t *state)  { -        int   ret = 0; - -        if (uuid_is_null (state->gfid)) -                goto out; - -        if (!state->dict) -                state->dict = dict_new (); +        fuse_resolve_loc_touchup (state); -        if (!state->dict) { -                ret = -1; -                goto out; -        } +        fuse_resolve_all (state); -        ret = dict_set_static_bin (state->dict, "gfid-req", -                                   state->gfid, sizeof (state->gfid)); -out: -        return ret; +        return 0;  }  int  fuse_resolve_and_resume (fuse_state_t *state, fuse_resume_fn_t fn)  { -        xlator_t *inode_xl = NULL; -        xlator_t *active_xl = NULL; -          fuse_gfid_set (state);          state->resume_fn = fn; -        active_xl = fuse_active_subvol (state->this); -        inode_xl = fuse_state_subvol (state); -        if (!inode_xl && state->loc.parent) -                inode_xl = state->loc.parent->table->xl; - -        /* If inode or fd is already in new graph, goto resume */ -        if (inode_xl == active_xl) { -                /* Lets move to resume if there is no other inode to check */ -                if (!(state->loc2.parent || state->loc2.inode)) -                        goto resume; - -                inode_xl = NULL; -                /* We have to make sure both inodes we are -                   working on are in same inode table */ -                if (state->loc2.inode) -                        inode_xl = state->loc2.inode->table->xl; -                if (!inode_xl && state->loc2.parent) -                        inode_xl = state->loc2.parent->table->xl; - -                if (inode_xl == active_xl) -                        goto resume; -        } - - -        /* If the resolve is for 'fd' and its open with 'write' flag -           set, don't switch to new graph yet */ - -        /* TODO: fix it later */ -        /* if (state->fd && ((state->fd->flags & O_RDWR) || -                          (state->fd->flags & O_WRONLY))) -        */ -        if (state->fd) -                goto resume; - -        /* -        if (state->fd) { -                state->resolve.fd = state->fd; -                state->fd = NULL; // TODO: we may need a 'fd_unref()' here, not very sure' -        } -        */ - -        /* now we have to resolve the inode to 'itable' */ -        state->itable = active_xl->itable; -          fuse_resolve_all (state);          return 0; -resume: -        fn (state); - -        return 0;  }  | 
