📄 fuse-bridge.c
字号:
void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct stat *buf){ fuse_state_t *state = frame->root->state; fuse_req_t req = state->req; fuse_private_t *priv = this->private; struct fuse_file_info fi = {0, }; struct fuse_entry_param e = {0, }; fd = state->fd; fi.flags = state->flags; if (op_ret >= 0) { inode_t *fuse_inode; fi.fh = (unsigned long) fd; if ((fi.flags & 3) && priv->direct_io_mode) fi.direct_io = 1; gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": (%d) %s => %p", frame->root->unique, frame->op, state->fuse_loc.loc.path, fd); fuse_inode = inode_update (state->itable, state->fuse_loc.parent, state->fuse_loc.name, buf); if (fuse_inode->ctx) { inode_unhash_name (state->itable, fuse_inode); inode_unref (fuse_inode); fuse_inode = inode_update (state->itable, state->fuse_loc.parent, state->fuse_loc.name, buf); } { if (fuse_inode->ctx != inode->ctx) { dict_t *swap = inode->ctx; inode->ctx = fuse_inode->ctx; fuse_inode->ctx = swap; fuse_inode->generation = inode->generation; fuse_inode->st_mode = buf->st_mode; } inode_lookup (fuse_inode); /* list_del (&fd->inode_list); */ LOCK (&fuse_inode->lock); list_add (&fd->inode_list, &fuse_inode->fds); inode_unref (fd->inode); fd->inode = inode_ref (fuse_inode); UNLOCK (&fuse_inode->lock); // inode_destroy (inode); } inode_unref (fuse_inode); e.ino = fuse_inode->ino;#ifdef GF_DARWIN_HOST_OS e.generation = 0;#else e.generation = buf->st_ctime;#endif e.entry_timeout = priv->entry_timeout; e.attr_timeout = priv->attr_timeout; e.attr = *buf; e.attr.st_blksize = BIG_FUSE_CHANNEL_SIZE; fi.keep_cache = 0; // if (fi.flags & 1) // fi.direct_io = 1; if (fuse_reply_create (req, &e, &fi) == -ENOENT) { gf_log ("glusterfs-fuse", GF_LOG_WARNING, "create() got EINTR"); /* TODO: forget this node too */ state->req = 0; FUSE_FOP_NOREPLY (state, GF_FOP_CLOSE, close, fd); } } else { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": %s => -1 (%d)", req_callid (req), state->fuse_loc.loc.path, op_errno); fuse_reply_err (req, op_errno); fd_destroy (fd); } free_state (state); STACK_DESTROY (frame->root); return 0;}static voidfuse_create (fuse_req_t req, fuse_ino_t par, const char *name, mode_t mode, struct fuse_file_info *fi){ fuse_state_t *state; fd_t *fd; state = state_from_req (req); state->flags = fi->flags; fuse_loc_fill (&state->fuse_loc, state, par, name); state->fuse_loc.loc.inode = dummy_inode (state->itable); fd = fd_create (state->fuse_loc.loc.inode); state->fd = fd; LOCK (&fd->inode->lock); list_del_init (&fd->inode_list); UNLOCK (&fd->inode->lock); gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": CREATE %s", req_callid (req), state->fuse_loc.loc.path); FUSE_FOP (state, fuse_create_cbk, GF_FOP_CREATE, create, &state->fuse_loc.loc, state->flags, mode, fd); return;}static voidfuse_open (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi){ fuse_state_t *state; fd_t *fd; state = state_from_req (req); state->flags = fi->flags; fuse_loc_fill (&state->fuse_loc, state, ino, NULL); if (!state->fuse_loc.loc.inode) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": OPEN %s (fuse_loc_fill() returned NULL inode)", req_callid (req), state->fuse_loc.loc.path); fuse_reply_err (req, EINVAL); return; } fd = fd_create (state->fuse_loc.loc.inode); state->fd = fd; LOCK (&fd->inode->lock); list_del_init (&fd->inode_list); UNLOCK (&fd->inode->lock); gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": OPEN %s", req_callid (req), state->fuse_loc.loc.path); FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPEN, open, &state->fuse_loc.loc, fi->flags, fd); return;}static int32_tfuse_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, int32_t count, struct stat *stbuf){ fuse_state_t *state = frame->root->state; fuse_req_t req = state->req; if (op_ret >= 0) { gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": READ => %d/%d,%"PRId64"/%"PRId64, frame->root->unique, op_ret, state->size, state->off, stbuf->st_size); fuse_reply_vec (req, vector, count); } else { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": READ => -1 (%d)", frame->root->unique, op_errno); fuse_reply_err (req, op_errno); } free_state (state); STACK_DESTROY (frame->root); return 0;}static voidfuse_readv (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi){ fuse_state_t *state; state = state_from_req (req); state->size = size; state->off = off; gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": READ (%p, size=%d, offset=%"PRId64")", req_callid (req), FI_TO_FD (fi), size, off); FUSE_FOP (state, fuse_readv_cbk, GF_FOP_READ, readv, FI_TO_FD (fi), size, off);}static int32_tfuse_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct stat *stbuf){ fuse_state_t *state = frame->root->state; fuse_req_t req = state->req; if (op_ret >= 0) { gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": WRITE => %d/%d,%"PRId64"/%"PRId64, frame->root->unique, op_ret, state->size, state->off, stbuf->st_size); fuse_reply_write (req, op_ret); } else { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": WRITE => -1 (%d)", frame->root->unique, op_errno); fuse_reply_err (req, op_errno); } free_state (state); STACK_DESTROY (frame->root); return 0;}static voidfuse_write (fuse_req_t req, fuse_ino_t ino, const char *buf, size_t size, off_t off, struct fuse_file_info *fi){ fuse_state_t *state; struct iovec vector; state = state_from_req (req); state->size = size; state->off = off; vector.iov_base = (void *)buf; vector.iov_len = size; gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": WRITE (%p, size=%d, offset=%"PRId64")", req_callid (req), FI_TO_FD (fi), size, off); FUSE_FOP (state, fuse_writev_cbk, GF_FOP_WRITE, writev, FI_TO_FD (fi), &vector, 1, off); return;}static voidfuse_flush (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi){ fuse_state_t *state; state = state_from_req (req); gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": FLUSH %p", req_callid (req), FI_TO_FD (fi)); FUSE_FOP (state, fuse_err_cbk, GF_FOP_FLUSH, flush, FI_TO_FD (fi)); return;}static void fuse_release (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi){ fuse_state_t *state; state = state_from_req (req); state->fd = FI_TO_FD (fi); LOCK (&state->fd->inode->lock); list_del_init (&state->fd->inode_list); UNLOCK (&state->fd->inode->lock); gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": CLOSE %p", req_callid (req), FI_TO_FD (fi)); FUSE_FOP (state, fuse_err_cbk, GF_FOP_CLOSE, close, state->fd); return;}static void fuse_fsync (fuse_req_t req, fuse_ino_t ino, int datasync, struct fuse_file_info *fi){ fuse_state_t *state; state = state_from_req (req); gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": FSYNC %p", req_callid (req), FI_TO_FD (fi)); FUSE_FOP (state, fuse_err_cbk, GF_FOP_FSYNC, fsync, FI_TO_FD (fi), datasync); return;}static voidfuse_opendir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi){ fuse_state_t *state; fd_t *fd; 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": OPEN %s (fuse_loc_fill() returned NULL inode)", req_callid (req), state->fuse_loc.loc.path); fuse_reply_err (req, EINVAL); return; } fd = fd_create (state->fuse_loc.loc.inode); state->fd = fd; LOCK (&fd->inode->lock); list_del_init (&fd->inode_list); UNLOCK (&fd->inode->lock); gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": OPEN %s", req_callid (req), state->fuse_loc.loc.path); FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPENDIR, opendir, &state->fuse_loc.loc, fd);}#if 0voidfuse_dir_reply (fuse_req_t req, size_t size, off_t off, fd_t *fd){ char *buf; size_t size_limited; data_t *buf_data; buf_data = dict_get (fd->ctx, "__fuse__getdents__internal__@@!!"); buf = buf_data->data; size_limited = size; if (size_limited > (buf_data->len - off)) size_limited = (buf_data->len - off); if (off > buf_data->len) { size_limited = 0; off = 0; } fuse_reply_buf (req, buf + off, size_limited);}static int32_tfuse_getdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dir_entry_t *entries, int32_t count){ fuse_state_t *state = frame->root->state; fuse_req_t req = state->req; if (op_ret < 0) { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": READDIR => -1 (%d)", frame->root->unique, op_errno); fuse_reply_err (state->req, op_errno); } else { dir_entry_t *trav; size_t size = 0; char *buf; data_t *buf_data; gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": READDIR => %d entries", frame->root->unique, count); for (trav = entries->next; trav; trav = trav->next) { size += fuse_add_direntry (req, NULL, 0, trav->name, NULL, 0); } buf = calloc (1, size); buf_data = data_from_dynptr (buf, size); size = 0; for (trav = entries->next; trav; trav = trav->next) { size_t entry_size; entry_size = fuse_add_direntry (req, NULL, 0, trav->name, NULL, 0); fuse_add_direntry (req, buf + size, entry_size, trav->name, &trav->buf, entry_size + size); size += entry_size; } dict_set (state->fd->ctx, "__fuse__getdents__internal__@@!!", buf_data); fuse_dir_reply (state->req, state->size, state->off, state->fd); } free_state (state); STACK_DESTROY (frame->root); return 0;}static voidfuse_getdents (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, size_t size, off_t off, int32_t flag){ fuse_state_t *state; fd_t *fd = FI_TO_FD (fi); gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": GETDENTS %p", req_callid (req), FI_TO_FD (fi)); if (!off) dict_del (fd->ctx, "__fuse__getdents__internal__@@!!"); if (dict_get (fd->ctx, "__fuse__getdents__internal__@@!!")) { fuse_dir_reply (req, size, off, fd); return; } state = state_from_req (req); state->size = size; state->off = off; state->fd = fd; FUSE_FOP (state, fuse_getdents_cbk, GF_FOP_GETDENTS, getdents, fd, size, off, 0);}#endifstatic int32_tfuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *buf){ fuse_state_t *state = frame->root->state; fuse_req_t req = state->req; if (op_ret >= 0) { gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": READDIR => %d/%d,%"PRId64, frame->root->unique, op_ret, state->size, state->off); fuse_reply_buf (req, (void *)buf, op_ret); } else { gf_log ("glusterfs-fuse", GF_LOG_ERROR, "%"PRId64": READDIR => -1 (%d)", frame->root->unique, op_errno); fuse_reply_err (req, op_errno); } free_state (state); STACK_DESTROY (frame->root); return 0;}static voidfuse_readdir (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi){ fuse_state_t *state; state = state_from_req (req); state->size = size; state->off = off; gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": READDIR (%p, size=%d, offset=%"PRId64")", req_callid (req), FI_TO_FD (fi), size, off); FUSE_FOP (state, fuse_readdir_cbk, GF_FOP_READDIR, readdir, FI_TO_FD (fi), size, off);}static voidfuse_releasedir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi){ fuse_state_t *state; state = state_from_req (req); state->fd = FI_TO_FD (fi); LOCK (&state->fd->inode->lock); list_del_init (&state->fd->inode_list); UNLOCK (&state->fd->inode->lock); gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%"PRId64": CLOSEDIR %p", req_callid (req), FI_TO_FD (fi)); FUSE_FOP (state, fuse_err_cbk, GF_FOP_CLOSEDIR, closedir, state->fd);}static void fuse_fsyncdir (fuse_req_t req, fuse_ino_t ino, int datasync, struct fuse_file_info *fi){ fuse_state_t *state; state = state_from_req (req); FUSE_FOP (state, fuse_err_cbk, GF_FOP_FSYNCDIR, fsyncdir, FI_TO_FD (fi), datasync); return;}static int32_tfuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct statvfs *buf){ fuse_state_t *state = frame->root->state; fuse_req_t req = state->req; /* Filesystems (like ZFS on solaris) reports different ->f_frsize and ->f_bsize. Old coreutils df tools use statfs() and do not see ->f_frsize. the ->f_blocks, ->f_bavail and ->f_bfree are w.r.t ->f_frsize and not ->f_bsize which makes the df tools report wrong values. Scale the block counts to match ->f_bsize. */ /* TODO: with old coreutils, f_bsize is taken from stat()'s st_blksize * so the df with old coreutils this wont work :(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -