diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2008-02-08 17:22:15 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2008-02-08 17:22:15 +0000 |
commit | 30ece080006087a7e615cce3f7fc51b6d8a5d5bf (patch) | |
tree | 5d60a4679f82a1bb941356278d87abe2b9560d1b /lib/modules | |
parent | b20d88bbbc6e5ae67f0c99595859fd653949a3aa (diff) |
Support receiving file handle from kernel in GETATTR request; Allow operations with a NULL path argument, if the filesystem supports it
Diffstat (limited to 'lib/modules')
-rw-r--r-- | lib/modules/iconv.c | 22 | ||||
-rw-r--r-- | lib/modules/subdir.c | 248 |
2 files changed, 150 insertions, 120 deletions
diff --git a/lib/modules/iconv.c b/lib/modules/iconv.c index c0e2b80..409cb66 100644 --- a/lib/modules/iconv.c +++ b/lib/modules/iconv.c @@ -42,17 +42,27 @@ static struct iconv *iconv_get(void) static int iconv_convpath(struct iconv *ic, const char *path, char **newpathp, int fromfs) { - size_t pathlen = strlen(path); - size_t newpathlen = pathlen * 4; - char *newpath = malloc(newpathlen + 1); - size_t plen = newpathlen; - char *p = newpath; + size_t pathlen; + size_t newpathlen; + char *newpath; + size_t plen; + char *p; size_t res; int err; + if (path == NULL) { + *newpathp = NULL; + return 0; + } + + pathlen = strlen(path); + newpathlen = pathlen * 4; + newpath = malloc(newpathlen + 1); if (!newpath) return -ENOMEM; + plen = newpathlen; + p = newpath; pthread_mutex_lock(&ic->lock); do { res = iconv(fromfs ? ic->fromfs : ic->tofs, (char **) &path, @@ -607,6 +617,8 @@ static struct fuse_operations iconv_oper = { .removexattr = iconv_removexattr, .lock = iconv_lock, .bmap = iconv_bmap, + + .flag_nullpath_ok = 1, }; static struct fuse_opt iconv_opts[] = { diff --git a/lib/modules/subdir.c b/lib/modules/subdir.c index 6f7b187..3188d1f 100644 --- a/lib/modules/subdir.c +++ b/lib/modules/subdir.c @@ -27,11 +27,17 @@ static struct subdir *subdir_get(void) return fuse_get_context()->private_data; } -static char *subdir_addpath(struct subdir *d, const char *path) +static int subdir_addpath(struct subdir *d, const char *path, char **newpathp) { - unsigned newlen = d->baselen + strlen(path); - char *newpath = malloc(newlen + 2); - if (newpath) { + char *newpath = NULL; + + if (path != NULL) { + unsigned newlen = d->baselen + strlen(path); + + newpath = malloc(newlen + 2); + if (!newpath) + return -ENOMEM; + if (path[0] == '/') path++; strcpy(newpath, d->base); @@ -39,15 +45,17 @@ static char *subdir_addpath(struct subdir *d, const char *path) if (!newpath[0]) strcpy(newpath, "."); } - return newpath; + *newpathp = newpath; + + return 0; } static int subdir_getattr(const char *path, struct stat *stbuf) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_getattr(d->next, newpath, stbuf); free(newpath); } @@ -58,9 +66,9 @@ static int subdir_fgetattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_fgetattr(d->next, newpath, stbuf, fi); free(newpath); } @@ -70,9 +78,9 @@ static int subdir_fgetattr(const char *path, struct stat *stbuf, static int subdir_access(const char *path, int mask) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_access(d->next, newpath, mask); free(newpath); } @@ -146,9 +154,9 @@ static void transform_symlink(struct subdir *d, const char *path, static int subdir_readlink(const char *path, char *buf, size_t size) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_readlink(d->next, newpath, buf, size); if (!err && d->rellinks) transform_symlink(d, newpath, buf, size); @@ -160,9 +168,9 @@ static int subdir_readlink(const char *path, char *buf, size_t size) static int subdir_opendir(const char *path, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_opendir(d->next, newpath, fi); free(newpath); } @@ -174,9 +182,9 @@ static int subdir_readdir(const char *path, void *buf, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_readdir(d->next, newpath, buf, filler, offset, fi); free(newpath); @@ -187,9 +195,9 @@ static int subdir_readdir(const char *path, void *buf, static int subdir_releasedir(const char *path, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_releasedir(d->next, newpath, fi); free(newpath); } @@ -199,9 +207,9 @@ static int subdir_releasedir(const char *path, struct fuse_file_info *fi) static int subdir_mknod(const char *path, mode_t mode, dev_t rdev) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_mknod(d->next, newpath, mode, rdev); free(newpath); } @@ -211,9 +219,9 @@ static int subdir_mknod(const char *path, mode_t mode, dev_t rdev) static int subdir_mkdir(const char *path, mode_t mode) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_mkdir(d->next, newpath, mode); free(newpath); } @@ -223,9 +231,9 @@ static int subdir_mkdir(const char *path, mode_t mode) static int subdir_unlink(const char *path) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_unlink(d->next, newpath); free(newpath); } @@ -235,9 +243,9 @@ static int subdir_unlink(const char *path) static int subdir_rmdir(const char *path) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_rmdir(d->next, newpath); free(newpath); } @@ -247,9 +255,9 @@ static int subdir_rmdir(const char *path) static int subdir_symlink(const char *from, const char *path) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_symlink(d->next, from, newpath); free(newpath); } @@ -259,35 +267,43 @@ static int subdir_symlink(const char *from, const char *path) static int subdir_rename(const char *from, const char *to) { struct subdir *d = subdir_get(); - char *newfrom = subdir_addpath(d, from); - char *newto = subdir_addpath(d, to); - int err = -ENOMEM; - if (newfrom && newto) - err = fuse_fs_rename(d->next, newfrom, newto); - free(newfrom); - free(newto); + char *newfrom; + char *newto; + int err = subdir_addpath(d, from, &newfrom); + if (!err) { + err = subdir_addpath(d, to, &newto); + if (!err) { + err = fuse_fs_rename(d->next, newfrom, newto); + free(newto); + } + free(newfrom); + } return err; } static int subdir_link(const char *from, const char *to) { struct subdir *d = subdir_get(); - char *newfrom = subdir_addpath(d, from); - char *newto = subdir_addpath(d, to); - int err = -ENOMEM; - if (newfrom && newto) - err = fuse_fs_link(d->next, newfrom, newto); - free(newfrom); - free(newto); + char *newfrom; + char *newto; + int err = subdir_addpath(d, from, &newfrom); + if (!err) { + err = subdir_addpath(d, to, &newto); + if (!err) { + err = fuse_fs_link(d->next, newfrom, newto); + free(newto); + } + free(newfrom); + } return err; } static int subdir_chmod(const char *path, mode_t mode) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_chmod(d->next, newpath, mode); free(newpath); } @@ -297,9 +313,9 @@ static int subdir_chmod(const char *path, mode_t mode) static int subdir_chown(const char *path, uid_t uid, gid_t gid) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_chown(d->next, newpath, uid, gid); free(newpath); } @@ -309,9 +325,9 @@ static int subdir_chown(const char *path, uid_t uid, gid_t gid) static int subdir_truncate(const char *path, off_t size) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_truncate(d->next, newpath, size); free(newpath); } @@ -322,9 +338,9 @@ static int subdir_ftruncate(const char *path, off_t size, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_ftruncate(d->next, newpath, size, fi); free(newpath); } @@ -334,9 +350,9 @@ static int subdir_ftruncate(const char *path, off_t size, static int subdir_utimens(const char *path, const struct timespec ts[2]) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_utimens(d->next, newpath, ts); free(newpath); } @@ -347,9 +363,9 @@ static int subdir_create(const char *path, mode_t mode, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_create(d->next, newpath, mode, fi); free(newpath); } @@ -359,9 +375,9 @@ static int subdir_create(const char *path, mode_t mode, static int subdir_open(const char *path, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_open(d->next, newpath, fi); free(newpath); } @@ -372,9 +388,9 @@ static int subdir_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_read(d->next, newpath, buf, size, offset, fi); free(newpath); } @@ -385,9 +401,9 @@ static int subdir_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_write(d->next, newpath, buf, size, offset, fi); free(newpath); } @@ -397,9 +413,9 @@ static int subdir_write(const char *path, const char *buf, size_t size, static int subdir_statfs(const char *path, struct statvfs *stbuf) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_statfs(d->next, newpath, stbuf); free(newpath); } @@ -409,9 +425,9 @@ static int subdir_statfs(const char *path, struct statvfs *stbuf) static int subdir_flush(const char *path, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_flush(d->next, newpath, fi); free(newpath); } @@ -421,9 +437,9 @@ static int subdir_flush(const char *path, struct fuse_file_info *fi) static int subdir_release(const char *path, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_release(d->next, newpath, fi); free(newpath); } @@ -434,9 +450,9 @@ static int subdir_fsync(const char *path, int isdatasync, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_fsync(d->next, newpath, isdatasync, fi); free(newpath); } @@ -447,9 +463,9 @@ static int subdir_fsyncdir(const char *path, int isdatasync, struct fuse_file_info *fi) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_fsyncdir(d->next, newpath, isdatasync, fi); free(newpath); } @@ -460,9 +476,9 @@ static int subdir_setxattr(const char *path, const char *name, const char *value, size_t size, int flags) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_setxattr(d->next, newpath, name, value, size, flags); free(newpath); @@ -474,9 +490,9 @@ static int subdir_getxattr(const char *path, const char *name, char *value, size_t size) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_getxattr(d->next, newpath, name, value, size); free(newpath); } @@ -486,9 +502,9 @@ static int subdir_getxattr(const char *path, const char *name, char *value, static int subdir_listxattr(const char *path, char *list, size_t size) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_listxattr(d->next, newpath, list, size); free(newpath); } @@ -498,9 +514,9 @@ static int subdir_listxattr(const char *path, char *list, size_t size) static int subdir_removexattr(const char *path, const char *name) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_removexattr(d->next, newpath, name); free(newpath); } @@ -511,9 +527,9 @@ static int subdir_lock(const char *path, struct fuse_file_info *fi, int cmd, struct flock *lock) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_lock(d->next, newpath, fi, cmd, lock); free(newpath); } @@ -523,9 +539,9 @@ static int subdir_lock(const char *path, struct fuse_file_info *fi, int cmd, static int subdir_bmap(const char *path, size_t blocksize, uint64_t *idx) { struct subdir *d = subdir_get(); - char *newpath = subdir_addpath(d, path); - int err = -ENOMEM; - if (newpath) { + char *newpath; + int err = subdir_addpath(d, path, &newpath); + if (!err) { err = fuse_fs_bmap(d->next, newpath, blocksize, idx); free(newpath); } @@ -584,6 +600,8 @@ static struct fuse_operations subdir_oper = { .removexattr = subdir_removexattr, .lock = subdir_lock, .bmap = subdir_bmap, + + .flag_nullpath_ok = 1, }; static struct fuse_opt subdir_opts[] = { |