diff options
Diffstat (limited to 'xlators/mount/fuse/src')
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 65 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.h | 4 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-resolve.c | 88 |
3 files changed, 107 insertions, 50 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index f14ccf5c1..86deaea07 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -26,7 +26,7 @@ static int gf_fuse_xattr_enotsup_log; void fini (xlator_t *this_xl); fuse_fd_ctx_t * -__fuse_fd_ctx_check_n_create (fd_t *fd, xlator_t *this) +__fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd) { uint64_t val = 0; int32_t ret = 0; @@ -54,7 +54,7 @@ __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) +fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd) { fuse_fd_ctx_t *fd_ctx = NULL; @@ -64,7 +64,7 @@ fuse_fd_ctx_check_n_create (fd_t *fd, xlator_t *this) LOCK (&fd->lock); { - fd_ctx = __fuse_fd_ctx_check_n_create (fd, this); + fd_ctx = __fuse_fd_ctx_check_n_create (this, fd); } UNLOCK (&fd->lock); @@ -618,7 +618,7 @@ fuse_fd_inherit_directio (xlator_t *this, fd_t *fd, struct fuse_open_out *foo) GF_VALIDATE_OR_GOTO_WITH_ERROR ("glusterfs-fuse", foo, out, ret, -EINVAL); - fdctx = fuse_fd_ctx_check_n_create (fd, this); + fdctx = fuse_fd_ctx_check_n_create (this, fd); if (!fdctx) { ret = -ENOMEM; goto out; @@ -3506,6 +3506,7 @@ fuse_nameless_lookup (xlator_t *xl, uuid_t gfid, loc_t *loc) int ret = -1; dict_t *xattr_req = NULL; struct iatt iatt = {0, }; + inode_t *linked_inode = NULL; if ((loc == NULL) || (xl == NULL)) { goto out; @@ -3530,7 +3531,9 @@ fuse_nameless_lookup (xlator_t *xl, uuid_t gfid, loc_t *loc) goto out; } - inode_link (loc->inode, NULL, NULL, &iatt); + linked_inode = inode_link (loc->inode, NULL, NULL, &iatt); + inode_unref (loc->inode); + loc->inode = linked_inode; ret = 0; out: @@ -3589,13 +3592,17 @@ fuse_migrate_fd (xlator_t *this, fd_t *fd, xlator_t *old_subvol, loc.path = ""; loc.name = NULL; - ret = fuse_nameless_lookup (new_subvol, fd->inode->gfid, &loc); - if (ret < 0) { - ret = -2; - gf_log ("glusterfs-fuse", GF_LOG_WARNING, - "name-less lookup of gfid (%s) failed (%s)", - uuid_utoa (fd->inode->gfid), strerror (errno)); - goto out; + loc.inode = inode_find (new_subvol->itable, fd->inode->gfid); + + if (loc.inode == NULL) { + ret = fuse_nameless_lookup (new_subvol, fd->inode->gfid, &loc); + if (ret < 0) { + gf_log ("glusterfs-fuse", GF_LOG_WARNING, + "name-less lookup of gfid (%s) failed (%s)", + uuid_utoa (fd->inode->gfid), strerror (errno)); + goto out; + } + } old_inode = fd->inode; @@ -3669,34 +3676,13 @@ fuse_handle_opened_fds (xlator_t *this, xlator_t *old_subvol, continue; ret = fuse_migrate_fd (this, fd, old_subvol, - new_subvol); - if (ret < 0) { - if (ret == -1) { - fdctx = fuse_fd_ctx_check_n_create (fd, - this); - if (fdctx != NULL) { - fdctx->migration_failed = 1; - gf_log_callingfn ("glusterfs-" - "fuse", - GF_LOG_ERROR, - "fd migration" - " for the fd " - "(%p), with" - "context (%p)" - " failed", fd, - fdctx); - } + new_subvol); + + fdctx = fuse_fd_ctx_check_n_create (this, fd); + if (fdctx) { + if (ret < 0) { + fdctx->migration_failed = 1; } else { - /* nameless lookup has failed, - * it can be identified using - * fd->inode->table->xl - * != active_subvol. so, do - * nothing - */ - } - } else { - fdctx = fuse_fd_ctx_get (this, fd); - if (fdctx != NULL) { fdctx->migration_failed = 0; } } @@ -3707,6 +3693,7 @@ fuse_handle_opened_fds (xlator_t *this, xlator_t *old_subvol, if (fd) fd_unref (fd); } + GF_FREE (fdentries); } diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h index 3711ca54d..c13c2dc76 100644 --- a/xlators/mount/fuse/src/fuse-bridge.h +++ b/xlators/mount/fuse/src/fuse-bridge.h @@ -350,8 +350,8 @@ inode_t *fuse_ino_to_inode (uint64_t ino, xlator_t *fuse); 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); -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); +fuse_fd_ctx_t * __fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd); +fuse_fd_ctx_t * fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd); 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, diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c index 5df0ac4b8..d7446a711 100644 --- a/xlators/mount/fuse/src/fuse-resolve.c +++ b/xlators/mount/fuse/src/fuse-resolve.c @@ -30,6 +30,8 @@ fuse_resolve_all (fuse_state_t *state); int fuse_resolve_continue (fuse_state_t *state); int fuse_resolve_entry_simple (fuse_state_t *state); int fuse_resolve_inode_simple (fuse_state_t *state); +int fuse_migrate_fd (xlator_t *this, fd_t *fd, xlator_t *old_subvol, + xlator_t *new_subvol); fuse_fd_ctx_t * fuse_fd_ctx_get (xlator_t *this, fd_t *fd); @@ -334,29 +336,97 @@ fuse_resolve_inode (fuse_state_t *state) return 0; } + +int +fuse_migrate_fd_task (void *data) +{ + int ret = -1; + fuse_fd_ctx_t *fdctx = NULL; + fuse_state_t *state = NULL; + + state = data; + if (state == NULL) { + goto out; + } + + ret = fuse_migrate_fd (state->this, state->fd, + state->fd->inode->table->xl, + state->active_subvol); + + fdctx = fuse_fd_ctx_check_n_create (state->this, state->fd); + if (fdctx != NULL) { + if (ret < 0) { + fdctx->migration_failed = 1; + } else { + fdctx->migration_failed = 0; + } + } + + ret = 0; + +out: + return ret; +} + + +static inline int +fuse_migrate_fd_error (xlator_t *this, fd_t *fd) +{ + fuse_fd_ctx_t *fdctx = NULL; + char error = 0; + + fdctx = fuse_fd_ctx_get (this, fd); + if (fdctx != NULL) { + if (fdctx->migration_failed) { + error = 1; + } + } + + return error; +} + + static int fuse_resolve_fd (fuse_state_t *state) { - fuse_resolve_t *resolve = NULL; - fd_t *fd = NULL; - xlator_t *active_subvol = NULL; - fuse_fd_ctx_t *fdctx = NULL; + fuse_resolve_t *resolve = NULL; + fd_t *fd = NULL; + xlator_t *active_subvol = NULL; + int ret = 0; + char fd_migration_error = 0; resolve = state->resolve_now; fd = resolve->fd; active_subvol = fd->inode->table->xl; - if (state->active_subvol != active_subvol) { + fd_migration_error = fuse_migrate_fd_error (state->this, fd); + if (fd_migration_error) { resolve->op_ret = -1; resolve->op_errno = EBADF; - } + } else if (state->active_subvol != active_subvol) { + ret = synctask_new (state->this->ctx->env, fuse_migrate_fd_task, + NULL, NULL, state); + + fd_migration_error = fuse_migrate_fd_error (state->this, fd); + + if ((ret == -1) || fd_migration_error + || (state->active_subvol != fd->inode->table->xl)) { + if (ret == -1) { + gf_log (state->this->name, GF_LOG_WARNING, + "starting sync-task to migrate fd (%p)" + " failed", fd); + } else { + gf_log (state->this->name, GF_LOG_WARNING, + "fd migration of fd (%p) failed", fd); + } - fdctx = fuse_fd_ctx_get (state->this, fd); - if (fdctx != NULL) { - if (fdctx->migration_failed) { resolve->op_ret = -1; resolve->op_errno = EBADF; + } else { + gf_log (state->this->name, GF_LOG_DEBUG, + "fd (%p) migrated successfully in resolver", + fd); } } |