summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Schubert <bschubert@ddn.com>2022-03-22 22:10:01 +0100
committerNikolaus Rath <Nikolaus@rath.org>2022-03-31 15:27:02 +0100
commitf8a24e9ec779dee3d23cd25f5bf6fc1c377e7d0a (patch)
treebaeda5639745ff0ecedfe7173e6a705e4dfd7811
parenta6a01c4a76c4c8265f7d1f0a0a9b5340b15384ab (diff)
downloadfuse-f8a24e9ec779dee3d23cd25f5bf6fc1c377e7d0a.tar.gz
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.
-rw-r--r--example/passthrough_hp.cc26
1 files changed, 26 insertions, 0 deletions
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<mutex> 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<mutex> 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<mutex> 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;