summaryrefslogtreecommitdiffstats
path: root/xlators/mount
diff options
context:
space:
mode:
authorAnand V. Avati <avati@blackhole.gluster.com>2009-10-18 13:35:15 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-10-18 12:15:46 -0700
commit3d09fb99093a84a303edc443b68bdf9eb10096b4 (patch)
tree9a95c17069123bd7cb16e21f7a026deb6498afc9 /xlators/mount
parent7e831d735e3746fa9e6ec2e797e1a7f68ac5c148 (diff)
fuse: use inode_t address as nodeid and use new inode API
Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 315 (generation number support) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=315
Diffstat (limited to 'xlators/mount')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c329
1 files changed, 105 insertions, 224 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 7ff2a9b2de3..49190ea5cdb 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -365,6 +365,30 @@ send_fuse_err (xlator_t *this, fuse_in_header_t *finh, int error)
return send_fuse_iov (this, finh, &iov_out, 1);
}
+static inode_t *
+fuse_ino_to_inode (fuse_ino_t ino, inode_table_t *table)
+{
+ inode_t *inode = NULL;
+
+ if (ino == 1) {
+ inode = table->root;
+ } else {
+ inode = (inode_t *) (unsigned long) ino;
+ inode_ref (inode);
+ }
+
+ return inode;
+}
+
+static fuse_ino_t
+inode_to_nodeid (inode_t *inode)
+{
+ if (!inode || inode->ino == 1)
+ return 1;
+
+ return (unsigned long) inode;
+}
+
GF_MUST_CHECK static int32_t
fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
@@ -380,56 +404,62 @@ fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
inode = loc->inode;
- if (!inode) {
- if (ino)
- inode = inode_search (state->itable, ino, NULL);
- if (par && name)
- inode = inode_search (state->itable, par, name);
-
- loc->inode = inode;
- if (inode)
- loc->ino = inode->ino;
- }
+ if (name) {
+ parent = loc->parent;
+ if (!parent) {
+ parent = fuse_ino_to_inode (par, state->itable);
+ loc->parent = parent;
+ }
- parent = loc->parent;
- if (!parent) {
- if (inode)
- parent = inode_parent (inode, par, name);
- else
- parent = inode_search (state->itable, par, NULL);
- loc->parent = parent;
- }
+ inode = loc->inode;
+ if (!inode) {
+ inode = inode_grep (state->itable, parent, name);
+ loc->inode = inode;
+ }
- if (name && parent) {
ret = inode_path (parent, name, &path);
if (ret <= 0) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
"inode_path failed for %"PRId64"/%s",
parent->ino, name);
goto fail;
- } else {
- loc->path = path;
}
- } else if (inode) {
+ loc->path = path;
+ } else {
+ inode = loc->inode;
+ if (!inode) {
+ inode = fuse_ino_to_inode (ino, state->itable);
+ loc->inode = inode;
+ }
+
+ parent = loc->parent;
+ if (!parent) {
+ parent = inode_parent (inode, par, name);
+ loc->parent = parent;
+ }
+
ret = inode_path (inode, NULL, &path);
if (ret <= 0) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
"inode_path failed for %"PRId64,
inode->ino);
goto fail;
- } else {
- loc->path = path;
}
+ loc->path = path;
}
+
+ if (inode)
+ loc->ino = inode->ino;
+
if (loc->path) {
loc->name = strrchr (loc->path, '/');
if (loc->name)
loc->name++;
- else loc->name = "";
+ else
+ loc->name = "";
}
- if ((ino != 1) &&
- (parent == NULL)) {
+ if ((ino != 1) && (parent == NULL)) {
gf_log ("fuse-bridge", GF_LOG_DEBUG,
"failed to search parent for %"PRId64"/%s (%"PRId64")",
(ino_t)par, name, (ino_t)ino);
@@ -442,34 +472,6 @@ fail:
}
-static int
-need_fresh_lookup (int32_t op_ret, int32_t op_errno,
- loc_t *loc, struct stat *buf)
-{
- if (op_ret == -1) {
- gf_log ("fuse-bridge", GF_LOG_DEBUG,
- "revalidate of %s failed (%s)",
- loc->path, strerror (op_errno));
- return 1;
- }
-
- if (loc->inode->ino != buf->st_ino) {
- gf_log ("fuse-bridge", GF_LOG_DEBUG,
- "inode num of %s changed %"PRId64" -> %"PRId64,
- loc->path, loc->inode->ino, buf->st_ino);
- return 1;
- }
-
- if ((loc->inode->st_mode & S_IFMT) ^ (buf->st_mode & S_IFMT)) {
- gf_log ("fuse-bridge", GF_LOG_DEBUG,
- "inode mode of %s changed 0%o -> 0%o",
- loc->path, loc->inode->st_mode, buf->st_mode);
- return 1;
- }
-
- return 0;
-}
-
/* courtesy of folly */
static void
stat2attr (struct stat *st, struct fuse_attr *fa)
@@ -491,24 +493,18 @@ stat2attr (struct stat *st, struct fuse_attr *fa)
fa->blksize = st->st_blksize;
}
-static int
-fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct stat *stat, dict_t *dict,
- struct stat *postparent);
-
static int
-fuse_newentry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct stat *buf, struct stat *preparent,
- struct stat *postparent)
+fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct stat *buf)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
struct fuse_entry_out feo = {0, };
struct fuse_attr_out *fao = NULL;
fuse_private_t *priv = NULL;
+ inode_t *linked_inode = NULL;
priv = this->private;
state = frame->root->state;
@@ -518,34 +514,16 @@ fuse_newentry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
buf->st_ino = 1;
}
- if (state->is_revalidate == 1
- && need_fresh_lookup (op_ret, op_errno, &state->loc, buf)) {
- inode_unref (state->loc.inode);
- state->loc.inode = inode_new (state->itable);
- state->is_revalidate = 2;
-
- STACK_WIND (frame, fuse_lookup_cbk,
- FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->lookup,
- &state->loc, state->dict);
-
- return 0;
- }
-
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": %s() %s => %"PRId64" (%"PRId64")",
frame->root->unique, gf_fop_list[frame->root->op],
state->loc.path, buf->st_ino, state->loc.ino);
- inode_link (inode, state->loc.parent, state->loc.name, buf);
-
- inode_lookup (inode);
-
buf->st_blksize = this->ctx->page_size;
stat2attr (buf, &feo.attr);
- if (!inode->ino || !buf->st_ino) {
+ if (!buf->st_ino) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": %s() %s returning inode 0",
frame->root->unique,
@@ -553,14 +531,17 @@ fuse_newentry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
if (state->loc.parent) {
+ linked_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, buf);
+
+ inode_lookup (linked_inode);
+
/* TODO: make these timeouts configurable (via meta?) */
- feo.nodeid = inode->ino;
+ feo.nodeid = inode_to_nodeid (linked_inode);
-#ifdef GF_DARWIN_HOST_OS
- feo.generation = 0;
-#else
- feo.generation = buf->st_ctime;
-#endif
+ feo.generation = linked_inode->generation;
+
+ inode_unref (linked_inode);
feo.entry_valid =
calc_timeout_sec (priv->entry_timeout);
@@ -607,108 +588,12 @@ fuse_newentry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static int
-fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct stat *buf)
+fuse_newentry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
- fuse_state_t *state = NULL;
- fuse_in_header_t *finh = NULL;
- struct fuse_entry_out feo = {0, };
- struct fuse_attr_out *fao = NULL;
- fuse_private_t *priv = NULL;
-
- priv = this->private;
- state = frame->root->state;
- finh = state->finh;
-
- if (!op_ret && state->loc.ino == 1) {
- buf->st_ino = 1;
- }
-
- if (state->is_revalidate == 1
- && need_fresh_lookup (op_ret, op_errno, &state->loc, buf)) {
- inode_unref (state->loc.inode);
- state->loc.inode = inode_new (state->itable);
- state->is_revalidate = 2;
-
- STACK_WIND (frame, fuse_lookup_cbk,
- FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->lookup,
- &state->loc, state->dict);
-
- return 0;
- }
-
- if (op_ret == 0) {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s() %s => %"PRId64" (%"PRId64")",
- frame->root->unique, gf_fop_list[frame->root->op],
- state->loc.path, buf->st_ino, state->loc.ino);
-
- inode_link (inode, state->loc.parent, state->loc.name, buf);
-
- inode_lookup (inode);
-
- buf->st_blksize = this->ctx->page_size;
- stat2attr (buf, &feo.attr);
-
- if (!inode->ino || !buf->st_ino) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": %s() %s returning inode 0",
- frame->root->unique,
- gf_fop_list[frame->root->op], state->loc.path);
- }
-
- if (state->loc.parent) {
- /* TODO: make these timeouts configurable (via meta?) */
- feo.nodeid = inode->ino;
-
-#ifdef GF_DARWIN_HOST_OS
- feo.generation = 0;
-#else
- feo.generation = buf->st_ctime;
-#endif
-
- feo.entry_valid =
- calc_timeout_sec (priv->entry_timeout);
- feo.entry_valid_nsec =
- calc_timeout_nsec (priv->entry_timeout);
- feo.attr_valid =
- calc_timeout_sec (priv->attribute_timeout);
- feo.attr_valid_nsec =
- calc_timeout_nsec (priv->attribute_timeout);
-
- priv->proto_minor >= 9 ?
- send_fuse_obj (this, finh, &feo) :
- send_fuse_data (this, finh, &feo,
- FUSE_COMPAT_ENTRY_OUT_SIZE);
- } else {
- /* Refurbish the entry_out as attr_out. Too hacky?... */
- fao = (struct fuse_attr_out *)
- ((char *)&feo.attr -
- offsetof (struct fuse_attr_out, attr));
-
- fao->attr_valid =
- calc_timeout_sec (priv->attribute_timeout);
- fao->attr_valid_nsec =
- calc_timeout_nsec (priv->attribute_timeout);
-
- priv->proto_minor >= 9 ?
- send_fuse_obj (this, finh, fao) :
- send_fuse_data (this, finh, fao,
- FUSE_COMPAT_ATTR_OUT_SIZE);
- }
- } else {
- gf_log ("glusterfs-fuse",
- (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_WARNING),
- "%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
- gf_fop_list[frame->root->op], state->loc.path,
- strerror (op_errno));
- send_fuse_err (this, state->finh, op_errno);
- }
-
- free_state (state);
- STACK_DESTROY (frame->root);
+ fuse_entry_cbk (frame, cookie, this, op_ret, op_errno, inode, buf);
return 0;
}
@@ -780,16 +665,10 @@ fuse_forget (xlator_t *this, fuse_in_header_t *finh, void *msg)
return;
}
- fuse_inode = inode_search (this->itable, finh->nodeid, NULL);
- if (fuse_inode) {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "got forget on inode (%"PRIu64")", finh->nodeid);
- inode_forget (fuse_inode, ffi->nlookup);
- inode_unref (fuse_inode);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "got forget, but inode (%"PRIu64") not found", finh->nodeid);
- }
+ fuse_inode = fuse_ino_to_inode (finh->nodeid, this->itable);
+
+ inode_forget (fuse_inode, ffi->nlookup);
+ inode_unref (fuse_inode);
FREE (finh);
}
@@ -849,8 +728,6 @@ fuse_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
-
-
static int
fuse_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct stat *buf)
@@ -924,11 +801,6 @@ fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
return;
}
- if (state->loc.inode)
- state->is_revalidate = 1;
- else
- state->is_revalidate = -1;
-
state->dict = dict_new ();
FUSE_FOP (state, fuse_lookup_cbk, GF_FOP_LOOKUP,
@@ -1767,7 +1639,9 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
struct fuse_out_header fouh = {0, };
struct fuse_entry_out feo = {0, };
struct fuse_open_out foo = {0, };
- struct iovec iov_out[3];
+ struct iovec iov_out[3];
+ inode_t *linked_inode = NULL;
+
state = frame->root->state;
priv = this->private;
@@ -1789,13 +1663,28 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
buf->st_blksize = this->ctx->page_size;
stat2attr (buf, &feo.attr);
- feo.nodeid = buf->st_ino;
+ inode_link (inode, state->loc.parent,
+ state->loc.name, buf);
+ linked_inode = inode;
+
+ if (linked_inode != inode) {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "create(%s) inode (ptr=%p, ino=%"PRId64", "
+ "gen=%"PRId64") found conflict (ptr=%p, "
+ "ino=%"PRId64", gen=%"PRId64")",
+ state->loc.path, inode, inode->ino,
+ inode->generation, linked_inode,
+ linked_inode->ino, linked_inode->generation);
+ }
+ inode_unref (linked_inode);
-#ifdef GF_DARWIN_HOST_OS
- feo.generation = 0;
-#else
- feo.generation = buf->st_ctime;
-#endif
+ inode_lookup (inode);
+
+ fd_ref (fd);
+
+ feo.nodeid = inode_to_nodeid (inode);
+
+ feo.generation = inode->generation;
feo.entry_valid = calc_timeout_sec (priv->entry_timeout);
feo.entry_valid_nsec = calc_timeout_nsec (priv->entry_timeout);
@@ -1803,13 +1692,6 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
feo.attr_valid_nsec =
calc_timeout_nsec (priv->attribute_timeout);
- inode_link (inode, state->loc.parent,
- state->loc.name, buf);
-
- inode_lookup (inode);
-
- fd_ref (fd);
-
fouh.error = 0;
iov_out[0].iov_base = &fouh;
iov_out[1].iov_base = &feo;
@@ -3056,7 +2938,6 @@ fuse_root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == 0) {
gf_log (this->name, GF_LOG_TRACE,
"first lookup on root succeeded.");
- inode_lookup (inode);
} else {
gf_log (this->name, GF_LOG_DEBUG,
"first lookup on root failed.");
@@ -3089,7 +2970,7 @@ fuse_root_lookup (xlator_t *this)
loc.path = "/";
loc.name = "";
loc.ino = 1;
- loc.inode = inode_search (this->itable, 1, NULL);
+ loc.inode = fuse_ino_to_inode (1, this->itable);
loc.parent = NULL;
dict = dict_new ();