diff options
author | Amar Tumballi <amar@gluster.com> | 2011-01-13 06:55:37 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2011-02-22 02:12:02 -0800 |
commit | b2d94417764ca5462cbdcdd634ea45ba12c8877f (patch) | |
tree | 5dfed708d2eaca891462401cae817d27425674f6 /xlators/mount/fuse/src | |
parent | 23d9783a192669b638d42b8dd127ad69ea36f950 (diff) |
fuse-resolve: correction in resolve logic
* bring in soft (gfid based) and hard (path based) resolving
* 'fd' resolving to new graph is not yet done.
* fuse-resolve works similar to server-resolve
Signed-off-by: Amar Tumballi <amar@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 2281 (I/O operations exit when add-brick is done)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2281
Diffstat (limited to 'xlators/mount/fuse/src')
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 102 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.h | 18 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-helpers.c | 4 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-resolve.c | 253 |
4 files changed, 286 insertions, 91 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 44340e992f1..affa37d5b31 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -258,8 +258,7 @@ 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 (ret < 0) { + 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); @@ -273,6 +272,7 @@ fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg) "%"PRIu64": LOOKUP %s(%"PRId64")", finh->unique, state->loc.path, state->loc.inode->ino); state->is_revalidate = 1; + memcpy (state->resolve.gfid, state->loc.inode->gfid, 16); } else { gf_log ("glusterfs-fuse", GF_LOG_TRACE, "%"PRIu64": LOOKUP %s", finh->unique, @@ -280,6 +280,10 @@ fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg) uuid_generate (state->gfid); } + memcpy (state->resolve.pargfid, state->loc.parent->gfid, 16); + state->resolve.bname = gf_strdup (name); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_lookup_resume); } @@ -513,6 +517,8 @@ fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg) state->fd = NULL; } + memcpy (state->resolve.gfid, state->loc.inode->gfid, 16); + state->resolve.path = gf_strdup (state->loc.path); fuse_resolve_and_resume (state, fuse_getattr_resume); } @@ -804,6 +810,9 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg) state->size = fsi->size; } + memcpy (state->resolve.gfid, state->loc.inode->gfid, 16); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_setattr_resume); } @@ -936,6 +945,9 @@ fuse_access (xlator_t *this, fuse_in_header_t *finh, void *msg) state->mask = fai->mask; + memcpy (state->resolve.gfid, state->loc.inode->gfid, 16); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_access_resume); return; } @@ -1004,6 +1016,9 @@ fuse_readlink (xlator_t *this, fuse_in_header_t *finh, void *msg) return; } + memcpy (state->resolve.gfid, state->loc.inode->gfid, 16); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_readlink_resume); return; @@ -1057,7 +1072,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 (ret < 0) { + 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); @@ -1069,6 +1084,10 @@ fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg) state->mode = fmi->mode; state->rdev = fmi->rdev; + memcpy (state->resolve.pargfid, state->loc.parent->gfid, 16); + state->resolve.bname = gf_strdup (name); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_mknod_resume); return; @@ -1114,7 +1133,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 (ret < 0) { + 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); @@ -1125,6 +1144,10 @@ fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg) state->mode = fmi->mode; + memcpy (state->resolve.pargfid, state->loc.parent->gfid, 16); + state->resolve.bname = gf_strdup (name); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_mkdir_resume); return; @@ -1158,7 +1181,7 @@ fuse_unlink (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 (ret < 0) { + 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); @@ -1167,6 +1190,10 @@ fuse_unlink (xlator_t *this, fuse_in_header_t *finh, void *msg) return; } + memcpy (state->resolve.pargfid, state->loc.parent->gfid, 16); + state->resolve.bname = gf_strdup (name); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_unlink_resume); return; @@ -1200,7 +1227,7 @@ fuse_rmdir (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 (ret < 0) { + 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); @@ -1209,6 +1236,10 @@ fuse_rmdir (xlator_t *this, fuse_in_header_t *finh, void *msg) return; } + memcpy (state->resolve.pargfid, state->loc.parent->gfid, 16); + state->resolve.bname = gf_strdup (name); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_rmdir_resume); return; } @@ -1253,7 +1284,7 @@ fuse_symlink (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 (ret < 0) { + 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); @@ -1263,6 +1294,11 @@ fuse_symlink (xlator_t *this, fuse_in_header_t *finh, void *msg) } state->name = gf_strdup (linkname); + + memcpy (state->resolve.pargfid, state->loc.parent->gfid, 16); + state->resolve.bname = gf_strdup (name); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_symlink_resume); return; } @@ -1345,7 +1381,7 @@ fuse_rename (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, oldname); - if (ret < 0) { + 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, @@ -1357,7 +1393,7 @@ fuse_rename (xlator_t *this, fuse_in_header_t *finh, void *msg) } ret = fuse_loc_fill (&state->loc2, state, 0, fri->newdir, newname); - if (ret < 0) { + 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, @@ -1368,6 +1404,14 @@ fuse_rename (xlator_t *this, fuse_in_header_t *finh, void *msg) return; } + memcpy (state->resolve.pargfid, state->loc.parent->gfid, 16); + state->resolve.bname = gf_strdup (oldname); + state->resolve.path = gf_strdup (state->loc.path); + + memcpy (state->resolve2.pargfid, state->loc2.parent->gfid, 16); + state->resolve2.bname = gf_strdup (newname); + state->resolve2.path = gf_strdup (state->loc2.path); + fuse_resolve_and_resume (state, fuse_rename_resume); return; @@ -1408,17 +1452,22 @@ fuse_link (xlator_t *this, fuse_in_header_t *finh, void *msg) ret = fuse_loc_fill (&state->loc2, state, fli->oldnodeid, 0, NULL); - if ((state->loc2.inode == NULL) || - (ret < 0)) { + if (!state->loc2.inode || (ret < 0) || !state->loc.parent) { gf_log ("glusterfs-fuse", GF_LOG_WARNING, - "fuse_loc_fill() failed for %s %"PRIu64": LINK %s %s", - state->loc2.path, finh->unique, - state->loc2.path, state->loc.path); + "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; } + memcpy (state->resolve.pargfid, state->loc.parent->gfid, 16); + state->resolve.bname = gf_strdup (name); + state->resolve.path = gf_strdup (state->loc.path); + + memcpy (state->resolve2.gfid, state->loc2.inode->gfid, 16); + state->resolve2.path = gf_strdup (state->loc2.path); + fuse_resolve_and_resume (state, fuse_link_resume); return; @@ -1580,7 +1629,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 (ret < 0) { + 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); @@ -1592,6 +1641,10 @@ fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg) state->mode = fci->mode; state->flags = fci->flags; + memcpy (state->resolve.pargfid, state->loc.parent->gfid, 16); + state->resolve.bname = gf_strdup (name); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_create_resume); return; @@ -1645,6 +1698,10 @@ fuse_open (xlator_t *this, fuse_in_header_t *finh, void *msg) } state->flags = foi->flags; + + memcpy (state->resolve.gfid, state->loc.inode->gfid, 16); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_open_resume); return; @@ -1967,6 +2024,9 @@ fuse_opendir (xlator_t *this, fuse_in_header_t *finh, void *msg) return; } + memcpy (state->resolve.gfid, state->loc.inode->gfid, 16); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_opendir_resume); } @@ -2331,6 +2391,9 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg) state->flags = fsi->flags; state->name = gf_strdup (name); + memcpy (state->resolve.gfid, state->loc.inode->gfid, 16); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_setxattr_resume); return; @@ -2517,6 +2580,9 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg) state->size = fgxi->size; state->name = gf_strdup (name); + memcpy (state->resolve.gfid, state->loc.inode->gfid, 16); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_getxattr_resume); return; } @@ -2555,6 +2621,9 @@ fuse_listxattr (xlator_t *this, fuse_in_header_t *finh, void *msg) } state->size = fgxi->size; + memcpy (state->resolve.gfid, state->loc.inode->gfid, 16); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_listxattr_resume); return; @@ -2594,6 +2663,9 @@ fuse_removexattr (xlator_t *this, fuse_in_header_t *finh, void *msg) } state->name = gf_strdup (name); + memcpy (state->resolve.gfid, state->loc.inode->gfid, 16); + state->resolve.path = gf_strdup (state->loc.path); + fuse_resolve_and_resume (state, fuse_removexattr_resume); return; } diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h index c51733fcb72..c6462c7ed82 100644 --- a/xlators/mount/fuse/src/fuse-bridge.h +++ b/xlators/mount/fuse/src/fuse-bridge.h @@ -208,9 +208,9 @@ typedef enum { RESOLVE_MAY, RESOLVE_DONTCARE, RESOLVE_EXACT -} gf_resolve_type_t; +} fuse_resolve_type_t; -struct gf_resolve_comp { +struct fuse_resolve_comp { char *basename; ino_t ino; uint64_t gen; @@ -218,20 +218,22 @@ struct gf_resolve_comp { }; typedef struct { - gf_resolve_type_t type; + 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]; + u_char pargfid[16]; char *resolved; int op_ret; int op_errno; loc_t deep_loc; - struct gf_resolve_comp *components; + struct fuse_resolve_comp *components; int comp_count; -} gf_resolve_t; +} fuse_resolve_t; typedef struct { @@ -255,11 +257,11 @@ typedef struct { /* used within resolve_and_resume */ /* */ - gf_resolve_t resolve; - gf_resolve_t resolve2; + fuse_resolve_t resolve; + fuse_resolve_t resolve2; loc_t *loc_now; - gf_resolve_t *resolve_now; + fuse_resolve_t *resolve_now; void *resume_fn; diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c index ec2cfe29601..cd35d719214 100644 --- a/xlators/mount/fuse/src/fuse-helpers.c +++ b/xlators/mount/fuse/src/fuse-helpers.c @@ -50,9 +50,9 @@ fuse_active_subvol (xlator_t *fuse) static void -fuse_resolve_wipe (gf_resolve_t *resolve) +fuse_resolve_wipe (fuse_resolve_t *resolve) { - struct gf_resolve_comp *comp = NULL; + struct fuse_resolve_comp *comp = NULL; if (resolve->path) GF_FREE ((void *)resolve->path); diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c index e89b4423151..b13cb360641 100644 --- a/xlators/mount/fuse/src/fuse-resolve.c +++ b/xlators/mount/fuse/src/fuse-resolve.c @@ -25,9 +25,9 @@ #include "fuse-bridge.h" static int -gf_resolve_all (fuse_state_t *state); +fuse_resolve_all (fuse_state_t *state); static int -resolve_path_simple (fuse_state_t *state); +fuse_resolve_path_simple (fuse_state_t *state); static int component_count (const char *path) @@ -48,9 +48,9 @@ static int prepare_components (fuse_state_t *state) { xlator_t *active_xl = NULL; - gf_resolve_t *resolve = NULL; + fuse_resolve_t *resolve = NULL; char *resolved = NULL; - struct gf_resolve_comp *components = NULL; + struct fuse_resolve_comp *components = NULL; char *trav = NULL; int count = 0; int i = 0; @@ -87,9 +87,9 @@ out: static int -resolve_loc_touchup (fuse_state_t *state) +fuse_resolve_loc_touchup (fuse_state_t *state) { - gf_resolve_t *resolve = NULL; + fuse_resolve_t *resolve = NULL; loc_t *loc = NULL; char *path = NULL; int ret = 0; @@ -129,7 +129,7 @@ fuse_resolve_newfd_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd) { fuse_state_t *state = NULL; - gf_resolve_t *resolve = NULL; + fuse_resolve_t *resolve = NULL; fd_t *old_fd = NULL; fd_t *tmp_fd = NULL; uint64_t tmp_fd_ctx = 0; @@ -163,14 +163,14 @@ fuse_resolve_newfd_cbk (call_frame_t *frame, void *cookie, xlator_t *this, gf_log ("resolve", GF_LOG_WARNING, "failed to set the fd ctx with resolved fd"); out: - gf_resolve_all (state); + fuse_resolve_all (state); return 0; } static void -gf_resolve_new_fd (fuse_state_t *state) +fuse_resolve_new_fd (fuse_state_t *state) { - gf_resolve_t *resolve = NULL; + fuse_resolve_t *resolve = NULL; fd_t *new_fd = NULL; fd_t *fd = NULL; @@ -189,9 +189,9 @@ gf_resolve_new_fd (fuse_state_t *state) } static int -resolve_deep_continue (fuse_state_t *state) +fuse_resolve_deep_continue (fuse_state_t *state) { - gf_resolve_t *resolve = NULL; + fuse_resolve_t *resolve = NULL; int ret = 0; resolve = state->resolve_now; @@ -200,32 +200,32 @@ resolve_deep_continue (fuse_state_t *state) resolve->op_errno = 0; if (resolve->path) - ret = resolve_path_simple (state); + ret = fuse_resolve_path_simple (state); if (ret) gf_log ("resolve", GF_LOG_TRACE, "return value of resolve_*_simple %d", ret); - resolve_loc_touchup (state); + fuse_resolve_loc_touchup (state); /* This function is called by either fd resolve or inode resolve */ if (!resolve->fd) - gf_resolve_all (state); + fuse_resolve_all (state); else - gf_resolve_new_fd (state); + fuse_resolve_new_fd (state); return 0; } static int -resolve_deep_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +fuse_resolve_deep_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) { xlator_t *active_xl = NULL; fuse_state_t *state = NULL; - gf_resolve_t *resolve = NULL; - struct gf_resolve_comp *components = NULL; + fuse_resolve_t *resolve = NULL; + struct fuse_resolve_comp *components = NULL; inode_t *link_inode = NULL; int i = 0; @@ -269,22 +269,22 @@ resolve_deep_cbk (call_frame_t *frame, void *cookie, xlator_t *this, resolve->deep_loc.inode = inode_new (active_xl->itable); resolve->deep_loc.name = components[i].basename; - FUSE_FOP_COOKIE (state, active_xl, resolve_deep_cbk, (void *)(long)i, + FUSE_FOP_COOKIE (state, active_xl, fuse_resolve_deep_cbk, (void *)(long)i, GF_FOP_LOOKUP, lookup, &resolve->deep_loc, NULL); return 0; get_out_of_here: - resolve_deep_continue (state); + fuse_resolve_deep_continue (state); return 0; } static int -resolve_path_deep (fuse_state_t *state) +fuse_resolve_path_deep (fuse_state_t *state) { xlator_t *active_xl = NULL; - gf_resolve_t *resolve = NULL; - struct gf_resolve_comp *components = NULL; + fuse_resolve_t *resolve = NULL; + struct fuse_resolve_comp *components = NULL; inode_t *inode = NULL; long i = 0; @@ -317,21 +317,21 @@ resolve_path_deep (fuse_state_t *state) resolve->deep_loc.inode = inode_new (active_xl->itable); resolve->deep_loc.name = components[i].basename; - FUSE_FOP_COOKIE (state, active_xl, resolve_deep_cbk, (void *)(long)i, + FUSE_FOP_COOKIE (state, active_xl, fuse_resolve_deep_cbk, (void *)(long)i, GF_FOP_LOOKUP, lookup, &resolve->deep_loc, NULL); return 0; resolved: - resolve_deep_continue (state); + fuse_resolve_deep_continue (state); return 0; } static int -resolve_path_simple (fuse_state_t *state) +fuse_resolve_path_simple (fuse_state_t *state) { - gf_resolve_t *resolve = NULL; - struct gf_resolve_comp *components = NULL; + fuse_resolve_t *resolve = NULL; + struct fuse_resolve_comp *components = NULL; int ret = -1; int par_idx = 0; int ino_idx = 0; @@ -387,10 +387,140 @@ out: > 0 - indecisive, need to perform deep resolution */ +int +fuse_resolve_entry_simple (fuse_state_t *state) +{ + xlator_t *active_xl = NULL; + xlator_t *this = NULL; + fuse_resolve_t *resolve = NULL; + inode_t *parent = NULL; + inode_t *inode = NULL; + int ret = 0; + + this = state->this; + resolve = state->resolve_now; + + active_xl = fuse_active_subvol (state->this); + + parent = inode_find (active_xl->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 */ + state->loc_now->parent = inode_ref (parent); + + inode = inode_grep (active_xl->itable, parent, resolve->bname); + if (!inode) { + resolve->op_ret = -1; + resolve->op_errno = ENOENT; + ret = 1; + goto out; + } + + ret = 0; + + state->loc_now->inode = inode_ref (inode); + +out: + if (parent) + inode_unref (parent); + + if (inode) + inode_unref (inode); + + return ret; +} + + +int +fuse_resolve_entry (fuse_state_t *state) +{ + int ret = 0; + loc_t *loc = NULL; + + loc = state->loc_now; + + ret = fuse_resolve_entry_simple (state); + if (ret > 0) { + loc_wipe (loc); + fuse_resolve_path_deep (state); + return 0; + } + + if (ret == 0) + fuse_resolve_loc_touchup (state); + + fuse_resolve_all (state); + + return 0; +} + + +int +fuse_resolve_inode_simple (fuse_state_t *state) +{ + xlator_t *active_xl = NULL; + fuse_resolve_t *resolve = NULL; + inode_t *inode = NULL; + int ret = 0; + + resolve = state->resolve_now; + active_xl = fuse_active_subvol (state->this); + + inode = inode_find (active_xl->itable, resolve->gfid); + if (!inode) { + resolve->op_ret = -1; + resolve->op_errno = ENOENT; + ret = 1; + goto out; + } + + ret = 0; + + state->loc_now->inode = inode_ref (inode); + +out: + if (inode) + inode_unref (inode); + + return ret; +} + + +int +fuse_resolve_inode (fuse_state_t *state) +{ + int ret = 0; + loc_t *loc = NULL; + + loc = state->loc_now; + + ret = fuse_resolve_inode_simple (state); + + if (ret > 0) { + loc_wipe (loc); + fuse_resolve_path_deep (state); + return 0; + } + + if (ret == 0) + fuse_resolve_loc_touchup (state); + + fuse_resolve_all (state); + + return 0; +} + static int -gf_resolve_fd (fuse_state_t *state) +fuse_resolve_fd (fuse_state_t *state) { - gf_resolve_t *resolve = NULL; + fuse_resolve_t *resolve = NULL; fd_t *fd = NULL; int ret = 0; uint64_t tmp_fd_ctx = 0; @@ -405,7 +535,7 @@ gf_resolve_fd (fuse_state_t *state) if (!ret) { state->fd = (fd_t *)(long)tmp_fd_ctx; fd_ref (state->fd); - gf_resolve_all (state); + fuse_resolve_all (state); goto out; } @@ -423,7 +553,7 @@ gf_resolve_fd (fuse_state_t *state) state->loc_now = &state->loc; - resolve_path_deep (state); + fuse_resolve_path_deep (state); out: return 0; @@ -431,26 +561,34 @@ out: static int -gf_resolve (fuse_state_t *state) +fuse_resolve (fuse_state_t *state) { - gf_resolve_t *resolve = NULL; + fuse_resolve_t *resolve = NULL; resolve = state->resolve_now; - if (resolve->path) { + if (resolve->fd) { + + fuse_resolve_fd (state); + + } else if (!uuid_is_null (resolve->pargfid)) { + + fuse_resolve_entry (state); + + } else if (!uuid_is_null (resolve->gfid)) { - resolve_path_deep (state); + fuse_resolve_inode (state); - } else if (resolve->fd) { + } else if (resolve->path) { - gf_resolve_fd (state); + fuse_resolve_path_deep (state); } else { resolve->op_ret = 0; resolve->op_errno = EINVAL; - gf_resolve_all (state); + fuse_resolve_all (state); } return 0; @@ -458,7 +596,7 @@ gf_resolve (fuse_state_t *state) static int -gf_resolve_done (fuse_state_t *state) +fuse_resolve_done (fuse_state_t *state) { fuse_resume_fn_t fn = NULL; @@ -482,25 +620,25 @@ out: * state->resolve_now is used to decide which location/fd is to be resolved now */ static int -gf_resolve_all (fuse_state_t *state) +fuse_resolve_all (fuse_state_t *state) { if (state->resolve_now == NULL) { state->resolve_now = &state->resolve; state->loc_now = &state->loc; - gf_resolve (state); + fuse_resolve (state); } else if (state->resolve_now == &state->resolve) { state->resolve_now = &state->resolve2; state->loc_now = &state->loc2; - gf_resolve (state); + fuse_resolve (state); } else if (state->resolve_now == &state->resolve2) { - gf_resolve_done (state); + fuse_resolve_done (state); } else { gf_log ("fuse-resolve", GF_LOG_ERROR, @@ -563,31 +701,14 @@ fuse_resolve_and_resume (fuse_state_t *state, fuse_resume_fn_t fn) if (state->fd) goto resume; - if (state->loc.path) { - state->resolve.path = gf_strdup (state->loc.path); - state->resolve.bname = gf_strdup (state->loc.name); - /* TODO: make sure there is no leaks in inode refs */ - //loc_wipe (&state->loc); - state->loc.inode = NULL; - state->loc.parent = NULL; - } - - /* Needed for rename and link */ - if (state->loc2.path) { - state->resolve2.path = gf_strdup (state->loc2.path); - state->resolve2.bname = gf_strdup (state->loc2.name); - //loc_wipe (&state->loc2); - state->loc2.inode = NULL; - state->loc2.parent = NULL; - } - + /* if (state->fd) { state->resolve.fd = state->fd; - /* TODO: check if its a leak, if yes, then do 'unref' */ - state->fd = NULL; + state->fd = NULL; // TODO: we may need a 'fd_unref()' here, not very sure' } + */ - gf_resolve_all (state); + fuse_resolve_all (state); return 0; resume: |