📄 fuse-bridge.c
字号:
*/ if (op_ret == 0) {#ifndef GF_DARWIN_HOST_OS /* MacFUSE doesn't respect anyof these tweaks */ buf->f_blocks *= buf->f_frsize; buf->f_blocks /= BIG_FUSE_CHANNEL_SIZE; buf->f_bavail *= buf->f_frsize; buf->f_bavail /= BIG_FUSE_CHANNEL_SIZE; buf->f_bfree *= buf->f_frsize; buf->f_bfree /= BIG_FUSE_CHANNEL_SIZE; buf->f_frsize = buf->f_bsize = BIG_FUSE_CHANNEL_SIZE;#endif /* GF_DARWIN_HOST_OS */ fuse_reply_statfs (req, buf); } else { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": ERR => -1 (%d)", frame->root->unique, op_errno); fuse_reply_err (req, op_errno); } free_state (state); STACK_DESTROY (frame->root); return 0;}static voidfuse_statfs (fuse_req_t req, fuse_ino_t ino){ fuse_state_t *state; state = state_from_req (req); fuse_loc_fill (&state->fuse_loc, state, 1, NULL); if (!state->fuse_loc.loc.inode) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": STATFS (fuse_loc_fill() returned NULL inode)", req_callid (req)); fuse_reply_err (req, EINVAL); return; } gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": STATFS", req_callid (req)); FUSE_FOP (state, fuse_statfs_cbk, GF_FOP_STATFS, statfs, &state->fuse_loc.loc);}static voidfuse_setxattr (fuse_req_t req, fuse_ino_t ino, const char *name, const char *value, size_t size, int flags){ fuse_state_t *state; state = state_from_req (req); state->size = size; fuse_loc_fill (&state->fuse_loc, state, ino, NULL); if (!state->fuse_loc.loc.inode) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": SETXATTR %s/%"PRId64" (%s) (fuse_loc_fill() returned NULL inode)", req_callid (req), state->fuse_loc.loc.path, (int64_t)ino, name); fuse_reply_err (req, EINVAL); return; } state->dict = get_new_dict (); dict_set (state->dict, (char *)name, bin_to_data ((void *)value, size)); dict_ref (state->dict); gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": SETXATTR %s/%"PRId64" (%s)", req_callid (req), state->fuse_loc.loc.path, (int64_t)ino, name); FUSE_FOP (state, fuse_err_cbk, GF_FOP_SETXATTR, setxattr, &state->fuse_loc.loc, state->dict, flags); return;}static int32_tfuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict){ int32_t ret = op_ret; char *value = ""; fuse_state_t *state = frame->root->state; fuse_req_t req = state->req; if (ret >= 0) { gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": (%d) %s => %d", frame->root->unique, frame->op, state->fuse_loc.loc.path, op_ret); /* if successful */ if (state->name) { /* if callback for getxattr */ data_t *value_data = dict_get (dict, state->name); if (value_data) { ret = value_data->len; /* Don't return the value for '\0' */ value = value_data->data; if (state->size) { /* if callback for getxattr and asks for value */ fuse_reply_buf (req, value, ret); } else { /* if callback for getxattr and asks for value length only */ fuse_reply_xattr (req, ret); } } else { fuse_reply_err (req, ENODATA); } } else { /* if callback for listxattr */ int32_t len = 0; data_pair_t *trav = dict->members_list; while (trav) { len += strlen (trav->key) + 1; trav = trav->next; } value = alloca (len + 1); len = 0; trav = dict->members_list; while (trav) { strcpy (value + len, trav->key); value[len + strlen(trav->key)] = '\0'; len += strlen (trav->key) + 1; trav = trav->next; } if (state->size) { /* if callback for listxattr and asks for list of keys */ fuse_reply_buf (req, value, len); } else { /* if callback for listxattr and asks for length of keys only */ fuse_reply_xattr (req, len); } } } else { /* if failure - no need to check if listxattr or getxattr */ if (op_errno != ENODATA) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": (%d) %s => -1 (%d)", frame->root->unique, frame->op, state->fuse_loc.loc.path, op_errno); } else { gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": (%d) %s => -1 (%d)", frame->root->unique, frame->op, state->fuse_loc.loc.path, op_errno); } fuse_reply_err (req, op_errno); } free_state (state); STACK_DESTROY (frame->root); return 0;}static voidfuse_getxattr (fuse_req_t req, fuse_ino_t ino, const char *name, size_t size){ fuse_state_t *state; state = state_from_req (req); state->size = size; state->name = strdup (name); fuse_loc_fill (&state->fuse_loc, state, ino, NULL); if (!state->fuse_loc.loc.inode) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": GETXATTR %s/%"PRId64" (%s) (fuse_loc_fill() returned NULL inode)", req_callid (req), state->fuse_loc.loc.path, (int64_t)ino, name); fuse_reply_err (req, EINVAL); return; } gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": GETXATTR %s/%"PRId64" (%s)", req_callid (req), state->fuse_loc.loc.path, (int64_t)ino, name); FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR, getxattr, &state->fuse_loc.loc); return;}static voidfuse_listxattr (fuse_req_t req, fuse_ino_t ino, size_t size){ fuse_state_t *state; state = state_from_req (req); state->size = size; fuse_loc_fill (&state->fuse_loc, state, ino, NULL); if (!state->fuse_loc.loc.inode) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": LISTXATTR %s/%"PRId64" (fuse_loc_fill() returned NULL inode)", req_callid (req), state->fuse_loc.loc.path, (int64_t)ino); fuse_reply_err (req, EINVAL); return; } gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": LISTXATTR %s/%"PRId64, req_callid (req), state->fuse_loc.loc.path, (int64_t)ino); FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR, getxattr, &state->fuse_loc.loc); return;}static voidfuse_removexattr (fuse_req_t req, fuse_ino_t ino, const char *name){ fuse_state_t *state; state = state_from_req (req); fuse_loc_fill (&state->fuse_loc, state, ino, NULL); if (!state->fuse_loc.loc.inode) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": REMOVEXATTR %s/%"PRId64" (%s) (fuse_loc_fill() returned NULL inode)", req_callid (req), state->fuse_loc.loc.path, (int64_t)ino, name); fuse_reply_err (req, EINVAL); return; } gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": REMOVEXATTR %s/%"PRId64" (%s)", req_callid (req), state->fuse_loc.loc.path, (int64_t)ino, name); FUSE_FOP (state, fuse_err_cbk, GF_FOP_REMOVEXATTR, removexattr, &state->fuse_loc.loc, name); return;}static int32_tfuse_getlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct flock *lock){ fuse_state_t *state = frame->root->state; if (op_ret == 0) { gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": ERR => 0", frame->root->unique); fuse_reply_lock (state->req, lock); } else { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": ERR => -1 (%d)", frame->root->unique, op_errno); fuse_reply_err (state->req, op_errno); } free_state (state); STACK_DESTROY (frame->root); return 0;}static voidfuse_getlk (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock){ fuse_state_t *state; state = state_from_req (req); state->req = req; gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": GETLK %p", req_callid (req), FI_TO_FD (fi)); FUSE_FOP (state, fuse_getlk_cbk, GF_FOP_LK, lk, FI_TO_FD (fi), F_GETLK, lock); return;}static int32_tfuse_setlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct flock *lock){ fuse_state_t *state = frame->root->state; if (op_ret == 0) { gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": ERR => 0", frame->root->unique); fuse_reply_err (state->req, 0); } else { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": ERR => -1 (%d)", frame->root->unique, op_errno); fuse_reply_err (state->req, op_errno); } free_state (state); STACK_DESTROY (frame->root); return 0;}static voidfuse_setlk (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct flock *lock, int sleep){ fuse_state_t *state; state = state_from_req (req); state->req = req; gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": SETLK %p (sleep=%d)", req_callid (req), FI_TO_FD (fi), sleep); FUSE_FOP (state, fuse_setlk_cbk, GF_FOP_LK, lk, FI_TO_FD(fi), (sleep ? F_SETLKW : F_SETLK), lock); return;}static voidfuse_init (void *data, struct fuse_conn_info *conn){ xlator_t *this = data; struct fuse_private *priv = this->private; if (!this->name) this->name = "fuse"; if (!priv->attr_timeout) priv->attr_timeout = 1.0; if (!priv->entry_timeout) priv->entry_timeout = 1.0; this->itable = inode_table_new (0, this);}static voidfuse_destroy (void *data){}static struct fuse_lowlevel_ops fuse_ops = { .init = fuse_init, .destroy = fuse_destroy, .lookup = fuse_lookup, .forget = fuse_forget, .getattr = fuse_getattr, .setattr = fuse_setattr, .opendir = fuse_opendir, .readdir = fuse_readdir, .releasedir = fuse_releasedir, .access = fuse_access, .readlink = fuse_readlink, .mknod = fuse_mknod, .mkdir = fuse_mkdir, .unlink = fuse_unlink, .rmdir = fuse_rmdir, .symlink = fuse_symlink, .rename = fuse_rename, .link = fuse_link, .create = fuse_create, .open = fuse_open, .read = fuse_readv, .write = fuse_write, .flush = fuse_flush, .release = fuse_release, .fsync = fuse_fsync, .fsyncdir = fuse_fsyncdir, .statfs = fuse_statfs, .setxattr = fuse_setxattr, .getxattr = fuse_getxattr, .listxattr = fuse_listxattr, .removexattr = fuse_removexattr, .getlk = fuse_getlk, .setlk = fuse_setlk};static void *fuse_thread_proc (void *data){ xlator_t *this = data; struct fuse_private *priv = this->private; int32_t res = 0; data_t *buf = priv->buf; int32_t ref = 0; size_t chan_size = fuse_chan_bufsize (priv->ch); char *recvbuf = calloc (1, chan_size); while (!fuse_session_exited (priv->se)) { int32_t fuse_chan_receive (struct fuse_chan * ch, char *buf, int32_t size); res = fuse_chan_receive (priv->ch, recvbuf, chan_size); if (res == -1) { if (errno != EINTR) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "fuse_chan_receive() returned -1 (%d)", errno); } if (errno == ENODEV) break; continue; } buf = priv->buf; if (res && res != -1) { if (buf->len < (res)) { if (buf->data) { freee (buf->data); buf->data = NULL; } buf->data = calloc (1, res); buf->len = res; } memcpy (buf->data, recvbuf, res); // evil evil fuse_session_process (priv->se, buf->data, res, priv->ch); } LOCK (&buf->lock); ref = buf->refcount; UNLOCK (&buf->lock); if (1) { data_unref (buf); priv->buf = data_ref (data_from_dynptr (NULL, 0)); priv->buf->is_locked = 1; } } fuse_session_remove_chan (priv->ch); fuse_session_destroy (priv->se); // fuse_unmount (priv->mount_point, priv->ch); exit (0); return NULL;}int32_tnotify (xlator_t *this, int32_t event, void *data, ...){ return 0;}int32_tinit (xlator_t *this){ dict_t *options = NULL; char *mount_point = NULL; char *source; int argc; struct fuse_private *priv = NULL; int32_t res; options = this->options; asprintf (&source, "fsname=glusterfs"); char *argv[] = { "glusterfs",#ifndef GF_DARWIN_HOST_OS "-o", "nonempty",#else "-o", "noexec",#endif "-o", "allow_other", "-o", "default_permissions", "-o", source, "-o", "max_readahead=1048576", "-o", "max_read=1048576", "-o", "max_write=1048576", NULL };#ifdef GF_DARWIN_HOST_OS argc = 15;#else argc = 15;#endif struct fuse_args args = FUSE_ARGS_INIT(argc, argv); priv = calloc (1, sizeof (*priv)); this->private = (void *)priv; if (!data_to_str (dict_get (options, "mount-point"))) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "'option mount-point /directory' not specified"); return -1; } mount_point = strdup (data_to_str (dict_get (options, "mount-point"))); if (dict_get (options, "attr-timeout")) { priv->attr_timeout = data_to_uint32 (dict_get (options, "attr-timeout")); } if (dict_get (options, "entry-timeout")) { priv->entry_timeout = data_to_uint32 (dict_get (options, "entry-timeout")); } if (dict_get (options, "direct-io-mode")) { priv->direct_io_mode = data_to_uint32 (dict_get (options, "direct-io-mode")); } priv->ch = fuse_mount (mount_point, &args); if (!priv->ch) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "fuse_mount failed (%s)\n", strerror (errno)); fuse_opt_free_args(&args); goto err_free; } priv->se = fuse_lowlevel_new (&args, &fuse_ops, sizeof (fuse_ops), this); if (!priv->se) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "fuse_lowlevel_new failed (%s)\n", strerror (errno)); fuse_opt_free_args (&args); goto err_free; } fuse_opt_free_args(&args); res = fuse_set_signal_handlers (priv->se); if (res == -1) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "fuse_set_signal_handlers failed"); goto err; } fuse_session_add_chan (priv->se, priv->ch); priv->fd = fuse_chan_fd (priv->ch); priv->buf = data_ref (data_from_dynptr (NULL, 0)); priv->buf->is_locked = 1; priv->mount_point = mount_point; if (pthread_create (&priv->fuse_thread, NULL, fuse_thread_proc, this) != 0) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "pthread_create() failed (%s)", strerror (errno)); goto err; } (this->children->xlator)->notify (this->children->xlator, GF_EVENT_PARENT_UP, this); return 0; err: fuse_unmount (mount_point, priv->ch); err_free: freee (mount_point); mount_point = NULL; return -1;}voidfini (xlator_t *this){ struct fuse_private *priv = this->private; if (dict_get (this->options, "mount-point")) { char *mount_point = data_to_str (dict_get (this->options, "mount-point")); fuse_unmount (mount_point, priv->ch); }}struct xlator_fops fops = {};struct xlator_mops mops = {};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -