diff options
-rw-r--r-- | fs/namespace.c | 35 | ||||
-rw-r--r-- | fs/pnode.h | 2 |
2 files changed, 31 insertions, 6 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index c7cb8a526c05..7829eab0b706 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1361,6 +1361,36 @@ enum umount_tree_flags { | |||
1361 | UMOUNT_PROPAGATE = 2, | 1361 | UMOUNT_PROPAGATE = 2, |
1362 | UMOUNT_CONNECTED = 4, | 1362 | UMOUNT_CONNECTED = 4, |
1363 | }; | 1363 | }; |
1364 | |||
1365 | static bool disconnect_mount(struct mount *mnt, enum umount_tree_flags how) | ||
1366 | { | ||
1367 | /* Leaving mounts connected is only valid for lazy umounts */ | ||
1368 | if (how & UMOUNT_SYNC) | ||
1369 | return true; | ||
1370 | |||
1371 | /* A mount without a parent has nothing to be connected to */ | ||
1372 | if (!mnt_has_parent(mnt)) | ||
1373 | return true; | ||
1374 | |||
1375 | /* Because the reference counting rules change when mounts are | ||
1376 | * unmounted and connected, umounted mounts may not be | ||
1377 | * connected to mounted mounts. | ||
1378 | */ | ||
1379 | if (!(mnt->mnt_parent->mnt.mnt_flags & MNT_UMOUNT)) | ||
1380 | return true; | ||
1381 | |||
1382 | /* Has it been requested that the mount remain connected? */ | ||
1383 | if (how & UMOUNT_CONNECTED) | ||
1384 | return false; | ||
1385 | |||
1386 | /* Is the mount locked such that it needs to remain connected? */ | ||
1387 | if (IS_MNT_LOCKED(mnt)) | ||
1388 | return false; | ||
1389 | |||
1390 | /* By default disconnect the mount */ | ||
1391 | return true; | ||
1392 | } | ||
1393 | |||
1364 | /* | 1394 | /* |
1365 | * mount_lock must be held | 1395 | * mount_lock must be held |
1366 | * namespace_sem must be held for write | 1396 | * namespace_sem must be held for write |
@@ -1398,10 +1428,7 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how) | |||
1398 | if (how & UMOUNT_SYNC) | 1428 | if (how & UMOUNT_SYNC) |
1399 | p->mnt.mnt_flags |= MNT_SYNC_UMOUNT; | 1429 | p->mnt.mnt_flags |= MNT_SYNC_UMOUNT; |
1400 | 1430 | ||
1401 | disconnect = !(((how & UMOUNT_CONNECTED) && | 1431 | disconnect = disconnect_mount(p, how); |
1402 | mnt_has_parent(p) && | ||
1403 | (p->mnt_parent->mnt.mnt_flags & MNT_UMOUNT)) || | ||
1404 | IS_MNT_LOCKED_AND_LAZY(p)); | ||
1405 | 1432 | ||
1406 | pin_insert_group(&p->mnt_umount, &p->mnt_parent->mnt, | 1433 | pin_insert_group(&p->mnt_umount, &p->mnt_parent->mnt, |
1407 | disconnect ? &unmounted : NULL); | 1434 | disconnect ? &unmounted : NULL); |
diff --git a/fs/pnode.h b/fs/pnode.h index 7114ce6e6b9e..0fcdbe7ca648 100644 --- a/fs/pnode.h +++ b/fs/pnode.h | |||
@@ -20,8 +20,6 @@ | |||
20 | #define SET_MNT_MARK(m) ((m)->mnt.mnt_flags |= MNT_MARKED) | 20 | #define SET_MNT_MARK(m) ((m)->mnt.mnt_flags |= MNT_MARKED) |
21 | #define CLEAR_MNT_MARK(m) ((m)->mnt.mnt_flags &= ~MNT_MARKED) | 21 | #define CLEAR_MNT_MARK(m) ((m)->mnt.mnt_flags &= ~MNT_MARKED) |
22 | #define IS_MNT_LOCKED(m) ((m)->mnt.mnt_flags & MNT_LOCKED) | 22 | #define IS_MNT_LOCKED(m) ((m)->mnt.mnt_flags & MNT_LOCKED) |
23 | #define IS_MNT_LOCKED_AND_LAZY(m) \ | ||
24 | (((m)->mnt.mnt_flags & (MNT_LOCKED|MNT_SYNC_UMOUNT)) == MNT_LOCKED) | ||
25 | 23 | ||
26 | #define CL_EXPIRE 0x01 | 24 | #define CL_EXPIRE 0x01 |
27 | #define CL_SLAVE 0x02 | 25 | #define CL_SLAVE 0x02 |