summaryrefslogtreecommitdiffstats
path: root/xlators/mount/fuse/src/fuse-bridge.c
diff options
context:
space:
mode:
authorRaghavendra G <raghavendra@gluster.com>2012-04-18 12:30:17 +0530
committerAnand Avati <avati@redhat.com>2012-05-15 17:09:58 -0700
commit7503c63ee141931556cf066b9b255fc62cefcb68 (patch)
treee96959e64123841fa3788ae97c7f237435f10047 /xlators/mount/fuse/src/fuse-bridge.c
parent4b94890c9777e7d78881d6c72ff739c91a9d3e99 (diff)
fuse-resolve: Attempt fd-migration in resolver, if migration
was never attempted. Since fd is always associated with an inode, we can create an fd only after resolver resolves an inode. So, there is a possibility that graph-switch can happen after resolver kicks in, but before it can complete, thereby resulting in the newly created fd not migrated to new graph. So, instead of migrating fds only during graph-switch, we give a second chance during fd-resolution. As an example, consider following sequence of events during a create call: 1. create wants to resolve parent inode, hence it starts resolution for parent 2. graph-switch happens (it can happen since fuse-request reader thread returns after winding lookup calls) 3. fd-migration of all the fds which are currently in fdtable is attempted (Note that the fd corresponding to current create call is not yet created and added to fd-table, hence it will not be migrated as part of graph switch) 4. resolution of parent triggered as part of create, completes 5. fd is created in fuse_create_resume and this fd is not migrated to new graph 6. Any future fops on this fd will fail with EBADF errors (create call itself will succeed) Change-Id: Iae06ecfaca24eaacb2e166ffefbbbb57446332ba BUG: 804592 Signed-off-by: Raghavendra G <raghavendra@gluster.com> Reviewed-on: http://review.gluster.com/3181 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators/mount/fuse/src/fuse-bridge.c')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c65
1 files changed, 26 insertions, 39 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);
}