aboutsummaryrefslogtreecommitdiff
path: root/example
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2014-03-05 14:45:44 +0100
committerMiklos Szeredi <mszeredi@suse.cz>2014-03-05 14:45:44 +0100
commit6bf2e6f07c133f7b145a4726c5d962f14c650ca7 (patch)
tree7ab3a9941edad868c961404f0bbee23967990118 /example
parent0096c126aa4548df66c658afeb18a5a5356a2c57 (diff)
downloadlibfuse-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-xexample/fioc.c10
-rwxr-xr-xexample/fsel.c6
-rwxr-xr-xexample/fusexmp.c6
-rwxr-xr-xexample/fusexmp_fh.c25
-rwxr-xr-xexample/hello.c10
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;
}