diff options
Diffstat (limited to 'xlators/mount/fuse/src/fuse-bridge.c')
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 127 |
1 files changed, 76 insertions, 51 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 3f4e19c211e..5bc070658e2 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -216,8 +216,8 @@ check_and_dump_fuse_W(fuse_private_t *priv, struct iovec *iov_out, int count, struct fuse_out_header *fouh = NULL; if (res == -1) { - gf_log("glusterfs-fuse", GF_LOG_ERROR, - "writing to fuse device failed: %s", strerror(errno)); + gf_log_callingfn("glusterfs-fuse", GF_LOG_ERROR, + "writing to fuse device failed: %s", strerror(errno)); return errno; } @@ -312,29 +312,29 @@ send_fuse_data(xlator_t *this, fuse_in_header_t *finh, void *data, size_t size) #define send_fuse_obj(this, finh, obj) \ send_fuse_data(this, finh, obj, sizeof(*(obj))) -#if FUSE_KERNEL_MINOR_VERSION >= 11 static void fuse_invalidate_entry(xlator_t *this, uint64_t fuse_ino) { +#if FUSE_KERNEL_MINOR_VERSION >= 11 struct fuse_out_header *fouh = NULL; struct fuse_notify_inval_entry_out *fnieo = NULL; fuse_private_t *priv = NULL; dentry_t *dentry = NULL; + dentry_t *tmp = NULL; inode_t *inode = NULL; size_t nlen = 0; fuse_invalidate_node_t *node = NULL; + char gfid_str[UUID_CANONICAL_FORM_LEN + 1]; priv = this->private; - if (!priv->reverse_fuse_thread_started) return; - inode = fuse_ino_to_inode(fuse_ino, this); - if (inode == NULL) { + inode = (inode_t *)(unsigned long)fuse_ino; + if (inode == NULL) return; - } - list_for_each_entry(dentry, &inode->dentry_list, inode_list) + list_for_each_entry_safe(dentry, tmp, &inode->dentry_list, inode_list) { node = GF_CALLOC(1, sizeof(*node), gf_fuse_mt_invalidate_node_t); if (node == NULL) @@ -348,38 +348,41 @@ fuse_invalidate_entry(xlator_t *this, uint64_t fuse_ino) fouh->unique = 0; fouh->error = FUSE_NOTIFY_INVAL_ENTRY; - nlen = strlen(dentry->name); - fouh->len = sizeof(*fouh) + sizeof(*fnieo) + nlen + 1; - fnieo->parent = inode_to_fuse_nodeid(dentry->parent); - - fnieo->namelen = nlen; - strcpy(node->inval_buf + sizeof(*fouh) + sizeof(*fnieo), dentry->name); + if (dentry->name) { + nlen = strlen(dentry->name); + fouh->len = sizeof(*fouh) + sizeof(*fnieo) + nlen + 1; + fnieo->parent = inode_to_fuse_nodeid(dentry->parent); - pthread_mutex_lock(&priv->invalidate_mutex); - { - list_add_tail(&node->next, &priv->invalidate_list); - pthread_cond_signal(&priv->invalidate_cond); + fnieo->namelen = nlen; + strcpy((node->inval_buf + sizeof(*fouh) + sizeof(*fnieo)), + dentry->name); } - pthread_mutex_unlock(&priv->invalidate_mutex); gf_log("glusterfs-fuse", GF_LOG_TRACE, - "INVALIDATE entry: " - "%" PRIu64 "/%s", - fnieo->parent, dentry->name); + "INVALIDATE entry: %" PRIu64 "/%s (gfid:%s)", fnieo->parent, + dentry->name, uuid_utoa(inode->gfid)); if (dentry->parent) { - fuse_log_eh(this, "Invalidated entry %s (parent: %s)", dentry->name, - uuid_utoa(dentry->parent->gfid)); + fuse_log_eh(this, "Invalidated entry %s (parent: %s) gfid:%s", + dentry->name, uuid_utoa(dentry->parent->gfid), + uuid_utoa_r(inode->gfid, gfid_str)); } else { - fuse_log_eh(this, "Invalidated entry %s(nodeid: %" PRIu64 ")", - dentry->name, fnieo->parent); + fuse_log_eh(this, + "Invalidated entry %s(nodeid: %" PRIu64 ") gfid:%s", + dentry->name, fnieo->parent, uuid_utoa(inode->gfid)); + } + + pthread_mutex_lock(&priv->invalidate_mutex); + { + list_add_tail(&node->next, &priv->invalidate_list); + pthread_cond_signal(&priv->invalidate_cond); } + pthread_mutex_unlock(&priv->invalidate_mutex); } - if (inode) - inode_unref(inode); -} #endif + return; +} /* * Send an inval inode notification to fuse. This causes an invalidation of the @@ -400,6 +403,10 @@ fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino) if (!priv->reverse_fuse_thread_started) return; + inode = (inode_t *)(unsigned long)fuse_ino; + if (inode == NULL) + return; + node = GF_CALLOC(1, sizeof(*node), gf_fuse_mt_invalidate_node_t); if (node == NULL) return; @@ -419,7 +426,11 @@ fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino) fniio->off = 0; fniio->len = -1; - inode = fuse_ino_to_inode(fuse_ino, this); + fuse_log_eh(this, "Invalidated inode %" PRIu64 " (gfid: %s)", fuse_ino, + uuid_utoa(inode->gfid)); + gf_log("glusterfs-fuse", GF_LOG_TRACE, + "INVALIDATE inode: %" PRIu64 "(gfid:%s)", fuse_ino, + uuid_utoa(inode->gfid)); pthread_mutex_lock(&priv->invalidate_mutex); { @@ -428,24 +439,22 @@ fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino) } pthread_mutex_unlock(&priv->invalidate_mutex); - gf_log("glusterfs-fuse", GF_LOG_TRACE, "INVALIDATE inode: %" PRIu64, - fuse_ino); - - if (inode) { - fuse_log_eh(this, "Invalidated inode %" PRIu64 " (gfid: %s)", fuse_ino, - uuid_utoa(inode->gfid)); - } else { - fuse_log_eh(this, "Invalidated inode %" PRIu64, fuse_ino); - } - - if (inode) - inode_unref(inode); #else gf_log("glusterfs-fuse", GF_LOG_WARNING, - "fuse_invalidate_inode not implemented on OS X due to missing FUSE " - "notification"); + "fuse_invalidate_inode not implemented on this system"); #endif + return; +} + +#if FUSE_KERNEL_MINOR_VERSION >= 11 +/* Need this function for the signature (inode_t *, instead of uint64_t) */ +static int32_t +fuse_inode_invalidate_fn(xlator_t *this, inode_t *inode) +{ + fuse_invalidate_entry(this, (uint64_t)inode); + return 0; } +#endif static fuse_timed_message_t * fuse_timed_message_new(void) @@ -1068,11 +1077,14 @@ do_forget(xlator_t *this, uint64_t unique, uint64_t nodeid, uint64_t nlookup) { inode_t *fuse_inode = fuse_ino_to_inode(nodeid, this); + gf_log("fuse", GF_LOG_TRACE, + "%" PRIu64 ": FORGET %" PRIu64 "/%" PRIu64 " gfid: (%s)", unique, + nodeid, nlookup, uuid_utoa(fuse_inode->gfid)); + fuse_log_eh(this, "%" PRIu64 ": FORGET %" PRIu64 "/%" PRIu64 " gfid: (%s)", unique, nodeid, nlookup, uuid_utoa(fuse_inode->gfid)); - inode_forget(fuse_inode, nlookup); - inode_unref(fuse_inode); + inode_forget_with_unref(fuse_inode, nlookup); } static void @@ -1087,10 +1099,6 @@ fuse_forget(xlator_t *this, fuse_in_header_t *finh, void *msg, return; } - gf_log("glusterfs-fuse", GF_LOG_TRACE, - "%" PRIu64 ": FORGET %" PRIu64 "/%" PRIu64, finh->unique, - finh->nodeid, ffi->nlookup); - do_forget(this, finh->unique, finh->nodeid, ffi->nlookup); GF_FREE(finh); @@ -5658,7 +5666,9 @@ fuse_thread_proc(void *data) fuse_in_header_t *finh = NULL; struct iovec iov_in[2]; void *msg = NULL; - const size_t msg0_size = sizeof(*finh) + 128; + /* we need 512 extra buffer size for BATCH_FORGET fop. By tests, it is + found to be reduces 'REALLOC()' in the loop */ + const size_t msg0_size = sizeof(*finh) + 512; fuse_handler_t **fuse_ops = NULL; struct pollfd pfd[2] = {{ 0, @@ -5992,7 +6002,12 @@ fuse_graph_setup(xlator_t *this, glusterfs_graph_t *graph) goto unlock; } +#if FUSE_KERNEL_MINOR_VERSION >= 11 + itable = inode_table_with_invalidator(priv->lru_limit, graph->top, + fuse_inode_invalidate_fn, this); +#else itable = inode_table_new(0, graph->top); +#endif if (!itable) { ret = -1; goto unlock; @@ -6453,6 +6468,8 @@ init(xlator_t *this_xl) } } + GF_OPTION_INIT("lru-limit", priv->lru_limit, uint32, cleanup_exit); + GF_OPTION_INIT("event-history", priv->event_history, bool, cleanup_exit); GF_OPTION_INIT("thin-client", priv->thin_client, bool, cleanup_exit); @@ -6780,6 +6797,14 @@ struct volume_options options[] = { .description = "Handle iterrupts in FLUSH handler (for testing purposes).", }, + { + .key = {"lru-limit"}, + .type = GF_OPTION_TYPE_INT, + .default_value = "131072", + .min = 0, + .description = "makes glusterfs invalidate kernel inodes after " + "reaching this limit (0 means 'unlimited')", + }, {.key = {NULL}}, }; |