Discussion:
PUFFS race on parent mtime update
Emmanuel Dreyfus
2014-09-03 15:46:04 UTC
Permalink
Hi

When running regression tests on FUSE filesystems, I hit a i
race condition: when I create a node in a directory, the
parent directory mtime/ctime seems to be updated asynchronously,
and some tests that check it report an error because it has not
been updated at test time.

Here is a PoC:
stat -f '%m' . ; mkfifo x; stat -f '%m' . ; sleep 1; stat -f '%m' .

This gives the result:
1409757799
1409757799
1409757818

Which means that when mkfifo returns, the parent directory
mtime is not yet updated. If I wait one second I get it alrgiht.

I have trouble to understand where parent directory ctime/mtime is
updated; Anyone can tell me how this should work?
--
Emmanuel Dreyfus
***@netbsd.org
Emmanuel Dreyfus
2014-09-05 04:22:30 UTC
Permalink
Post by Emmanuel Dreyfus
When running regression tests on FUSE filesystems, I hit a i
race condition: when I create a node in a directory, the
parent directory mtime/ctime seems to be updated asynchronously,
and some tests that check it report an error because it has not
been updated at test time.
The patch below seems to fix the problem: update parent directory mtime/ctime
cache when
- creating or removing an object
- renaming an object (update both source and destination)

Opinion?

Index: sys/fs/puffs/puffs_node.c
===================================================================
RCS file: /cvsroot/src/sys/fs/puffs/puffs_node.c,v
retrieving revision 1.23.2.2
diff -U 4 -r1.23.2.2 puffs_node.c
--- sys/fs/puffs/puffs_node.c 12 Aug 2012 12:59:50 -0000 1.23.2.2
+++ sys/fs/puffs/puffs_node.c 5 Sep 2014 04:13:18 -0000
@@ -248,8 +248,11 @@

if (PUFFS_USE_NAMECACHE(pmp))
cache_enter(dvp, vp, cnp);

+ puffs_updatenode(VPTOPP(dvp),
+ PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
+
return 0;
}

void
Index: sys/fs/puffs/puffs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/puffs/puffs_vnops.c,v
retrieving revision 1.163.2.4
diff -U 4 -r1.163.2.4 puffs_vnops.c
--- sys/fs/puffs/puffs_vnops.c 12 Aug 2012 13:13:20 -0000 1.163.2.4
+++ sys/fs/puffs/puffs_vnops.c 5 Sep 2014 04:13:19 -0000
@@ -1791,8 +1798,11 @@
error = puffs_msg_wait2(pmp, park_remove, dpn, pn);

PUFFS_MSG_RELEASE(remove);

