aboutsummaryrefslogtreecommitdiff
path: root/example
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2018-08-14 21:37:02 +0200
committerNikolaus Rath <Nikolaus@rath.org>2018-10-10 10:49:48 +0100
commit49676ed9cc2f21d52eabc464e8ab2eea6374eb34 (patch)
tree734db5e9d4b6c7cc1e7acf898e83052fc2e388de /example
parentc3fa8578867fc45ca3d842b5641a48cacbc8eea1 (diff)
downloadlibfuse-49676ed9cc2f21d52eabc464e8ab2eea6374eb34.tar.gz
passthrough_ll: fix refcount for "." and ".." entries
Kernel is not expecting an elevated lookup count for the "." and ".." entries when doing READDIRPLUS. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'example')
-rw-r--r--example/passthrough_ll.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/example/passthrough_ll.c b/example/passthrough_ll.c
index f358e55..0b92d9c 100644
--- a/example/passthrough_ll.c
+++ b/example/passthrough_ll.c
@@ -342,6 +342,12 @@ out_err:
fuse_reply_err(req, error);
}
+static int is_dot_or_dotdot(const char *name)
+{
+ return name[0] == '.' && (name[1] == '\0' ||
+ (name[1] == '.' && name[2] == '\0'));
+}
+
static void lo_do_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
off_t offset, struct fuse_file_info *fi, int plus)
{
@@ -367,6 +373,7 @@ static void lo_do_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
while (1) {
size_t entsize;
off_t nextoff;
+ const char *name;
if (!d->entry) {
errno = 0;
@@ -380,23 +387,28 @@ static void lo_do_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
}
}
nextoff = telldir(d->dp);
+ name = d->entry->d_name;
if (plus) {
struct fuse_entry_param e;
- err = lo_do_lookup(req, ino, d->entry->d_name, &e);
- if (err)
- goto error;
+ if (is_dot_or_dotdot(name)) {
+ e.ino = 0;
+ e.attr.st_ino = d->entry->d_ino;
+ e.attr.st_mode = d->entry->d_type << 12;
+ } else {
+ err = lo_do_lookup(req, ino, name, &e);
+ if (err)
+ goto error;
+ }
- entsize = fuse_add_direntry_plus(req, p, rem,
- d->entry->d_name,
+ entsize = fuse_add_direntry_plus(req, p, rem, name,
&e, nextoff);
} else {
struct stat st = {
.st_ino = d->entry->d_ino,
.st_mode = d->entry->d_type << 12,
};
- entsize = fuse_add_direntry(req, p, rem,
- d->entry->d_name,
+ entsize = fuse_add_direntry(req, p, rem, name,
&st, nextoff);
}
if (entsize > rem)