⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fuse-bridge.c

📁 分布式文件系统
💻 C
📖 第 1 页 / 共 4 页
字号:
   */  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 + -