+ puffs_updatenode(VPTOPP(dvp),
+ PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
+
RELEPN_AND_VP(dvp, dpn);
RELEPN_AND_VP(vp, pn);

error = checkerr(pmp, error, __func__);
@@ -1909,8 +1919,11 @@
error = puffs_msg_wait2(pmp, park_rmdir, dpn, pn);

PUFFS_MSG_RELEASE(rmdir);

+ puffs_updatenode(VPTOPP(dvp),
+ PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
+
/* XXX: some call cache_purge() *for both vnodes* here, investigate */
RELEPN_AND_VP(dvp, dpn);
RELEPN_AND_VP(vp, pn);

@@ -1954,10 +1967,13 @@
/*
* XXX: stay in touch with the cache. I don't like this, but
* don't have a better solution either. See also puffs_rename().
*/
- if (error == 0)
+ if (error == 0) {
puffs_updatenode(pn, PUFFS_UPDATECTIME, 0);
+ puffs_updatenode(VPTOPP(dvp),
+ PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
+ }

RELEPN_AND_VP(dvp, dpn);
puffs_releasenode(pn);

@@ -2121,8 +2137,12 @@
* don't have a better solution either. See also puffs_link().
*/
if (error == 0) {
puffs_updatenode(fpn, PUFFS_UPDATECTIME, 0);
+ puffs_updatenode(VPTOPP(fvp),
+ PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
+ puffs_updatenode(VPTOPP(tvp),
+ PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);

if (PUFFS_USE_DOTDOTCACHE(pmp) &&
(VPTOPP(fvp)->pn_parent != tdvp))
update_parent(fvp, tdvp);
--
Emmanuel Dreyfus
http://hcpnet.free.fr/pubz
***@netbsd.org
Emmanuel Dreyfus
2014-09-05 04:38:07 UTC
Permalink
Post by Emmanuel Dreyfus
The patch below seems to fix the problem: update parent directory mtime/ctime
cache when
- creating or removing an object
- renaming an object (update both source and destination)
Opinion?
Update fixing an error in rename

Index: sys/fs/puffs/puffs_node.c
===================================================================
RCS file: /cvsroot/src/sys/fs/puffs/puffs_node.c,v
retrieving revision 1.23.2.2
diff -U 4 -r1.23.2.2 puffs_node.c
--- sys/fs/puffs/puffs_node.c 12 Aug 2012 12:59:50 -0000 1.23.2.2
+++ sys/fs/puffs/puffs_node.c 5 Sep 2014 04:32:10 -0000
@@ -248,8 +248,11 @@

if (PUFFS_USE_NAMECACHE(pmp))
cache_enter(dvp, vp, cnp);

+ puffs_updatenode(VPTOPP(dvp),
+ PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
+
return 0;
}

void
Index: sys/fs/puffs/puffs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/puffs/puffs_vnops.c,v
retrieving revision 1.163.2.4
diff -U 4 -r1.163.2.4 puffs_vnops.c
--- sys/fs/puffs/puffs_vnops.c 12 Aug 2012 13:13:20 -0000 1.163.2.4
+++ sys/fs/puffs/puffs_vnops.c 5 Sep 2014 04:32:11 -0000
@@ -1791,8 +1798,11 @@
error = puffs_msg_wait2(pmp, park_remove, dpn, pn);

PUFFS_MSG_RELEASE(remove);

+ puffs_updatenode(VPTOPP(dvp),
+ PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
+
RELEPN_AND_VP(dvp, dpn);
RELEPN_AND_VP(vp, pn);

error = checkerr(pmp, error, __func__);
@@ -1909,8 +1919,11 @@
error = puffs_msg_wait2(pmp, park_rmdir, dpn, pn);

PUFFS_MSG_RELEASE(rmdir);

+ puffs_updatenode(VPTOPP(dvp),
+ PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
+
/* XXX: some call cache_purge() *for both vnodes* here, investigate */
RELEPN_AND_VP(dvp, dpn);
RELEPN_AND_VP(vp, pn);

@@ -1954,10 +1967,13 @@
/*
* XXX: stay in touch with the cache. I don't like this, but
* don't have a better solution either. See also puffs_rename().
*/
- if (error == 0)
+ if (error == 0) {
puffs_updatenode(pn, PUFFS_UPDATECTIME, 0);
+ puffs_updatenode(VPTOPP(dvp),
+ PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
+ }

RELEPN_AND_VP(dvp, dpn);
puffs_releasenode(pn);

@@ -2121,8 +2137,14 @@
* don't have a better solution either. See also puffs_link().
*/
if (error == 0) {
puffs_updatenode(fpn, PUFFS_UPDATECTIME, 0);
+ puffs_updatenode(VPTOPP(fdvp),
+ PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME, 0);
+ if (fdvp != tdvp)
+ puffs_updatenode(VPTOPP(tdvp),
+ PUFFS_UPDATECTIME|PUFFS_UPDATEMTIME,
+ 0);

if (PUFFS_USE_DOTDOTCACHE(pmp) &&
(VPTOPP(fvp)->pn_parent != tdvp))
update_parent(fvp, tdvp);
--
Emmanuel Dreyfus
http://hcpnet.free.fr/pubz
***@netbsd.org
Loading...