From: Bernd Schubert Date: Tue, 22 Mar 2022 21:10:01 +0000 (+0100) Subject: passthrough_hp: Fix inode ref in sfs_unlink X-Git-Tag: fuse-3.11.0~7 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=f8a24e9ec779dee3d23cd25f5bf6fc1c377e7d0a;p=qemu-gpiodev%2Flibfuse.git passthrough_hp: Fix inode ref in sfs_unlink sfs_unlink may call do_lookup(), which increases the inode ref count, but since that function does not return attributes that lookup ref count won't get automatically decreased. --- diff --git a/example/passthrough_hp.cc b/example/passthrough_hp.cc index e15f893..a421182 100644 --- a/example/passthrough_hp.cc +++ b/example/passthrough_hp.cc @@ -357,7 +357,14 @@ static int do_lookup(fuse_ino_t parent, const char *name, cerr << "DEBUG: lookup(): inode " << e->attr.st_ino << " (userspace) already known; fd = " << inode.fd << endl; lock_guard g {inode.m}; + inode.nlookup++; + if (fs.debug) + cerr << "DEBUG:" << __func__ << ":" << __LINE__ << " " + << "inode " << inode.src_ino + << " count " << inode.nlookup << endl; + + close(newfd); } else { // no existing inode /* This is just here to make Helgrind happy. It violates the @@ -367,7 +374,13 @@ static int do_lookup(fuse_ino_t parent, const char *name, lock_guard g {inode.m}; inode.src_ino = e->attr.st_ino; inode.src_dev = e->attr.st_dev; + inode.nlookup++; + if (fs.debug) + cerr << "DEBUG:" << __func__ << ":" << __LINE__ << " " + << "inode " << inode.src_ino + << " count " << inode.nlookup << endl; + inode.fd = newfd; fs_lock.unlock(); @@ -474,6 +487,10 @@ static void sfs_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t parent, { lock_guard g {inode.m}; inode.nlookup++; + if (fs.debug) + cerr << "DEBUG:" << __func__ << ":" << __LINE__ << " " + << "inode " << inode.src_ino + << " count " << inode.nlookup << endl; } fuse_reply_entry(req, &e); @@ -529,6 +546,9 @@ static void sfs_unlink(fuse_req_t req, fuse_ino_t parent, const char *name) { inode.generation++; } } + + // decrease the ref which lookup above had increased + forget_one(e.ino, 1); } auto res = unlinkat(inode_p.fd, name, 0); fuse_reply_err(req, res == -1 ? errno : 0); @@ -545,6 +565,12 @@ static void forget_one(fuse_ino_t ino, uint64_t n) { abort(); } inode.nlookup -= n; + + if (fs.debug) + cerr << "DEBUG:" << __func__ << ":" << __LINE__ << " " + << "inode " << inode.src_ino + << " count " << inode.nlookup << endl; + if (!inode.nlookup) { if (fs.debug) cerr << "DEBUG: forget: cleaning up inode " << inode.src_ino << endl;