From 8e81cbacc53adc77bc4eabb5a26d6d13012f5f86 Mon Sep 17 00:00:00 2001 From: Anand Avati Date: Mon, 30 Jan 2012 15:03:56 +0530 Subject: 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 Reviewed-by: Amar Tumballi Reviewed-by: Anand Avati --- xlators/mount/fuse/src/fuse-bridge.c | 784 ++++++++++++++-------------------- xlators/mount/fuse/src/fuse-bridge.h | 36 +- xlators/mount/fuse/src/fuse-helpers.c | 60 +-- 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 #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); @@ -103,6 +100,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, @@ -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; } -- cgit