mirror of
https://git.openafs.org/openafs.git
synced 2025-02-01 05:57:43 +00:00
LINUX: Do not lookup immediately recursive mtpts
On Linux, having a mountpoint in a volume root that points to the same volume can cause serious problems. By 'immediately recursive', I mean a situation like the following: fs mkm mtpt vol fs mkm mtpt/mtpt vol If there are multiple dentry aliases for the directory (which is possible if the directory is a mountpoint), an 'rmdir' on the recursive mountpoint can cause the client to deadlock. Since the 'rmdir' code path in Linux locks the parent directory inode to perform the rmdir, and locks the child directory inode after performing a couple of sanity checks. For an immediately recursive mountpoint, these two inodes are the same, and so we will deadlock. Reviewed-on: http://gerrit.openafs.org/7742 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Derrick Brashear <shadow@dementix.org> (cherry picked from commit d785abd5ec9302bdc1b3c33368246e573e0cd65d) Change-Id: I531adbf66cf6714e04811356b072b17335980aa3 Reviewed-on: http://gerrit.openafs.org/7952 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Derrick Brashear <shadow@dementix.org>
This commit is contained in:
parent
dda3ea5f9d
commit
85432bf0b4
@ -1245,6 +1245,18 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
|
||||
|
||||
if (vcp) {
|
||||
struct vattr vattr;
|
||||
struct vcache *parent_vc = VTOAFS(dip);
|
||||
|
||||
if (parent_vc == vcp) {
|
||||
/* This is possible if the parent dir is a mountpoint to a volume,
|
||||
* and the dir entry we looked up is a mountpoint to the same
|
||||
* volume. Linux cannot cope with this, so return an error instead
|
||||
* of risking a deadlock or panic. */
|
||||
afs_PutVCache(vcp);
|
||||
code = EDEADLK;
|
||||
AFS_GUNLOCK();
|
||||
goto done;
|
||||
}
|
||||
|
||||
ip = AFSTOV(vcp);
|
||||
afs_getattr(vcp, &vattr, credp);
|
||||
@ -1284,6 +1296,7 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
|
||||
}
|
||||
newdp = d_splice_alias(ip, dp);
|
||||
|
||||
done:
|
||||
crfree(credp);
|
||||
|
||||
/* It's ok for the file to not be found. That's noted by the caller by
|
||||
|
@ -1271,6 +1271,18 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
|
||||
|
||||
if (vcp) {
|
||||
struct vattr vattr;
|
||||
struct vcache *parent_vc = VTOAFS(dip);
|
||||
|
||||
if (parent_vc == vcp) {
|
||||
/* This is possible if the parent dir is a mountpoint to a volume,
|
||||
* and the dir entry we looked up is a mountpoint to the same
|
||||
* volume. Linux cannot cope with this, so return an error instead
|
||||
* of risking a deadlock or panic. */
|
||||
afs_PutVCache(vcp);
|
||||
code = EDEADLK;
|
||||
AFS_GUNLOCK();
|
||||
goto done;
|
||||
}
|
||||
|
||||
ip = AFSTOV(vcp);
|
||||
afs_getattr(vcp, &vattr, credp);
|
||||
@ -1312,6 +1324,7 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
|
||||
#endif
|
||||
d_add(dp, ip);
|
||||
|
||||
done:
|
||||
crfree(credp);
|
||||
|
||||
/* It's ok for the file to not be found. That's noted by the caller by
|
||||
|
Loading…
x
Reference in New Issue
Block a user