example/passthrough_hp: Fix . and .. readdir lookup count
authorBernd Schubert <bschubert@ddn.com>
Mon, 29 Jul 2024 23:13:27 +0000 (01:13 +0200)
committerBernd Schubert <bernd.schubert@fastmail.fm>
Tue, 30 Jul 2024 08:53:16 +0000 (10:53 +0200)
Commit 170edc6a8ef0 added dot and dotdot (. and ..) to readdir
results, but introduced an issue when max number of entries
was reached - lookup count must not be decreased without
doing the lookup.
With ext4 as underlying file system readir seems to return . and ..
at random offsets and randomly failed xfstests for me.

This also fixes indentation, as passthrough_hp.cc does not follow
the linux indentation style (if we decide to fix this, it needs
to be done for the entire file).

Signed-off-by: Bernd Schubert <bschubert@ddn.com>
example/passthrough_hp.cc

index 708a38e5d697c170d95ac17ea85630949599c39b..eb225b5910165c087bc945e3db7f2af81251f6cf 100644 (file)
@@ -735,6 +735,7 @@ static void do_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
     }
 
     while (1) {
+        bool did_lookup = false;
         struct dirent *entry;
         errno = 0;
         entry = readdir(d->dp);
@@ -753,14 +754,15 @@ static void do_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
         size_t entsize;
         if (plus) {
             if (is_dot_or_dotdot(entry->d_name)) {
-               /* fuse kernel ignores attributes for these and also does
-                * not increase lookup count (see fuse_direntplus_link) */
-               e.attr.st_ino = entry->d_ino;
-               e.attr.st_mode = entry->d_type << 12;
+                /* fuse kernel ignores attributes for these and also does
+                 * not increase lookup count (see fuse_direntplus_link) */
+                e.attr.st_ino = entry->d_ino;
+                e.attr.st_mode = entry->d_type << 12;
             } else {
                 err = do_lookup(ino, entry->d_name, &e);
                 if (err)
                     goto error;
+                did_lookup = true;
             }
             entsize = fuse_add_direntry_plus(req, p, rem, entry->d_name, &e, entry->d_off);
         } else {
@@ -772,7 +774,7 @@ static void do_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
         if (entsize > rem) {
             if (fs.debug)
                 cerr << "DEBUG: readdir(): buffer full, returning data. " << endl;
-            if (plus)
+            if (did_lookup)
                 forget_one(e.ino, 1);
             break;
         }