summaryrefslogtreecommitdiffstats
path: root/xlators/mount/fuse
diff options
context:
space:
mode:
authorAnand Avati <avati@redhat.com>2012-01-30 15:03:56 +0530
committerAnand Avati <avati@gluster.com>2012-02-08 03:13:08 -0800
commit8e81cbacc53adc77bc4eabb5a26d6d13012f5f86 (patch)
tree4788e3a14fb2d276689c4423cc7542f0d72c3348 /xlators/mount/fuse
parentaec6d5d89249868dc99d8fb432d8ab120bb38ef1 (diff)
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 <jenkins@build.gluster.com> Reviewed-by: Amar Tumballi <amar@gluster.com> Reviewed-by: Anand Avati <avati@gluster.com>
Diffstat (limited to 'xlators/mount/fuse')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c784
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h36
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c60
-rw-r--r--xlators/mount/fuse/src/fuse-resolve.c431
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 72bb1b15761..6537c0bcc83 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 4d80af57412..489e6d6456d 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 2070447faa3..81994ad9614 100644
--- a/xlators/mount/fuse/src/fuse-helpers.c
+++ b/xlators/mount/fuse/src/fuse-helpers.c
@@ -24,41 +24,10 @@
#include <sys/sysctl.h>
#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 755e2f429f1..1af80b93c57 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);
@@ -104,6 +101,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,
dict_t *xattr, struct iatt *postparent)
@@ -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;
}