diff options
Diffstat (limited to 'xlators/mount/fuse')
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 37 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-resolve.c | 30 |
2 files changed, 59 insertions, 8 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index c93b17df971..1413c306e25 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -52,6 +52,39 @@ fuse_invalidate(xlator_t *this, inode_t *inode) return 0; } +void +fuse_inode_set_need_lookup (inode_t *inode, xlator_t *this) +{ + uint64_t need_lookup = 1; + + if (!inode || !this) + return; + + inode_ctx_set (inode, this, &need_lookup); + + return; +} + + +gf_boolean_t +fuse_inode_needs_lookup (inode_t *inode, xlator_t *this) +{ + uint64_t need_lookup = 0; + gf_boolean_t ret = _gf_false; + + if (!inode || !this) + return ret; + + inode_ctx_get (inode, this, &need_lookup); + if (need_lookup) + ret = _gf_true; + need_lookup = 0; + inode_ctx_set (inode, this, &need_lookup); + + return ret; +} + + fuse_fd_ctx_t * __fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd) { @@ -2633,6 +2666,8 @@ fuse_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, feo->nodeid = inode_to_fuse_nodeid (linked_inode); + fuse_inode_set_need_lookup (linked_inode, this); + inode_unref (linked_inode); feo->entry_valid = @@ -5439,7 +5474,7 @@ struct volume_options options[] = { }, { .key = {"use-readdirp"}, .type = GF_OPTION_TYPE_BOOL, - .default_value = "no" + .default_value = "yes" }, { .key = {NULL} }, }; diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c index 88ce32ab9cd..8565ce0e478 100644 --- a/xlators/mount/fuse/src/fuse-resolve.c +++ b/xlators/mount/fuse/src/fuse-resolve.c @@ -26,6 +26,8 @@ int fuse_migrate_fd (xlator_t *this, fd_t *fd, xlator_t *old_subvol, fuse_fd_ctx_t * fuse_fd_ctx_get (xlator_t *this, fd_t *fd); +gf_boolean_t fuse_inode_needs_lookup (inode_t *inode, xlator_t *this); + static int fuse_resolve_loc_touchup (fuse_state_t *state) { @@ -201,7 +203,11 @@ fuse_resolve_gfid (fuse_state_t *state) uuid_copy (resolve_loc->gfid, resolve->gfid); } - resolve_loc->inode = inode_new (state->itable); + /* inode may already exist in case we are looking up an inode which was + linked through readdirplus */ + resolve_loc->inode = inode_find (state->itable, resolve_loc->gfid); + if (!resolve_loc->inode) + resolve_loc->inode = inode_new (state->itable); ret = loc_path (resolve_loc, NULL); if (ret <= 0) { @@ -239,6 +245,9 @@ fuse_resolve_parent_simple (fuse_state_t *state) parent = resolve->parhint; if (parent->table == state->itable) { + if (fuse_inode_needs_lookup (parent, THIS)) + return 1; + /* no graph switches since */ loc->parent = inode_ref (parent); uuid_copy (loc->pargfid, parent->gfid); @@ -265,6 +274,10 @@ fuse_resolve_parent_simple (fuse_state_t *state) /* non decisive result - parent missing */ return 1; } + if (fuse_inode_needs_lookup (parent, THIS)) { + inode_unref (parent); + return 1; + } loc->parent = parent; uuid_copy (loc->pargfid, resolve->pargfid); @@ -314,15 +327,18 @@ fuse_resolve_inode_simple (fuse_state_t *state) loc = state->loc_now; inode = resolve->hint; - if (inode->table == state->itable) { + if (inode->table == state->itable) inode_ref (inode); - goto found; + else + inode = inode_find (state->itable, resolve->gfid); + + if (inode) { + if (!fuse_inode_needs_lookup (inode, THIS)) + goto found; + /* inode was linked through readdirplus */ + inode_unref (inode); } - inode = inode_find (state->itable, resolve->gfid); - if (inode) - goto found; - return 1; found: loc->inode = inode; |