📄 fuse.c
字号:
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);}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 fs->op.release(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 fs->op.opendir(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 fs->op.open(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 fs->op.statfs(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;}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 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 return -ENOSYS;}int fuse_fs_lock(struct fuse_fs *fs, const char *path, struct fuse_file_info *fi, int cmd, struct flock *lock){ fuse_get_context()->private_data = fs->user_data; if (fs->op.lock) return fs->op.lock(path, fi, cmd, lock); else return -ENOSYS;}int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid){ fuse_get_context()->private_data = fs->user_data; if (fs->op.chown) return fs->op.chown(path, uid, gid); else return -ENOSYS;}int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size){ fuse_get_context()->private_data = fs->user_data; if (fs->op.truncate) return fs->op.truncate(path, size); else return -ENOSYS;}int fuse_fs_ftruncate(struct fuse_fs *fs, const char *path, off_t size, struct fuse_file_info *fi){ fuse_get_context()->private_data = fs->user_data; if (fs->op.ftruncate) return fs->op.ftruncate(path, size, fi); else if (fs->op.truncate) return fs->op.truncate(path, size); else return -ENOSYS;}int fuse_fs_utimens(struct fuse_fs *fs, const char *path, const struct timespec tv[2]){ fuse_get_context()->private_data = fs->user_data; if (fs->op.utimens) return fs->op.utimens(path, tv); else if(fs->op.utime) { struct utimbuf buf; buf.actime = tv[0].tv_sec; buf.modtime = tv[1].tv_sec; return fs->op.utime(path, &buf); } else return -ENOSYS;}int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask){ fuse_get_context()->private_data = fs->user_data; if (fs->op.access) return fs->op.access(path, mask); else return -ENOSYS;}int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf, size_t len){ fuse_get_context()->private_data = fs->user_data; if (fs->op.readlink) return fs->op.readlink(path, buf, len); else return -ENOSYS;}int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode, dev_t rdev){ fuse_get_context()->private_data = fs->user_data; if (fs->op.mknod) return fs->op.mknod(path, mode, rdev); else return -ENOSYS;}int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode){ fuse_get_context()->private_data = fs->user_data; if (fs->op.mkdir) return fs->op.mkdir(path, mode); else return -ENOSYS;}int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name, const char *value, size_t size, int flags){ fuse_get_context()->private_data = fs->user_data; if (fs->op.setxattr) return fs->op.setxattr(path, name, value, size, flags); else return -ENOSYS;}int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name, char *value, size_t size){ fuse_get_context()->private_data = fs->user_data; if (fs->op.getxattr) return fs->op.getxattr(path, name, value, size); else return -ENOSYS;}int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list, size_t size){ fuse_get_context()->private_data = fs->user_data; if (fs->op.listxattr) return fs->op.listxattr(path, list, size); else return -ENOSYS;}int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize, uint64_t *idx){ fuse_get_context()->private_data = fs->user_data; if (fs->op.bmap) return fs->op.bmap(path, blocksize, idx); else return -ENOSYS;}int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, const char *name){ fuse_get_context()->private_data = fs->user_data; if (fs->op.removexattr) return fs->op.removexattr(path, name); else return -ENOSYS;}static int is_open(struct fuse *f, fuse_ino_t dir, const char *name){ struct node *node; int isopen = 0; pthread_mutex_lock(&f->lock); node = lookup_node(f, dir, name); if (node && node->open_count > 0) isopen = 1; pthread_mutex_unlock(&f->lock); return isopen;}static char *hidden_name(struct fuse *f, fuse_ino_t dir, const char *oldname, char *newname, size_t bufsize){ struct stat buf; struct node *node; struct node *newnode; char *newpath; int res; int failctr = 10; do { pthread_mutex_lock(&f->lock); node = lookup_node(f, dir, oldname); if (node == NULL) { pthread_mutex_unlock(&f->lock); return NULL; } do { f->hidectr ++; snprintf(newname, bufsize, ".fuse_hidden%08x%08x", (unsigned int) node->nodeid, f->hidectr); newnode = lookup_node(f, dir, newname); } while(newnode); pthread_mutex_unlock(&f->lock); newpath = get_path_name(f, dir, newname); if (!newpath) break; res = fuse_fs_getattr(f->fs, newpath, &buf); if (res == -ENOENT) break; free(newpath); newpath = NULL; } while(res == 0 && --failctr); return newpath;}static int hide_node(struct fuse *f, const char *oldpath, fuse_ino_t dir, const char *oldname){ char newname[64]; char *newpath; int err = -EBUSY; newpath = hidden_name(f, dir, oldname, newname, sizeof(newname)); if (newpath) { err = fuse_fs_rename(f->fs, oldpath, newpath); if (!err) err = rename_node(f, dir, oldname, dir, newname, 1); free(newpath); } return err;}static int mtime_eq(const struct stat *stbuf, const struct timespec *ts){ return stbuf->st_mtime == ts->tv_sec && ST_MTIM_NSEC(stbuf) == ts->tv_nsec;}#ifndef CLOCK_MONOTONIC#define CLOCK_MONOTONIC CLOCK_REALTIME#endifstatic void curr_time(struct timespec *now){ static clockid_t clockid = CLOCK_MONOTONIC; int res = clock_gettime(clockid, now); if (res == -1 && errno == EINVAL) { clockid = CLOCK_REALTIME; res = clock_gettime(clockid, now); } if (res == -1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -