📄 fuse.c
字号:
static void forget_node(struct fuse *f, fuse_ino_t nodeid, uint64_t nlookup){ struct node *node; if (nodeid == FUSE_ROOT_ID) return; pthread_mutex_lock(&f->lock); node = get_node(f, nodeid); assert(node->nlookup >= nlookup); node->nlookup -= nlookup; if (!node->nlookup) { unhash_name(f, node); unref_node(f, node); } pthread_mutex_unlock(&f->lock);}static void remove_node(struct fuse *f, fuse_ino_t dir, const char *name){ struct node *node; pthread_mutex_lock(&f->lock); node = lookup_node(f, dir, name); if (node != NULL) unhash_name(f, node); pthread_mutex_unlock(&f->lock);}static int rename_node(struct fuse *f, fuse_ino_t olddir, const char *oldname, fuse_ino_t newdir, const char *newname, int hide){ struct node *node; struct node *newnode; int err = 0; pthread_mutex_lock(&f->lock); node = lookup_node(f, olddir, oldname); newnode = lookup_node(f, newdir, newname); if (node == NULL) goto out; if (newnode != NULL) { if (hide) { fprintf(stderr, "fuse: hidden file got created during hiding\n"); err = -EBUSY; goto out; } unhash_name(f, newnode); } unhash_name(f, node); if (hash_name(f, node, newdir, newname) == -1) { err = -ENOMEM; goto out; } if (hide) node->is_hidden = 1; out: pthread_mutex_unlock(&f->lock); return err;}static void set_stat(struct fuse *f, fuse_ino_t nodeid, struct stat *stbuf){ if (!f->conf.use_ino) stbuf->st_ino = nodeid; if (f->conf.set_mode) stbuf->st_mode = (stbuf->st_mode & S_IFMT) | (0777 & ~f->conf.umask); if (f->conf.set_uid) stbuf->st_uid = f->conf.uid; if (f->conf.set_gid) stbuf->st_gid = f->conf.gid;}static struct fuse *req_fuse(fuse_req_t req){ return (struct fuse *) fuse_req_userdata(req);}static void fuse_intr_sighandler(int sig){ (void) sig; /* Nothing to do */}struct fuse_intr_data { pthread_t id; pthread_cond_t cond; int finished;};static void fuse_interrupt(fuse_req_t req, void *d_){ struct fuse_intr_data *d = d_; struct fuse *f = req_fuse(req); if (d->id == pthread_self()) return; pthread_mutex_lock(&f->lock); while (!d->finished) { struct timeval now; struct timespec timeout; pthread_kill(d->id, f->conf.intr_signal); gettimeofday(&now, NULL); timeout.tv_sec = now.tv_sec + 1; timeout.tv_nsec = now.tv_usec * 1000; pthread_cond_timedwait(&d->cond, &f->lock, &timeout); } pthread_mutex_unlock(&f->lock);}static void fuse_do_finish_interrupt(struct fuse *f, fuse_req_t req, struct fuse_intr_data *d){ pthread_mutex_lock(&f->lock); d->finished = 1; pthread_cond_broadcast(&d->cond); pthread_mutex_unlock(&f->lock); fuse_req_interrupt_func(req, NULL, NULL); pthread_cond_destroy(&d->cond);}static void fuse_do_prepare_interrupt(fuse_req_t req, struct fuse_intr_data *d){ d->id = pthread_self(); pthread_cond_init(&d->cond, NULL); d->finished = 0; fuse_req_interrupt_func(req, fuse_interrupt, d);}static inline void fuse_finish_interrupt(struct fuse *f, fuse_req_t req, struct fuse_intr_data *d){ if (f->conf.intr) fuse_do_finish_interrupt(f, req, d);}static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req, struct fuse_intr_data *d){ if (f->conf.intr) fuse_do_prepare_interrupt(req, d);}#ifndef __FreeBSD__static int fuse_compat_open(struct fuse_fs *fs, const char *path, struct fuse_file_info *fi){ int err; if (!fs->compat || fs->compat >= 25) err = fs->op.open(path, fi); else if (fs->compat == 22) { struct fuse_file_info_compat tmp; memcpy(&tmp, fi, sizeof(tmp)); err = ((struct fuse_operations_compat22 *) &fs->op)->open(path, &tmp); memcpy(fi, &tmp, sizeof(tmp)); fi->fh = tmp.fh; } else err = ((struct fuse_operations_compat2 *) &fs->op) ->open(path, fi->flags); return err;}static int fuse_compat_release(struct fuse_fs *fs, const char *path, struct fuse_file_info *fi){ if (!fs->compat || fs->compat >= 22) return fs->op.release(path, fi); else return ((struct fuse_operations_compat2 *) &fs->op) ->release(path, fi->flags);}static int fuse_compat_opendir(struct fuse_fs *fs, const char *path, struct fuse_file_info *fi){ if (!fs->compat || fs->compat >= 25) return fs->op.opendir(path, fi); else { int err; struct fuse_file_info_compat tmp; memcpy(&tmp, fi, sizeof(tmp)); err = ((struct fuse_operations_compat22 *) &fs->op) ->opendir(path, &tmp); memcpy(fi, &tmp, sizeof(tmp)); fi->fh = tmp.fh; return err; }}static void convert_statfs_compat(struct fuse_statfs_compat1 *compatbuf, struct statvfs *stbuf){ stbuf->f_bsize = compatbuf->block_size; stbuf->f_blocks = compatbuf->blocks; stbuf->f_bfree = compatbuf->blocks_free; stbuf->f_bavail = compatbuf->blocks_free; stbuf->f_files = compatbuf->files; stbuf->f_ffree = compatbuf->files_free; stbuf->f_namemax = compatbuf->namelen;}static void convert_statfs_old(struct statfs *oldbuf, struct statvfs *stbuf){ stbuf->f_bsize = oldbuf->f_bsize; stbuf->f_blocks = oldbuf->f_blocks; stbuf->f_bfree = oldbuf->f_bfree; stbuf->f_bavail = oldbuf->f_bavail; stbuf->f_files = oldbuf->f_files; stbuf->f_ffree = oldbuf->f_ffree; stbuf->f_namemax = oldbuf->f_namelen;}static int fuse_compat_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf){ int err; if (!fs->compat || fs->compat >= 25) { err = fs->op.statfs(fs->compat == 25 ? "/" : path, buf); } else if (fs->compat > 11) { struct statfs oldbuf; err = ((struct fuse_operations_compat22 *) &fs->op) ->statfs("/", &oldbuf); if (!err) convert_statfs_old(&oldbuf, buf); } else { struct fuse_statfs_compat1 compatbuf; memset(&compatbuf, 0, sizeof(struct fuse_statfs_compat1)); err = ((struct fuse_operations_compat1 *) &fs->op)->statfs(&compatbuf); if (!err) convert_statfs_compat(&compatbuf, buf); } return err;}#else /* __FreeBSD__ */static inline int fuse_compat_open(struct fuse_fs *fs, char *path, struct fuse_file_info *fi){ return fs->op.open(path, fi);}static inline int fuse_compat_release(struct fuse_fs *fs, const char *path, struct fuse_file_info *fi){ return fs->op.release(path, fi);}static inline int fuse_compat_opendir(struct fuse_fs *fs, const char *path, struct fuse_file_info *fi){ return fs->op.opendir(path, fi);}static inline int fuse_compat_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf){ return fs->op.statfs(fs->compat == 25 ? "/" : path, buf);}#endif /* __FreeBSD__ */int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf){ fuse_get_context()->private_data = fs->user_data; if (fs->op.getattr) return fs->op.getattr(path, buf); else return -ENOSYS;}int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct stat *buf, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.fgetattr) return fs->op.fgetattr(path, buf, fi); else if (fs->op.getattr) return fs->op.getattr(path, buf); else return -ENOSYS;}int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath, const char *newpath){ fuse_get_context()->private_data = fs->user_data; if (fs->op.rename) return fs->op.rename(oldpath, newpath); else return -ENOSYS;}int fuse_fs_unlink(struct fuse_fs *fs, const char *path){ fuse_get_context()->private_data = fs->user_data; if (fs->op.unlink) return fs->op.unlink(path); else return -ENOSYS;}int fuse_fs_rmdir(struct fuse_fs *fs, const char *path){ fuse_get_context()->private_data = fs->user_data; if (fs->op.rmdir) return fs->op.rmdir(path); else return -ENOSYS;}int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname, const char *path){ fuse_get_context()->private_data = fs->user_data; if (fs->op.symlink) return fs->op.symlink(linkname, path); else return -ENOSYS;}int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath){ fuse_get_context()->private_data = fs->user_data; if (fs->op.link) return fs->op.link(oldpath, newpath); else return -ENOSYS;}int fuse_fs_release(struct fuse_fs *fs, const char *path, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.release) return fuse_compat_release(fs, path, fi); else return 0;}int fuse_fs_opendir(struct fuse_fs *fs, const char *path, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.opendir) return fuse_compat_opendir(fs, path, fi); else return 0;}int fuse_fs_open(struct fuse_fs *fs, const char *path, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.open) return fuse_compat_open(fs, path, fi); else return 0;}int fuse_fs_read(struct fuse_fs *fs, const char *path, char *buf, size_t size, off_t off, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.read) return fs->op.read(path, buf, size, off, fi); else return -ENOSYS;}int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *buf, size_t size, off_t off, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.write) return fs->op.write(path, buf, size, off, fi); else return -ENOSYS;}int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.fsync) return fs->op.fsync(path, datasync, fi); else return -ENOSYS;}int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.fsyncdir) return fs->op.fsyncdir(path, datasync, fi); else return -ENOSYS;}int fuse_fs_flush(struct fuse_fs *fs, const char *path, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.flush) return fs->op.flush(path, fi); else return -ENOSYS;}int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf){ fuse_get_context()->private_data = fs->user_data; if (fs->op.statfs) return fuse_compat_statfs(fs, path, buf); else { buf->f_namemax = 255; buf->f_bsize = 512; return 0; }}int fuse_fs_releasedir(struct fuse_fs *fs, const char *path, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.releasedir) return fs->op.releasedir(path, fi); else return 0;}static int fill_dir_old(struct fuse_dirhandle *dh, const char *name, int type, ino_t ino){ int res; struct stat stbuf; memset(&stbuf, 0, sizeof(stbuf)); stbuf.st_mode = type << 12; stbuf.st_ino = ino; res = dh->filler(dh->buf, name, &stbuf, 0); return res ? -ENOMEM : 0;}int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf, fuse_fill_dir_t filler, off_t off, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.readdir) return fs->op.readdir(path, buf, filler, off, fi); else if (fs->op.getdir) { struct fuse_dirhandle dh; dh.filler = filler; dh.buf = buf; return fs->op.getdir(path, &dh, fill_dir_old); } else return -ENOSYS;}int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.create) return fs->op.create(path, mode, fi); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -