diff options
| author | Anand V. Avati <avati@blackhole.gluster.com> | 2009-10-18 13:35:15 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2009-10-18 12:15:46 -0700 | 
| commit | 3d09fb99093a84a303edc443b68bdf9eb10096b4 (patch) | |
| tree | 9a95c17069123bd7cb16e21f7a026deb6498afc9 | |
| parent | 7e831d735e3746fa9e6ec2e797e1a7f68ac5c148 (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
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 329 | 
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 ();  | 
