diff options
author | Raghavendra G <raghavendra@gluster.com> | 2012-05-14 14:23:56 +0530 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2012-08-03 01:13:36 -0700 |
commit | 66205114267ec659b4ad8084c7e9497009529c61 (patch) | |
tree | 1ad8e04f505cb1adfc6021acb9fb372a9c3827dd | |
parent | 8a1dedca925fe99860f61b554b7c86d8c1302596 (diff) |
mount/fuse: ignore any erros that might've happened while resolving entry in resolver.
One error we hit was absence of gfid on backend. While the lookup
code-path generates a new uuid and sets it on file, resolver code
doesn't do that. Since, functionally (atleast after resolving parent
inode, we would be resolving the path in new-graph) both resolver
and lookup does same work, it would be no harm in ignoring errors
during resolving the entry. This would help us to continue with
the _extra_ work (like healing gfid as of now) in fuse_lookup_resume.
Change-Id: If46d5e07c32e67b5744287a6ef55d0b0fe347689
BUG: 821138
Signed-off-by: Raghavendra G <raghavendra@gluster.com>
Reviewed-on: http://review.gluster.com/3344
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 8 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.h | 115 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-resolve.c | 19 |
3 files changed, 117 insertions, 25 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 124cca14eab..fc294e7a8a5 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -432,6 +432,14 @@ fuse_lookup_resume (fuse_state_t *state) return; } + /* parent was resolved, entry could not, may be a missing gfid? + * Hence try to do a regular lookup + */ + if ((state->resolve.op_ret == -2) + && (state->resolve.op_errno == ENODATA)) { + state->resolve.op_ret = 0; + } + if (state->loc.inode) { gf_log ("glusterfs-fuse", GF_LOG_TRACE, "%"PRIu64": LOOKUP %s(%s)", state->finh->unique, diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h index cb5eb600147..055cbd3110c 100644 --- a/xlators/mount/fuse/src/fuse-bridge.h +++ b/xlators/mount/fuse/src/fuse-bridge.h @@ -145,9 +145,9 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t; #define FUSE_FOP(state, ret, op_num, fop, args ...) \ do { \ - call_frame_t *frame = NULL; \ - xlator_t *xl = NULL; \ - int32_t op_ret = 0, op_errno = 0; \ + call_frame_t *frame = NULL; \ + xlator_t *xl = NULL; \ + int32_t op_ret = 0, op_errno = 0; \ \ frame = get_call_frame_for_req (state); \ if (!frame) { \ @@ -177,26 +177,46 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t; xl = state->active_subvol; \ if (!xl) { \ gf_log_callingfn ("glusterfs-fuse", GF_LOG_ERROR, \ - "xl is NULL"); \ + "xl is NULL"); \ op_errno = ENOENT; \ op_ret = -1; \ } else if (state->resolve.op_ret < 0) { \ - op_errno = state->resolve.op_errno; \ - op_ret = -1; \ -/* gf_log_callingfn ("glusterfs-fuse", GF_LOG_WARNING, \ - "resolve failed (%s)", \ - strerror (op_errno)); */ \ - } else if (state->resolve2.op_ret < 0) { \ - op_errno = state->resolve2.op_errno; \ - op_ret = -1; \ - /* gf_log_callingfn ("glusterfs-fuse", GF_LOG_WARNING, \ - "resolve of second entity " \ - "failed (%s)", \ - strerror (op_errno)); */ \ - } \ - \ - if (op_ret < 0) { \ - send_fuse_err (state->this, state->finh, op_errno); \ + op_errno = state->resolve.op_errno; \ + op_ret = -1; \ + if (op_num == GF_FOP_LOOKUP) { \ + gf_log ("glusterfs-fuse", \ + (op_errno == ENOENT ? GF_LOG_TRACE \ + : GF_LOG_WARNING), \ + "%"PRIu64": %s() %s => -1 (%s)", \ + frame->root->unique, \ + gf_fop_list[frame->root->op], \ + state->resolve.resolve_loc.path, \ + strerror (op_errno)); \ + } else { \ + gf_log ("glusterfs-fuse", \ + GF_LOG_WARNING, \ + "%"PRIu64": %s() inode " \ + "migration of %s failed (%s)", \ + frame->root->unique, \ + gf_fop_list[frame->root->op], \ + state->resolve.resolve_loc.path, \ + strerror (op_errno)); \ + } \ + } else if (state->resolve2.op_ret < 0) { \ + op_errno = state->resolve2.op_errno; \ + op_ret = -1; \ + gf_log ("glusterfs-fuse", \ + GF_LOG_WARNING, \ + "%"PRIu64": %s() inode " \ + "migration of %s failed (%s)", \ + frame->root->unique, \ + gf_fop_list[frame->root->op], \ + state->resolve2.resolve_loc.path, \ + strerror (op_errno)); \ + } \ + \ + if (op_ret < 0) { \ + send_fuse_err (state->this, state->finh, op_errno); \ free_fuse_state (state); \ STACK_DESTROY (frame->root); \ } else { \ @@ -208,7 +228,9 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t; #define FUSE_FOP_COOKIE(state, xl, ret, cky, op_num, fop, args ...) \ do { \ - call_frame_t *frame = NULL; \ + call_frame_t *frame = NULL; \ + xlator_t *xl = NULL; \ + int32_t op_ret = 0, op_errno = 0; \ \ frame = get_call_frame_for_req (state); \ if (!frame) { \ @@ -226,7 +248,56 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t; frame->root->state = state; \ frame->root->op = op_num; \ frame->op = op_num; \ - STACK_WIND_COOKIE (frame, ret, cky, xl, xl->fops->fop, args); \ + \ + xl = state->active_subvol; \ + if (!xl) { \ + gf_log_callingfn ("glusterfs-fuse", GF_LOG_ERROR, \ + "xl is NULL"); \ + op_errno = ENOENT; \ + op_ret = -1; \ + } else if (state->resolve.op_ret < 0) { \ + op_errno = state->resolve.op_errno; \ + op_ret = -1; \ + if (op_num == GF_FOP_LOOKUP) { \ + gf_log ("glusterfs-fuse", \ + (op_errno == ENOENT ? GF_LOG_TRACE \ + : GF_LOG_WARNING), \ + "%"PRIu64": %s() %s => -1 (%s)", \ + frame->root->unique, \ + gf_fop_list[frame->root->op], \ + state->resolve.resolve_loc.path, \ + strerror (op_errno)); \ + } else { \ + gf_log ("glusterfs-fuse", \ + GF_LOG_WARNING, \ + "%"PRIu64": %s() inode " \ + "migration of %s failed (%s)", \ + frame->root->unique, \ + gf_fop_list[frame->root->op], \ + state->resolve.resolve_loc.path, \ + strerror (op_errno)); \ + } \ + } else if (state->resolve2.op_ret < 0) { \ + op_errno = state->resolve2.op_errno; \ + op_ret = -1; \ + gf_log ("glusterfs-fuse", \ + GF_LOG_WARNING, \ + "%"PRIu64": %s() inode " \ + "migration of %s failed (%s)", \ + frame->root->unique, \ + gf_fop_list[frame->root->op], \ + state->resolve2.resolve_loc.path, \ + strerror (op_errno)); \ + } \ + \ + if (op_ret < 0) { \ + send_fuse_err (state->this, state->finh, op_errno); \ + free_fuse_state (state); \ + STACK_DESTROY (frame->root); \ + } else { \ + STACK_WIND_COOKIE (frame, ret, cky, xl, xl->fops->fop, \ + args); \ + } \ } while (0) #define GF_SELECT_LOG_LEVEL(_errno) \ diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c index 9e4bef0b138..62ee456f8f9 100644 --- a/xlators/mount/fuse/src/fuse-resolve.c +++ b/xlators/mount/fuse/src/fuse-resolve.c @@ -98,6 +98,7 @@ fuse_resolve_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this, resolve_loc->name, buf); state->loc_now->inode = link_inode; + out: loc_wipe (resolve_loc); @@ -132,8 +133,8 @@ fuse_resolve_entry (fuse_state_t *state) 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) + 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; @@ -153,7 +154,19 @@ fuse_resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this, uuid_utoa (resolve->resolve_loc.gfid), strerror (op_errno)); loc_wipe (&resolve->resolve_loc); - resolve->op_ret = -1; + + /* resolve->op_ret can have 3 values: 0, -1, -2. + * 0 : resolution was successful. + * -1: parent inode could not be resolved. + * -2: entry (inode corresponding to path) could not be resolved + */ + + if (uuid_is_null (resolve->gfid)) { + resolve->op_ret = -1; + } else { + resolve->op_ret = -2; + } + resolve->op_errno = op_errno; goto out; } |