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

📄 fuse.c

📁 LINUX下读写NTFS分区的工具。 已经集成了通过LIBCONV库支持中文的代码。
💻 C
📖 第 1 页 / 共 5 页
字号:
                                             dh->needlen - dh->len, name,                                             &stbuf, off);        if (newlen > dh->needlen)            return 1;    } else {        newlen = dh->len + fuse_add_direntry(dh->req, NULL, 0, name, NULL, 0);        if (extend_contents(dh, newlen) == -1)            return 1;        fuse_add_direntry(dh->req, dh->contents + dh->len, dh->size - dh->len,                          name, &stbuf, newlen);    }    dh->len = newlen;    return 0;}static int readdir_fill(struct fuse *f, fuse_req_t req, fuse_ino_t ino,                        size_t size, off_t off, struct fuse_dh *dh,                        struct fuse_file_info *fi){    int err = -ENOENT;    char *path;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    if (path != NULL) {        struct fuse_intr_data d;        dh->len = 0;        dh->error = 0;        dh->needlen = size;        dh->filled = 1;        dh->req = req;        fuse_prepare_interrupt(f, req, &d);        err = fuse_fs_readdir(f->fs, path, dh, fill_dir, off, fi);        fuse_finish_interrupt(f, req, &d);        dh->req = NULL;        if (!err)            err = dh->error;        if (err)            dh->filled = 0;        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    return err;}static void fuse_lib_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,                             off_t off, struct fuse_file_info *llfi){    struct fuse *f = req_fuse_prepare(req);    struct fuse_file_info fi;    struct fuse_dh *dh = get_dirhandle(llfi, &fi);    pthread_mutex_lock(&dh->lock);    /* According to SUS, directory contents need to be refreshed on       rewinddir() */    if (!off)        dh->filled = 0;    if (!dh->filled) {        int err = readdir_fill(f, req, ino, size, off, dh, &fi);        if (err) {            reply_err(req, err);            goto out;        }    }    if (dh->filled) {        if (off < dh->len) {            if (off + size > dh->len)                size = dh->len - off;        } else            size = 0;    } else {        size = dh->len;        off = 0;    }    fuse_reply_buf(req, dh->contents + off, size); out:    pthread_mutex_unlock(&dh->lock);}static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,                            struct fuse_file_info *llfi){    struct fuse *f = req_fuse_prepare(req);    struct fuse_intr_data d;    struct fuse_file_info fi;    struct fuse_dh *dh = get_dirhandle(llfi, &fi);    char *path;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    fuse_prepare_interrupt(f, req, &d);    fuse_fs_releasedir(f->fs, path ? path : "-", &fi);    fuse_finish_interrupt(f, req, &d);    if (path)        free(path);    pthread_rwlock_unlock(&f->tree_lock);    pthread_mutex_lock(&dh->lock);    pthread_mutex_unlock(&dh->lock);    pthread_mutex_destroy(&dh->lock);    free(dh->contents);    free(dh);    reply_err(req, 0);}static void fuse_lib_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,                          struct fuse_file_info *llfi){    struct fuse *f = req_fuse_prepare(req);    struct fuse_file_info fi;    char *path;    int err;    get_dirhandle(llfi, &fi);    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    if (path != NULL) {        struct fuse_intr_data d;        fuse_prepare_interrupt(f, req, &d);        err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);        fuse_finish_interrupt(f, req, &d);        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    reply_err(req, err);}static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino){    struct fuse *f = req_fuse_prepare(req);    struct statvfs buf;    char *path;    int err;    memset(&buf, 0, sizeof(buf));    pthread_rwlock_rdlock(&f->tree_lock);    if (!ino) {        err = -ENOMEM;        path = strdup("/");    } else {        err = -ENOENT;        path = get_path(f, ino);    }    if (path) {        struct fuse_intr_data d;        fuse_prepare_interrupt(f, req, &d);        err = fuse_fs_statfs(f->fs, path, &buf);        fuse_finish_interrupt(f, req, &d);        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    if (!err)        fuse_reply_statfs(req, &buf);    else        reply_err(req, err);}static void fuse_lib_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,                              const char *value, size_t size, int flags){    struct fuse *f = req_fuse_prepare(req);    char *path;    int err;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    if (path != NULL) {        struct fuse_intr_data d;        fuse_prepare_interrupt(f, req, &d);        err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);        fuse_finish_interrupt(f, req, &d);        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    reply_err(req, err);}static int common_getxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,                           const char *name, char *value, size_t size){    int err;    char *path;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    if (path != NULL) {        struct fuse_intr_data d;        fuse_prepare_interrupt(f, req, &d);        err = fuse_fs_getxattr(f->fs, path, name, value, size);        fuse_finish_interrupt(f, req, &d);        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    return err;}static void fuse_lib_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,                              size_t size){    struct fuse *f = req_fuse_prepare(req);    int res;    if (size) {        char *value = (char *) malloc(size);        if (value == NULL) {            reply_err(req, -ENOMEM);            return;        }        res = common_getxattr(f, req, ino, name, value, size);        if (res > 0)            fuse_reply_buf(req, value, res);        else            reply_err(req, res);        free(value);    } else {        res = common_getxattr(f, req, ino, name, NULL, 0);        if (res >= 0)            fuse_reply_xattr(req, res);        else            reply_err(req, res);    }}static int common_listxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,                            char *list, size_t size){    char *path;    int err;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    if (path != NULL) {        struct fuse_intr_data d;        fuse_prepare_interrupt(f, req, &d);        err = fuse_fs_listxattr(f->fs, path, list, size);        fuse_finish_interrupt(f, req, &d);        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    return err;}static void fuse_lib_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size){    struct fuse *f = req_fuse_prepare(req);    int res;    if (size) {        char *list = (char *) malloc(size);        if (list == NULL) {            reply_err(req, -ENOMEM);            return;        }        res = common_listxattr(f, req, ino, list, size);        if (res > 0)            fuse_reply_buf(req, list, res);        else            reply_err(req, res);        free(list);    } else {        res = common_listxattr(f, req, ino, NULL, 0);        if (res >= 0)            fuse_reply_xattr(req, res);        else            reply_err(req, res);    }}static void fuse_lib_removexattr(fuse_req_t req, fuse_ino_t ino,                                 const char *name){    struct fuse *f = req_fuse_prepare(req);    char *path;    int err;    err = -ENOENT;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    if (path != NULL) {        struct fuse_intr_data d;        fuse_prepare_interrupt(f, req, &d);        err = fuse_fs_removexattr(f->fs, path, name);        fuse_finish_interrupt(f, req, &d);        free(path);    }    pthread_rwlock_unlock(&f->tree_lock);    reply_err(req, err);}static struct lock *locks_conflict(struct node *node, const struct lock *lock){    struct lock *l;    for (l = node->locks; l; l = l->next)        if (l->owner != lock->owner &&            lock->start <= l->end && l->start <= lock->end &&            (l->type == F_WRLCK || lock->type == F_WRLCK))            break;    return l;}static void delete_lock(struct lock **lockp){    struct lock *l = *lockp;    *lockp = l->next;    free(l);}static void insert_lock(struct lock **pos, struct lock *lock){    lock->next = *pos;    *pos = lock;}static int locks_insert(struct node *node, struct lock *lock){    struct lock **lp;    struct lock *newl1 = NULL;    struct lock *newl2 = NULL;    if (lock->type != F_UNLCK || lock->start != 0 || lock->end != OFFSET_MAX) {        newl1 = malloc(sizeof(struct lock));        newl2 = malloc(sizeof(struct lock));        if (!newl1 || !newl2) {            free(newl1);            free(newl2);            return -ENOLCK;        }    }    for (lp = &node->locks; *lp;) {        struct lock *l = *lp;        if (l->owner != lock->owner)            goto skip;        if (lock->type == l->type) {            if (l->end < lock->start - 1)                goto skip;            if (lock->end < l->start - 1)                break;            if (l->start <= lock->start && lock->end <= l->end)                goto out;            if (l->start < lock->start)                lock->start = l->start;            if (lock->end < l->end)                lock->end = l->end;            goto delete;        } else {            if (l->end < lock->start)                goto skip;            if (lock->end < l->start)                break;            if (lock->start <= l->start && l->end <= lock->end)                goto delete;            if (l->end <= lock->end) {                l->end = lock->start - 1;                goto skip;            }            if (lock->start <= l->start) {                l->start = lock->end + 1;                break;            }            *newl2 = *l;            newl2->start = lock->end + 1;            l->end = lock->start - 1;            insert_lock(&l->next, newl2);            newl2 = NULL;        }    skip:        lp = &l->next;        continue;    delete:        delete_lock(lp);    }    if (lock->type != F_UNLCK) {        *newl1 = *lock;        insert_lock(lp, newl1);        newl1 = NULL;    }out:    free(newl1);    free(newl2);    return 0;}static void flock_to_lock(struct flock *flock, struct lock *lock){    memset(lock, 0, sizeof(struct lock));    lock->type = flock->l_type;    lock->start = flock->l_start;    lock->end = flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;    lock->pid = flock->l_pid;}static void lock_to_flock(struct lock *lock, struct flock *flock){    flock->l_type = lock->type;    flock->l_start = lock->start;    flock->l_len = (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;    flock->l_pid = lock->pid;}static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino,                             const char *path, struct fuse_file_info *fi){    struct fuse_intr_data d;    struct flock lock;    struct lock l;    int err;    int errlock;    fuse_prepare_interrupt(f, req, &d);    memset(&lock, 0, sizeof(lock));    lock.l_type = F_UNLCK;    lock.l_whence = SEEK_SET;    err = fuse_fs_flush(f->fs, path, fi);    errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);    fuse_finish_interrupt(f, req, &d);    if (errlock != -ENOSYS) {        flock_to_lock(&lock, &l);        l.owner = fi->lock_owner;        pthread_mutex_lock(&f->lock);        locks_insert(get_node(f, ino), &l);        pthread_mutex_unlock(&f->lock);        /* if op.lock() is defined FLUSH is needed regardless of op.flush() */        if (err == -ENOSYS)            err = 0;    }    return err;}static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,                             struct fuse_file_info *fi){    struct fuse *f = req_fuse_prepare(req);    struct fuse_intr_data d;    char *path;    int err = 0;    pthread_rwlock_rdlock(&f->tree_lock);    path = get_path(f, ino);    if (f->conf.debug)        fprintf(stderr, "RELEASE%s[%llu] flags: 0x%x\n",                fi->flush ? "+FLUSH" : "",                (unsigned long long) fi->fh, fi->flags);    if (fi->flush) {        err = fuse_flush_common(f, req, ino, path, fi);        if (err == -ENOSYS)            err = 0;    }    fuse_prepare_interrupt(f, req, &d);    fuse_do_release(f, ino, path, fi);    fuse_finish_interrupt(f, req, &d);    free(path);    pthread_rwlock_unlock(&f->tree_lock);    reply_err(req, err);}static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino,                       struct fuse_file_info

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -