Commit 78dec11
fuse: fix race between concurrent setattrs from multiple nodes
When mounting a user-space filesystem on multiple clients, after
concurrent ->setattr() calls from different node, stale inode
attributes may be cached in some node.
This is caused by fuse_setattr() racing with
fuse_reverse_inval_inode().
When filesystem server receives setattr request, the client node
with valid iattr cached will be required to update the fuse_inode's
attr_version and invalidate the cache by fuse_reverse_inval_inode(),
and at the next call to ->getattr() they will be fetched from user
space.
The race scenario is:
1. client-1 sends setattr (iattr-1) request to server
2. client-1 receives the reply from server
3. before client-1 updates iattr-1 to the cached attributes by
fuse_change_attributes_common(), server receives another setattr
(iattr-2) request from client-2
4. server requests client-1 to update the inode attr_version and
invalidate the cached iattr, and iattr-1 becomes staled
5. client-2 receives the reply from server, and caches iattr-2
6. continue with step 2, client-1 invokes
fuse_change_attributes_common(), and caches iattr-1
The issue has been observed from concurrent of chmod, chown, or
truncate, which all invoke ->setattr() call.
The solution is to use fuse_inode's attr_version to check whether
the attributes have been modified during the setattr request's
lifetime. If so, mark the attributes as invalid in the function
fuse_change_attributes_common().
Signed-off-by: Guang Yuan Wu <gwu@ddn.com>
Reviewed-by: Bernd Schubert <bschubert@ddn.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>1 parent 763c96d commit 78dec11
1 file changed
+11
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1889 | 1889 | | |
1890 | 1890 | | |
1891 | 1891 | | |
| 1892 | + | |
1892 | 1893 | | |
1893 | 1894 | | |
1894 | 1895 | | |
| |||
1973 | 1974 | | |
1974 | 1975 | | |
1975 | 1976 | | |
| 1977 | + | |
| 1978 | + | |
1976 | 1979 | | |
1977 | 1980 | | |
1978 | 1981 | | |
| |||
1998 | 2001 | | |
1999 | 2002 | | |
2000 | 2003 | | |
| 2004 | + | |
| 2005 | + | |
| 2006 | + | |
| 2007 | + | |
| 2008 | + | |
| 2009 | + | |
| 2010 | + | |
| 2011 | + | |
2001 | 2012 | | |
2002 | 2013 | | |
2003 | 2014 | | |
| |||
0 commit comments