diff options
author | Eric Wong <normalperson@yhbt.net> | 2014-03-05 14:45:44 +0100 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2014-03-05 14:45:44 +0100 |
commit | 6bf2e6f07c133f7b145a4726c5d962f14c650ca7 (patch) | |
tree | 7ab3a9941edad868c961404f0bbee23967990118 /example | |
parent | 0096c126aa4548df66c658afeb18a5a5356a2c57 (diff) | |
download | libfuse-6bf2e6f07c133f7b145a4726c5d962f14c650ca7.tar.gz |
libfuse: implement readdirplus for high-level API
Reuse the old "readdir" callback, but add a flags argument, that has
FUSE_READDIR_PLUS in case this is a "plus" version. Filesystems can safely
ignore this flag, but if they want they can add optimizations based on it:
i.e. only retrieve the full attributes in PLUS mode.
The filler function is also given a flags argument and the filesystem can
set FUSE_FILL_DIR_PLUS if all the attributes in "stat" are valid.
Diffstat (limited to 'example')
-rwxr-xr-x | example/fioc.c | 10 | ||||
-rwxr-xr-x | example/fsel.c | 6 | ||||
-rwxr-xr-x | example/fusexmp.c | 6 | ||||
-rwxr-xr-x | example/fusexmp_fh.c | 25 | ||||
-rwxr-xr-x | example/hello.c | 10 |
5 files changed, 39 insertions, 18 deletions
diff --git a/example/fioc.c b/example/fioc.c index 2117ac8..368f807 100755 --- a/example/fioc.c +++ b/example/fioc.c @@ -169,17 +169,19 @@ static int fioc_truncate(const char *path, off_t size) } static int fioc_readdir(const char *path, void *buf, fuse_fill_dir_t filler, - off_t offset, struct fuse_file_info *fi) + off_t offset, struct fuse_file_info *fi, + enum fuse_readdir_flags flags) { (void) fi; (void) offset; + (void) flags; if (fioc_file_type(path) != FIOC_ROOT) return -ENOENT; - filler(buf, ".", NULL, 0); - filler(buf, "..", NULL, 0); - filler(buf, FIOC_NAME, NULL, 0); + filler(buf, ".", NULL, 0, 0); + filler(buf, "..", NULL, 0, 0); + filler(buf, FIOC_NAME, NULL, 0, 0); return 0; } diff --git a/example/fsel.c b/example/fsel.c index 69202ee..b496c9a 100755 --- a/example/fsel.c +++ b/example/fsel.c @@ -87,20 +87,22 @@ static int fsel_getattr(const char *path, struct stat *stbuf) } static int fsel_readdir(const char *path, void *buf, fuse_fill_dir_t filler, - off_t offset, struct fuse_file_info *fi) + off_t offset, struct fuse_file_info *fi, + enum fuse_readdir_flags flags) { char name[2] = { }; int i; (void) offset; (void) fi; + (void) flags; if (strcmp(path, "/") != 0) return -ENOENT; for (i = 0; i < FSEL_FILES; i++) { name[0] = fsel_hex_map[i]; - filler(buf, name, NULL, 0); + filler(buf, name, NULL, 0, 0); } return 0; diff --git a/example/fusexmp.c b/example/fusexmp.c index 6f63ae9..fe20f57 100755 --- a/example/fusexmp.c +++ b/example/fusexmp.c @@ -81,13 +81,15 @@ static int xmp_readlink(const char *path, char *buf, size_t size) static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, - off_t offset, struct fuse_file_info *fi) + off_t offset, struct fuse_file_info *fi, + enum fuse_readdir_flags flags) { DIR *dp; struct dirent *de; (void) offset; (void) fi; + (void) flags; dp = opendir(path); if (dp == NULL) @@ -98,7 +100,7 @@ static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, memset(&st, 0, sizeof(st)); st.st_ino = de->d_ino; st.st_mode = de->d_type << 12; - if (filler(buf, de->d_name, &st, 0)) + if (filler(buf, de->d_name, &st, 0, 0)) break; } diff --git a/example/fusexmp_fh.c b/example/fusexmp_fh.c index ba6789b..531438f 100755 --- a/example/fusexmp_fh.c +++ b/example/fusexmp_fh.c @@ -128,7 +128,8 @@ static inline struct xmp_dirp *get_dirp(struct fuse_file_info *fi) } static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, - off_t offset, struct fuse_file_info *fi) + off_t offset, struct fuse_file_info *fi, + enum fuse_readdir_flags flags) { struct xmp_dirp *d = get_dirp(fi); @@ -141,18 +142,30 @@ static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, while (1) { struct stat st; off_t nextoff; + enum fuse_fill_dir_flags fill_flags = 0; if (!d->entry) { d->entry = readdir(d->dp); if (!d->entry) break; } - - memset(&st, 0, sizeof(st)); - st.st_ino = d->entry->d_ino; - st.st_mode = d->entry->d_type << 12; +#ifdef HAVE_FSTATAT + if (flags & FUSE_READDIR_PLUS) { + int res; + + res = fstatat(dirfd(d->dp), d->entry->d_name, &st, + AT_SYMLINK_NOFOLLOW); + if (res != -1) + fill_flags |= FUSE_FILL_DIR_PLUS; + } +#endif + if (!(fill_flags & FUSE_FILL_DIR_PLUS)) { + memset(&st, 0, sizeof(st)); + st.st_ino = d->entry->d_ino; + st.st_mode = d->entry->d_type << 12; + } nextoff = telldir(d->dp); - if (filler(buf, d->entry->d_name, &st, nextoff)) + if (filler(buf, d->entry->d_name, &st, nextoff, fill_flags)) break; d->entry = NULL; diff --git a/example/hello.c b/example/hello.c index d26d826..3c24c8b 100755 --- a/example/hello.c +++ b/example/hello.c @@ -65,17 +65,19 @@ static int hello_getattr(const char *path, struct stat *stbuf) } static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, - off_t offset, struct fuse_file_info *fi) + off_t offset, struct fuse_file_info *fi, + enum fuse_readdir_flags flags) { (void) offset; (void) fi; + (void) flags; if (strcmp(path, "/") != 0) return -ENOENT; - filler(buf, ".", NULL, 0); - filler(buf, "..", NULL, 0); - filler(buf, hello_path + 1, NULL, 0); + filler(buf, ".", NULL, 0, 0); + filler(buf, "..", NULL, 0, 0); + filler(buf, hello_path + 1, NULL, 0, 0); return 0; } |