static gboolean manage_fuse_st (GIOChannel *source, GIOCondition condition, gpointer data) { int res; char *buf; gboolean ret; size_t bufsize; struct fuse *fuse; struct fuse_session *se; struct fuse_chan *ch; fuse = (struct fuse*) data; se = fuse_get_session (fuse); ch = fuse_session_next_chan (se, NULL); bufsize = fuse_chan_bufsize (ch); buf = alloca (bufsize); ret = TRUE; res = fuse_chan_recv (&ch, buf, bufsize); if (res == -EINTR) ret = TRUE; else if (res <= 0) ret = FALSE; else fuse_session_process (se, buf, res, ch); return ret; }
// Do a mount for helper_thread() static void helper_thread_mount(mount_t * m) { Dprintf("%s(\"%s\")\n", __FUNCTION__, m->fstitch_path); if ((m->channel_fd = fuse_mount(m->mountpoint, &m->args)) == -1) { fprintf(stderr, "%s(): fuse_mount(\"%s\") failed. (Does the mountpoint exist?)\n", __FUNCTION__, m->mountpoint); return; } if (!(m->session = fuse_lowlevel_new(&m->args, ops, ops_len, m))) { fprintf(stderr, "%s(): fuse_lowlevel_new() failed\n", __FUNCTION__); return; } if (!(m->channel = fuse_kern_chan_new(m->channel_fd))) { fprintf(stderr, "%s(): fuse_kern_chan_new() failed\n", __FUNCTION__); return; } fuse_session_add_chan(m->session, m->channel); if (fuse_chan_bufsize(m->channel) != fuse_serve_mount_chan_bufsize()) fprintf(stderr, "bufsizes differ!\n"); m->mounted = 1; printf("Mounted \"%s\" from %s\n", m->fstitch_path, modman_name_cfs(m->cfs)); }
static Bool fuseProcessMessages(void *data) { CompDisplay *d = (CompDisplay *)data; struct fuse_chan *channel; size_t bufferSize; int res = 0; FUSE_DISPLAY(d); channel = fuse_session_next_chan(fd->session, NULL); bufferSize = fuse_chan_bufsize(channel); if (fuse_session_exited(fd->session)) return FALSE; for (;; ) { struct fuse_chan *tmpch = channel; res = fuse_chan_recv(&tmpch, fd->buffer, bufferSize); if (res == -EINTR) continue; if (res > 0) fuse_session_process(fd->session, fd->buffer, res, tmpch); break; } return TRUE; }
static int fuse_loop_start_thread(struct fuse_mt *mt) { int res; struct fuse_worker *w = malloc(sizeof(struct fuse_worker)); if (!w) { fprintf(stderr, "fuse: failed to allocate worker structure\n"); return -1; } memset(w, 0, sizeof(struct fuse_worker)); w->bufsize = fuse_chan_bufsize(mt->prevch); w->buf = malloc(w->bufsize); w->mt = mt; if (!w->buf) { fprintf(stderr, "fuse: failed to allocate read buffer\n"); free(w); return -1; } res = fuse_start_thread(&w->thread_id, fuse_do_work, w); if (res == -1) { free(w->buf); free(w); return -1; } list_add_worker(w, &mt->main); mt->numavail ++; mt->numworker ++; return 0; }
int fuse_session_loop(struct fuse_session *se) { int res = 0; struct fuse_chan *ch = fuse_session_next_chan(se, NULL); size_t bufsize = fuse_chan_bufsize(ch); char *buf = (char *) malloc(bufsize); if (!buf) { fprintf(stderr, "fuse: failed to allocate read buffer\n"); return -1; } while (!fuse_session_exited(se)) { struct fuse_chan *tmpch = ch; res = fuse_chan_recv(&tmpch, buf, bufsize); if (res == -EINTR) continue; if (res <= 0) break; fuse_session_process(se, buf, res, tmpch); } free(buf); fuse_session_reset(se); return res < 0 ? -1 : 0; }
static gboolean manage_fuse_mt (GIOChannel *source, GIOCondition condition, gpointer data) { int res; char *buf; size_t bufsize; struct fuse *fuse; struct fuse_session *se; struct fuse_chan *ch; GThreadPool *pool; GError *error; ThreadsData *info; fuse = (struct fuse*) data; error = NULL; pool = g_thread_pool_new (manage_request, fuse, -1, FALSE, &error); if (pool == NULL) { g_warning ("Unable to start thread pool: %s", error->message); g_error_free (error); return NULL; } se = fuse_get_session (fuse); ch = fuse_session_next_chan (se, NULL); bufsize = fuse_chan_bufsize (ch); while (1) { buf = (char*) malloc (bufsize); res = fuse_chan_recv (&ch, buf, bufsize); if (res == -EINTR) { free (buf); continue; } else if (res <= 0) { free (buf); break; } info = do_threads_data (buf, res); error = NULL; g_thread_pool_push (pool, info, &error); if (error != NULL) { g_warning ("Unable to start processing request: %s", error->message); g_error_free (error); free_threads_data (info); } } g_thread_pool_free (pool, TRUE, TRUE); return NULL; }
static int fuse_start_thread(struct fuse_mt *mt) { sigset_t oldset; sigset_t newset; int res; pthread_attr_t attr; char *stack_size; struct fuse_worker *w = malloc(sizeof(struct fuse_worker)); if (!w) { fprintf(stderr, "fuse: failed to allocate worker structure\n"); return -1; } memset(w, 0, sizeof(struct fuse_worker)); w->bufsize = fuse_chan_bufsize(mt->prevch); w->buf = malloc(w->bufsize); w->mt = mt; if (!w->buf) { fprintf(stderr, "fuse: failed to allocate read buffer\n"); free(w); return -1; } /* Override default stack size */ pthread_attr_init(&attr); stack_size = getenv(ENVNAME_THREAD_STACK); if (stack_size && pthread_attr_setstacksize(&attr, atoi(stack_size))) fprintf(stderr, "fuse: invalid stack size: %s\n", stack_size); /* Disallow signal reception in worker threads */ sigemptyset(&newset); sigaddset(&newset, SIGTERM); sigaddset(&newset, SIGINT); sigaddset(&newset, SIGHUP); sigaddset(&newset, SIGQUIT); pthread_sigmask(SIG_BLOCK, &newset, &oldset); res = pthread_create(&w->thread_id, &attr, fuse_do_work, w); pthread_sigmask(SIG_SETMASK, &oldset, NULL); pthread_attr_destroy(&attr); if (res != 0) { fprintf(stderr, "fuse: error creating thread: %s\n", strerror(res)); free(w->buf); free(w); return -1; } list_add_worker(w, &mt->main); mt->numavail ++; mt->numworker ++; return 0; }
static void fuseMount(CompDisplay *d) { char *mountPoint; struct fuse_args args = FUSE_ARGS_INIT(0, NULL); FUSE_DISPLAY(d); mountPoint = strdup(fd->opt[FUSE_DISPLAY_OPTION_MOUNT_POINT].value.s); if (!mountPoint) return; fuse_opt_add_arg(&args, ""); fuse_opt_add_arg(&args, "-o"); fuse_opt_add_arg(&args, "allow_root"); fd->channel = fuse_mount(mountPoint, &args); if (!fd->channel) { fuse_opt_free_args(&args); free(mountPoint); return; } fuse_opt_free_args(&args); fd->buffer = malloc(fuse_chan_bufsize(fd->channel)); if (!fd->buffer) { fuse_unmount(mountPoint, fd->channel); free(mountPoint); fd->channel = NULL; return; } fd->mountPoint = mountPoint; fuse_session_add_chan(fd->session, fd->channel); fd->watchFdHandle = compAddWatchFd(fuse_chan_fd(fd->channel), POLLIN | POLLPRI | POLLHUP | POLLERR, fuseProcessMessages, d); }
int zfsfuse_newfs(char *mntpoint, struct fuse_chan *ch) { fuse_fs_info_t info = { 0 }; info.fd = fuse_chan_fd(ch); info.bufsize = fuse_chan_bufsize(ch); info.ch = ch; info.se = fuse_chan_session(ch); info.mntlen = strlen(mntpoint); if(write(newfs_fd[1], &info, sizeof(info)) != sizeof(info)) { perror("Warning (while writing fsinfo to newfs_fd)"); return -1; } if(write(newfs_fd[1], mntpoint, info.mntlen) != info.mntlen) { perror("Warning (while writing mntpoint to newfs_fd)"); return -1; } return 0; }
void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) { struct fuse_init_in *arg = (struct fuse_init_in *) inarg; struct cuse_init_out outarg; struct fuse_ll *f = req->f; struct cuse_data *cd = f->cuse_data; size_t bufsize = fuse_chan_bufsize(req->ch); struct cuse_lowlevel_ops *clop = req_clop(req); (void) nodeid; if (f->debug) { fprintf(stderr, "CUSE_INIT: %u.%u\n", arg->major, arg->minor); fprintf(stderr, "flags=0x%08x\n", arg->flags); } f->conn.proto_major = arg->major; f->conn.proto_minor = arg->minor; f->conn.capable = 0; f->conn.want = 0; if (arg->major < 7) { fprintf(stderr, "cuse: unsupported protocol version: %u.%u\n", arg->major, arg->minor); fuse_reply_err(req, EPROTO); return; } if (bufsize < FUSE_MIN_READ_BUFFER) { fprintf(stderr, "cuse: warning: buffer size too small: %zu\n", bufsize); bufsize = FUSE_MIN_READ_BUFFER; } bufsize -= 4096; if (bufsize < f->conn.max_write) f->conn.max_write = bufsize; f->got_init = 1; if (f->op.init) f->op.init(f->userdata, &f->conn); memset(&outarg, 0, sizeof(outarg)); outarg.major = FUSE_KERNEL_VERSION; outarg.minor = FUSE_KERNEL_MINOR_VERSION; outarg.flags = cd->flags; outarg.max_read = cd->max_read; outarg.max_write = f->conn.max_write; outarg.dev_major = cd->dev_major; outarg.dev_minor = cd->dev_minor; if (f->debug) { fprintf(stderr, " CUSE_INIT: %u.%u\n", outarg.major, outarg.minor); fprintf(stderr, " flags=0x%08x\n", outarg.flags); fprintf(stderr, " max_read=0x%08x\n", outarg.max_read); fprintf(stderr, " max_write=0x%08x\n", outarg.max_write); fprintf(stderr, " dev_major=%u\n", outarg.dev_major); fprintf(stderr, " dev_minor=%u\n", outarg.dev_minor); fprintf(stderr, " dev_info: %.*s\n", cd->dev_info_len, cd->dev_info); } cuse_reply_init(req, &outarg, cd->dev_info, cd->dev_info_len); if (clop->init_done) clop->init_done(f->userdata); fuse_free_req(req); }
size_t fuse_serve_mount_chan_bufsize(void) { assert(root && root->mounted); return fuse_chan_bufsize(root->channel); }
/** * Init of the pseudo fuse thread @param ch : initial channel @param se : initial session @param rozofs_fuse_buffer_count : number of request buffers (corresponds to the number of fuse save context) @retval 0 on success @retval -1 on error */ int rozofs_fuse_init(struct fuse_chan *ch,struct fuse_session *se,int rozofs_fuse_buffer_count) { int status = 0; // return 0; int fileflags; rozofs_fuse_ctx_p = malloc(sizeof (rozofs_fuse_ctx_t)); if (rozofs_fuse_ctx_p == NULL) { /* ** cannot allocate memory for fuse rozofs context */ return -1; } /* ** clear read/write merge stats table */ memset(rozofs_write_merge_stats_tab,0,sizeof(uint64_t)*RZ_FUSE_WRITE_MAX); memset (rozofs_write_buf_section_table,0,sizeof(uint64_t)*ROZOFS_FUSE_NB_OF_BUSIZE_SECTION_MAX); memset (rozofs_read_buf_section_table,0,sizeof(uint64_t)*ROZOFS_FUSE_NB_OF_BUSIZE_SECTION_MAX); memset(&rozofs_fuse_read_write_stats_buf,0,sizeof(rozofs_fuse_read_write_stats)); /* ** init of the context */ rozofs_fuse_ctx_p->fuseReqPoolRef = NULL; rozofs_fuse_ctx_p->ch = NULL; rozofs_fuse_ctx_p->se = se; rozofs_fuse_ctx_p->bufsize = 0; rozofs_fuse_ctx_p->buf_fuse_req_p = NULL; rozofs_fuse_ctx_p->initBufCount = rozofs_fuse_buffer_count; while (1) { /* ** get the receive buffer size for former channel in order to create the request distributor */ int bufsize = fuse_chan_bufsize(ch); rozofs_fuse_ctx_p->bufsize = bufsize; /* ** create the pool */ rozofs_fuse_ctx_p->fuseReqPoolRef = ruc_buf_poolCreate(rozofs_fuse_buffer_count,sizeof(rozofs_fuse_save_ctx_t)); if (rozofs_fuse_ctx_p->fuseReqPoolRef == NULL) { ERRLOG "rozofs_fuse_init buffer pool creation error(%d,%d)", (int)rozofs_fuse_buffer_count, (int)sizeof(rozofs_fuse_save_ctx_t) ENDERRLOG ; status = -1; break; } /* ** allocate a buffer for receiving the fuse request */ rozofs_fuse_ctx_p->buf_fuse_req_p = malloc(bufsize); if (rozofs_fuse_ctx_p == NULL) { ERRLOG "rozofs_fuse_init out of memory %d", bufsize ENDERRLOG ; status = -1; break; } /* ** get the fd of the channel */ rozofs_fuse_ctx_p->fd = fuse_chan_fd(ch); /* ** create a new channel with the specific operation for rozofs (non-blocking) */ rozofs_fuse_ctx_p->ch = fuse_chan_new(&rozofs_fuse_ch_ops,fuse_chan_fd(ch),fuse_chan_bufsize(ch),rozofs_fuse_ctx_p); if (rozofs_fuse_ctx_p->ch == NULL) { ERRLOG "rozofs_fuse_init fuse_chan_new error" ENDERRLOG ; status = -1; break; } /* ** remove the association between the initial session and channel */ fuse_session_remove_chan(ch); /* ** OK, now add the new channel */ fuse_session_add_chan(se,rozofs_fuse_ctx_p->ch ); /* ** set the channel in non blocking mode */ if((fileflags=fcntl(rozofs_fuse_ctx_p->fd,F_GETFL,0))==-1) { RUC_WARNING(errno); status = -1; break; } if((fcntl(rozofs_fuse_ctx_p->fd,F_SETFL,fileflags|O_NDELAY))==-1) { RUC_WARNING(errno); status = -1; break; } /* ** perform the connection with the socket controller */ /* ** OK, we are almost done, just need to connect with the socket controller */ rozofs_fuse_ctx_p->connectionId = ruc_sockctl_connect(rozofs_fuse_ctx_p->fd, // Reference of the socket "rozofs_fuse", // name of the socket 3, // Priority within the socket controller (void*)rozofs_fuse_ctx_p, // user param for socketcontroller callback &rozofs_fuse_callBack_sock); // Default callbacks if (rozofs_fuse_ctx_p->connectionId == NULL) { /* ** Fail to connect with the socket controller */ RUC_WARNING(-1); status = -1; break; } status = 0; break; } uma_dbg_addTopic("fuse", rozofs_fuse_show); return status; }
static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) { struct fuse_init_in *arg = (struct fuse_init_in *) inarg; struct fuse_init_out outarg; struct fuse_ll *f = req->f; size_t bufsize = fuse_chan_bufsize(req->ch); (void) nodeid; if (f->debug) { fprintf(stderr, "INIT: %u.%u\n", arg->major, arg->minor); if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) { fprintf(stderr, "flags=0x%08x\n", arg->flags); fprintf(stderr, "max_readahead=0x%08x\n", arg->max_readahead); } } f->conn.proto_major = arg->major; f->conn.proto_minor = arg->minor; if (arg->major < 7) { fprintf(stderr, "fuse: unsupported protocol version: %u.%u\n", arg->major, arg->minor); fuse_reply_err(req, EPROTO); return; } if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) { if (f->conn.async_read) f->conn.async_read = arg->flags & FUSE_ASYNC_READ; if (arg->max_readahead < f->conn.max_readahead) f->conn.max_readahead = arg->max_readahead; } else { f->conn.async_read = 0; f->conn.max_readahead = 0; } if (bufsize < FUSE_MIN_READ_BUFFER) { fprintf(stderr, "fuse: warning: buffer size too small: %zu\n", bufsize); bufsize = FUSE_MIN_READ_BUFFER; } bufsize -= 4096; if (bufsize < f->conn.max_write) f->conn.max_write = bufsize; f->got_init = 1; if (f->op.init) f->op.init(f->userdata, &f->conn); memset(&outarg, 0, sizeof(outarg)); outarg.major = FUSE_KERNEL_VERSION; outarg.minor = FUSE_KERNEL_MINOR_VERSION; if (f->conn.async_read) outarg.flags |= FUSE_ASYNC_READ; if (f->op.getlk && f->op.setlk) outarg.flags |= FUSE_POSIX_LOCKS; outarg.max_readahead = f->conn.max_readahead; outarg.max_write = f->conn.max_write; if (f->debug) { fprintf(stderr, " INIT: %u.%u\n", outarg.major, outarg.minor); fprintf(stderr, " flags=0x%08x\n", outarg.flags); fprintf(stderr, " max_readahead=0x%08x\n", outarg.max_readahead); fprintf(stderr, " max_write=0x%08x\n", outarg.max_write); } send_reply_ok(req, &outarg, arg->minor < 5 ? 8 : sizeof(outarg)); }
static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) { struct fuse_init_in *arg = (struct fuse_init_in *) inarg; struct fuse_init_out outarg; struct fuse_ll *f = req->f; size_t bufsize = fuse_chan_bufsize(req->ch); (void) nodeid; if (f->debug) { fprintf(stderr, "INIT: %u.%u\n", arg->major, arg->minor); if (arg->major == 7 && arg->minor >= 6) { fprintf(stderr, "flags=0x%08x\n", arg->flags); fprintf(stderr, "max_readahead=0x%08x\n", arg->max_readahead); } } f->conn.proto_major = arg->major; f->conn.proto_minor = arg->minor; f->conn.capable = 0; f->conn.want = 0; memset(&outarg, 0, sizeof(outarg)); outarg.major = FUSE_KERNEL_VERSION; outarg.minor = FUSE_KERNEL_MINOR_VERSION; if (arg->major < 7) { fprintf(stderr, "fuse: unsupported protocol version: %u.%u\n", arg->major, arg->minor); fuse_reply_err(req, EPROTO); return; } if (arg->major > 7) { /* Wait for a second INIT request with a 7.X version */ send_reply_ok(req, &outarg, sizeof(outarg)); return; } if (arg->minor >= 6) { if (f->conn.async_read) f->conn.async_read = arg->flags & FUSE_ASYNC_READ; if (arg->max_readahead < f->conn.max_readahead) f->conn.max_readahead = arg->max_readahead; if (arg->flags & FUSE_ASYNC_READ) f->conn.capable |= FUSE_CAP_ASYNC_READ; if (arg->flags & FUSE_POSIX_LOCKS) f->conn.capable |= FUSE_CAP_POSIX_LOCKS; if (arg->flags & FUSE_ATOMIC_O_TRUNC) f->conn.capable |= FUSE_CAP_ATOMIC_O_TRUNC; if (arg->flags & FUSE_EXPORT_SUPPORT) f->conn.capable |= FUSE_CAP_EXPORT_SUPPORT; if (arg->flags & FUSE_BIG_WRITES) f->conn.capable |= FUSE_CAP_BIG_WRITES; if (arg->flags & FUSE_DONT_MASK) f->conn.capable |= FUSE_CAP_DONT_MASK; } else { f->conn.async_read = 0; f->conn.max_readahead = 0; } if (f->atomic_o_trunc) f->conn.want |= FUSE_CAP_ATOMIC_O_TRUNC; if (f->op.getlk && f->op.setlk && !f->no_remote_lock) f->conn.want |= FUSE_CAP_POSIX_LOCKS; if (f->big_writes) f->conn.want |= FUSE_CAP_BIG_WRITES; if (bufsize < FUSE_MIN_READ_BUFFER) { fprintf(stderr, "fuse: warning: buffer size too small: %zu\n", bufsize); bufsize = FUSE_MIN_READ_BUFFER; } bufsize -= 4096; if (bufsize < f->conn.max_write) f->conn.max_write = bufsize; f->got_init = 1; if (f->op.init) f->op.init(f->userdata, &f->conn); if (f->conn.async_read || (f->conn.want & FUSE_CAP_ASYNC_READ)) outarg.flags |= FUSE_ASYNC_READ; if (f->conn.want & FUSE_CAP_POSIX_LOCKS) outarg.flags |= FUSE_POSIX_LOCKS; if (f->conn.want & FUSE_CAP_ATOMIC_O_TRUNC) outarg.flags |= FUSE_ATOMIC_O_TRUNC; if (f->conn.want & FUSE_CAP_EXPORT_SUPPORT) outarg.flags |= FUSE_EXPORT_SUPPORT; if (f->conn.want & FUSE_CAP_BIG_WRITES) outarg.flags |= FUSE_BIG_WRITES; if (f->conn.want & FUSE_CAP_DONT_MASK) outarg.flags |= FUSE_DONT_MASK; outarg.max_readahead = f->conn.max_readahead; outarg.max_write = f->conn.max_write; if (f->debug) { fprintf(stderr, " INIT: %u.%u\n", outarg.major, outarg.minor); fprintf(stderr, " flags=0x%08x\n", outarg.flags); fprintf(stderr, " max_readahead=0x%08x\n", outarg.max_readahead); fprintf(stderr, " max_write=0x%08x\n", outarg.max_write); } send_reply_ok(req, &outarg, arg->minor < 5 ? 8 : sizeof(outarg)); }
static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) { const struct fuse_init_in *arg = (const struct fuse_init_in *) inarg; struct fuse_init_out outarg; struct fuse_ll *f = req->f; size_t bufsize = fuse_chan_bufsize(req->ch); (void) nodeid; if (f->debug) { fprintf(stderr, "INIT: %u.%u\n", arg->major, arg->minor); if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) { fprintf(stderr, "flags=0x%08x\n", arg->flags); fprintf(stderr, "max_readahead=0x%08x\n", arg->max_readahead); } } f->conn.proto_major = arg->major; f->conn.proto_minor = arg->minor; if (arg->major < 7) { fprintf(stderr, "fuse: unsupported protocol version: %u.%u\n", arg->major, arg->minor); fuse_reply_err(req, EPROTO); return; } if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) { if (f->conn.async_read) f->conn.async_read = arg->flags & FUSE_ASYNC_READ; if (arg->max_readahead < f->conn.max_readahead) f->conn.max_readahead = arg->max_readahead; #ifdef POSIXACLS if (arg->flags & FUSE_DONT_MASK) f->conn.capable |= FUSE_CAP_DONT_MASK; #endif } else { f->conn.async_read = 0; f->conn.max_readahead = 0; } if (bufsize < FUSE_MIN_READ_BUFFER) { fprintf(stderr, "fuse: warning: buffer size too small: %zu\n", bufsize); bufsize = FUSE_MIN_READ_BUFFER; } bufsize -= 4096; if (bufsize < f->conn.max_write) f->conn.max_write = bufsize; f->got_init = 1; if (f->op.init) f->op.init(f->userdata, &f->conn); memset(&outarg, 0, sizeof(outarg)); outarg.major = FUSE_KERNEL_VERSION; /* * if POSIXACLS is not set, protocol 7.8 provides a good * compatibility with older kernel modules. * if POSIXACLS is set, we try to use protocol 7.12 supposed * to have the ability to process the umask conditionnally, * but, when using an older kernel module, we fallback to 7.8 */ #ifdef POSIXACLS if (arg->major > 7 || (arg->major == 7 && arg->minor >= 12)) outarg.minor = FUSE_KERNEL_MINOR_VERSION; else outarg.minor = FUSE_KERNEL_MINOR_FALLBACK; #else outarg.minor = FUSE_KERNEL_MINOR_VERSION; #endif if (f->conn.async_read) outarg.flags |= FUSE_ASYNC_READ; if (f->op.getlk && f->op.setlk) outarg.flags |= FUSE_POSIX_LOCKS; #ifdef POSIXACLS if (f->conn.want & FUSE_CAP_DONT_MASK) outarg.flags |= FUSE_DONT_MASK; #endif outarg.flags |= FUSE_BIG_WRITES ; outarg.max_readahead = f->conn.max_readahead; outarg.max_write = f->conn.max_write; if (f->debug) { fprintf(stderr, " INIT: %u.%u\n", outarg.major, outarg.minor); fprintf(stderr, " flags=0x%08x\n", outarg.flags); fprintf(stderr, " max_readahead=0x%08x\n", outarg.max_readahead); fprintf(stderr, " max_write=0x%08x\n", outarg.max_write); } send_reply_ok(req, &outarg, arg->minor < 5 ? 8 : sizeof(outarg)); }
/** * Init of the pseudo fuse thread @param ch : initial channel @param se : initial session @param rozofs_fuse_buffer_count : number of request buffers (corresponds to the number of fuse save context) @retval 0 on success @retval -1 on error */ int rozofs_fuse_init(struct fuse_chan *ch,struct fuse_session *se,int rozofs_fuse_buffer_count) { int status = 0; int i; // return 0; fuse_sharemem_init_done = 0; int fileflags; rozofs_fuse_ctx_p = malloc(sizeof (rozofs_fuse_ctx_t)); if (rozofs_fuse_ctx_p == NULL) { /* ** cannot allocate memory for fuse rozofs context */ return -1; } memset(rozofs_fuse_ctx_p,0,sizeof (rozofs_fuse_ctx_t)); /* ** clear read/write merge stats table */ memset(rozofs_write_merge_stats_tab,0,sizeof(uint64_t)*RZ_FUSE_WRITE_MAX); memset (rozofs_write_buf_section_table,0,sizeof(uint64_t)*ROZOFS_FUSE_NB_OF_BUSIZE_SECTION_MAX); memset (rozofs_read_buf_section_table,0,sizeof(uint64_t)*ROZOFS_FUSE_NB_OF_BUSIZE_SECTION_MAX); memset(&rozofs_fuse_read_write_stats_buf,0,sizeof(rozofs_fuse_read_write_stats)); /* ** init of the context */ rozofs_fuse_ctx_p->fuseReqPoolRef = NULL; rozofs_fuse_ctx_p->ch = NULL; rozofs_fuse_ctx_p->se = se; rozofs_fuse_ctx_p->bufsize = 0; rozofs_fuse_ctx_p->buf_fuse_req_p = NULL; rozofs_fuse_ctx_p->dir_attr_invalidate = 0; rozofs_fuse_ctx_p->initBufCount = rozofs_fuse_buffer_count; while (1) { /* ** get the receive buffer size for former channel in order to create the request distributor: ** note: by default the fuse buffer is 4K+128K: for RozoFS the payload can reach 512K (x4) */ int bufsize = fuse_chan_bufsize(ch)*4; rozofs_fuse_ctx_p->bufsize = bufsize; /* ** create the distributor fro receiving data from fuse kernel */ status = rozofs_fuse_init_rcv_buffer_pool(ROZOFS_FUSE_RECV_BUF_COUNT,bufsize); if (status < 0) { severe( "rozofs_fuse_init fuse buffer pool creation error(%d,%d)", (int)ROZOFS_FUSE_RECV_BUF_COUNT, (int)bufsize ) ; status = -1; break; } /* ** create the pool */ rozofs_fuse_ctx_p->fuseReqPoolRef = ruc_buf_poolCreate(rozofs_fuse_buffer_count,sizeof(rozofs_fuse_save_ctx_t)); if (rozofs_fuse_ctx_p->fuseReqPoolRef == NULL) { severe( "rozofs_fuse_init buffer pool creation error(%d,%d)", (int)rozofs_fuse_buffer_count, (int)sizeof(rozofs_fuse_save_ctx_t) ) ; status = -1; break; } ruc_buffer_debug_register_pool("fuseCtx", rozofs_fuse_ctx_p->fuseReqPoolRef); /* ** Allocate a head of list for queueing pending lookup requests */ for (i=0; i< ROZOFS_MAX_LKUP_QUEUE ; i++) { ruc_listHdrInit(&rozofs_lookup_queue[i]); } /* ** allocate a buffer for receiving the fuse request */ rozofs_fuse_ctx_p->buf_fuse_req_p = malloc(bufsize); if (rozofs_fuse_ctx_p == NULL) { severe( "rozofs_fuse_init out of memory %d", bufsize ) ; status = -1; break; } /* ** get the fd of the channel */ rozofs_fuse_ctx_p->fd = fuse_chan_fd(ch); /* ** wait the end of the share memroy init prior providing it to fuse */ while (rozofs_shared_mem_init_done == 0) sleep(1); /* ** create a new channel with the specific operation for rozofs (non-blocking) */ rozofs_fuse_ctx_p->ch = fuse_chan_new(&rozofs_fuse_ch_ops,fuse_chan_fd(ch),bufsize,rozofs_fuse_ctx_p); if (rozofs_fuse_ctx_p->ch == NULL) { severe( "rozofs_fuse_init fuse_chan_new error" ) ; status = -1; break; } /* ** remove the association between the initial session and channel */ fuse_session_remove_chan(ch); /* ** OK, now add the new channel */ fuse_session_add_chan(se,rozofs_fuse_ctx_p->ch ); /* ** set the channel in non blocking mode */ if((fileflags=fcntl(rozofs_fuse_ctx_p->fd,F_GETFL,0))==-1) { RUC_WARNING(errno); status = -1; break; } if((fcntl(rozofs_fuse_ctx_p->fd,F_SETFL,fileflags|O_NDELAY))==-1) { RUC_WARNING(errno); status = -1; break; } /* ** send XON to the fuse channel */ { int ret; rozofs_fuse_ctx_p->ioctl_supported = 1; rozofs_fuse_ctx_p->data_xon = 1; while(1) { ret = ioctl(rozofs_fuse_ctx_p->fd,1,NULL); if (ret < 0) { warning("ioctl error %s",strerror(errno)); rozofs_fuse_ctx_p->ioctl_supported = 0; break; } if (rozofs_fuse_ctx_p->dir_attr_invalidate == 0) { ret = ioctl(rozofs_fuse_ctx_p->fd,3,NULL); if (ret < 0) { warning("ioctl error %s",strerror(errno)); // rozofs_fuse_ctx_p->ioctl_supported = 0; rozofs_fuse_ctx_p->dir_attr_invalidate = 1; break; } } break; } } /* ** perform the connection with the socket controller */ /* ** OK, we are almost done, just need to connect with the socket controller */ rozofs_fuse_ctx_p->connectionId = ruc_sockctl_connect(rozofs_fuse_ctx_p->fd, // Reference of the socket "rozofs_fuse", // name of the socket 3, // Priority within the socket controller (void*)rozofs_fuse_ctx_p, // user param for socketcontroller callback &rozofs_fuse_callBack_sock); // Default callbacks if (rozofs_fuse_ctx_p->connectionId == NULL) { /* ** Fail to connect with the socket controller */ RUC_WARNING(-1); status = -1; break; } rozofs_fuse_get_ticker(); status = 0; break; } /* ** attach the callback on socket controller */ //#warning no poller ruc_sockCtrl_attach_applicative_poller(rozofs_fuse_scheduler_entry_point); for(i = 0; i < 3;i++) fuse_profile[i] = 0; uma_dbg_addTopic("fuse", rozofs_fuse_show); return status; }