summaryrefslogtreecommitdiffstats
path: root/xlators/mount
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mount')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c70
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h1
-rw-r--r--xlators/mount/fuse/src/fuse-resolve.c20
3 files changed, 72 insertions, 19 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index a14de57e5a3..bf25c967909 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -72,6 +72,25 @@ out:
}
+fuse_fd_ctx_t *
+fuse_fd_ctx_get (xlator_t *this, fd_t *fd)
+{
+ fuse_fd_ctx_t *fdctx = NULL;
+ uint64_t value = 0;
+ int ret = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret < 0) {
+ goto out;
+ }
+
+ fdctx = (fuse_fd_ctx_t *) (unsigned long)value;
+
+out:
+ return fdctx;
+}
+
+
/*
* iov_out should contain a fuse_out_header at zeroth position.
* The error value of this header is sent to kernel.
@@ -587,7 +606,6 @@ fuse_fd_inherit_directio (xlator_t *this, fd_t *fd, struct fuse_open_out *foo)
int32_t ret = 0;
fuse_fd_ctx_t *fdctx = NULL, *tmp_fdctx = NULL;
fd_t *tmp_fd = NULL;
- uint64_t val = 0;
GF_VALIDATE_OR_GOTO_WITH_ERROR ("glusterfs-fuse", this, out, ret,
-EINVAL);
@@ -604,14 +622,11 @@ fuse_fd_inherit_directio (xlator_t *this, fd_t *fd, struct fuse_open_out *foo)
tmp_fd = fd_lookup (fd->inode, 0);
if (tmp_fd) {
- ret = fd_ctx_get (tmp_fd, this, &val);
- if (!ret) {
- tmp_fdctx = (fuse_fd_ctx_t *)(unsigned long)val;
- if (tmp_fdctx) {
- foo->open_flags &= ~FOPEN_DIRECT_IO;
- foo->open_flags |= (tmp_fdctx->open_flags
- & FOPEN_DIRECT_IO);
- }
+ tmp_fdctx = fuse_fd_ctx_get (this, fd);
+ if (tmp_fdctx) {
+ foo->open_flags &= ~FOPEN_DIRECT_IO;
+ foo->open_flags |= (tmp_fdctx->open_flags
+ & FOPEN_DIRECT_IO);
}
}
@@ -3528,11 +3543,11 @@ int
fuse_migrate_fd (xlator_t *this, fd_t *fd, xlator_t *old_subvol,
xlator_t *new_subvol)
{
- int ret = -1;
- loc_t loc = {0, };
- char create_in_progress = 0;
- inode_t *old_inode = NULL;
- int flags = 0;
+ int ret = -1;
+ loc_t loc = {0, };
+ char create_in_progress = 0;
+ inode_t *old_inode = NULL;
+ int flags = 0;
/* could've used pthread_cond_wait, but that requires a cond variable to
* be mainted for each fd and that is a bit too much overhead.
@@ -3573,6 +3588,7 @@ fuse_migrate_fd (xlator_t *this, fd_t *fd, xlator_t *old_subvol,
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));
@@ -3635,6 +3651,8 @@ fuse_handle_opened_fds (xlator_t *this, xlator_t *old_subvol,
fdtable_t *fdtable = NULL;
int i = 0;
fd_t *fd = NULL;
+ int32_t ret = 0;
+ fuse_fd_ctx_t *fdctx = NULL;
priv = this->private;
@@ -3645,8 +3663,28 @@ fuse_handle_opened_fds (xlator_t *this, xlator_t *old_subvol,
for (i = 0; i < count; i++) {
fd = fdentries[i].fd;
if (fd != NULL) {
- fuse_migrate_fd (this, fd, old_subvol,
- new_subvol);
+ 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;
+ }
+ } 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;
+ }
+ }
}
}
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
index afda8f77549..72aa6be48f3 100644
--- a/xlators/mount/fuse/src/fuse-bridge.h
+++ b/xlators/mount/fuse/src/fuse-bridge.h
@@ -328,6 +328,7 @@ typedef struct {
typedef struct fuse_fd_ctx {
uint32_t open_flags;
+ char migration_failed;
fd_t *fd;
} fuse_fd_ctx_t;
diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c
index 94a825e3d24..abb11dbb1d9 100644
--- a/xlators/mount/fuse/src/fuse-resolve.c
+++ b/xlators/mount/fuse/src/fuse-resolve.c
@@ -31,6 +31,8 @@ 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);
+fuse_fd_ctx_t *
+fuse_fd_ctx_get (xlator_t *this, fd_t *fd);
static int
fuse_resolve_loc_touchup (fuse_state_t *state)
@@ -330,9 +332,10 @@ fuse_resolve_inode (fuse_state_t *state)
static int
fuse_resolve_fd (fuse_state_t *state)
{
- fuse_resolve_t *resolve = NULL;
- fd_t *fd = NULL;
- xlator_t *active_subvol = NULL;
+ fuse_resolve_t *resolve = NULL;
+ fd_t *fd = NULL;
+ xlator_t *active_subvol = NULL;
+ fuse_fd_ctx_t *fdctx = NULL;
resolve = state->resolve_now;
@@ -342,6 +345,17 @@ fuse_resolve_fd (fuse_state_t *state)
if (state->active_subvol != active_subvol) {
resolve->op_ret = -1;
resolve->op_errno = EBADF;
+ }
+
+ fdctx = fuse_fd_ctx_get (state->this, fd);
+ if (fdctx != NULL) {
+ if (fdctx->migration_failed) {
+ resolve->op_ret = -1;
+ resolve->op_errno = EBADF;
+ }
+ }
+
+ if ((resolve->op_ret == -1) && (resolve->op_errno == EBADF)) {
gf_log ("fuse-resolve", GF_LOG_WARNING, "migration of fd (%p) "
"did not complete, failing fop with EBADF", fd);
}