diff options
author | Kevin Hilman <khilman@linaro.org> | 2015-05-22 14:30:13 -0700 |
---|---|---|
committer | Kevin Hilman <khilman@linaro.org> | 2015-05-22 14:30:13 -0700 |
commit | e49d192fe7dcdc7bc46987f9981dc90f61e5f28c (patch) | |
tree | 84579e5de62f4d67d65203450d0e0268e1e47f2f /fs/namespace.c | |
parent | a61d3b775855a1d67d97ca0aa389489cb8a9320d (diff) | |
parent | 51af817611f2c0987030d024f24fc7ea95dd33e6 (diff) |
Merge branch 'linux-3.18.y' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into linux-linaro-lsk-v3.18lsk-v3.18-15.05
* 'linux-3.18.y' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable: (222 commits)
Linux 3.18.14
Drivers: hv: vmbus: Don't wait after requesting offers
hfsplus: don't store special "osx" xattr prefix on-disk
drm/radeon: check new address before removing old one
drm/radeon: add SI DPM quirk for Sapphire R9 270 Dual-X 2G GDDR5
drm/radeon: adjust pll when audio is not enabled
3w-sas: fix command completion race
3w-9xxx: fix command completion race
3w-xxxx: fix command completion race
ext4: move check under lock scope to close a race.
ext4: fix data corruption caused by unwritten and delayed extents
uas: Set max_sectors_240 quirk for ASM1053 devices
uas: Add US_FL_MAX_SECTORS_240 flag
uas: Allow uas_use_uas_driver to return usb-storage flags
rbd: end I/O the entire obj_request on error
tty/serial: at91: maxburst was missing for dma transfers
ACPI / SBS: Enable battery manager when present
btrfs: unlock i_mutex after attempting to delete subvolume during send
ASoC: rt5677: fixed wrong DMIC ref clock
ASoC: dapm: Enable autodisable on SOC_DAPM_SINGLE_TLV_AUTODISABLE
...
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index bbde14719655..07ba424181a5 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1322,14 +1322,15 @@ static inline void namespace_lock(void) down_write(&namespace_sem); } +enum umount_tree_flags { + UMOUNT_SYNC = 1, + UMOUNT_PROPAGATE = 2, +}; /* * mount_lock must be held * namespace_sem must be held for write - * how = 0 => just this tree, don't propagate - * how = 1 => propagate; we know that nobody else has reference to any victims - * how = 2 => lazy umount */ -void umount_tree(struct mount *mnt, int how) +static void umount_tree(struct mount *mnt, enum umount_tree_flags how) { HLIST_HEAD(tmp_list); struct mount *p; @@ -1343,7 +1344,7 @@ void umount_tree(struct mount *mnt, int how) hlist_for_each_entry(p, &tmp_list, mnt_hash) list_del_init(&p->mnt_child); - if (how) + if (how & UMOUNT_PROPAGATE) propagate_umount(&tmp_list); hlist_for_each_entry(p, &tmp_list, mnt_hash) { @@ -1351,7 +1352,7 @@ void umount_tree(struct mount *mnt, int how) list_del_init(&p->mnt_list); __touch_mnt_namespace(p->mnt_ns); p->mnt_ns = NULL; - if (how < 2) + if (how & UMOUNT_SYNC) p->mnt.mnt_flags |= MNT_SYNC_UMOUNT; if (mnt_has_parent(p)) { hlist_del_init(&p->mnt_mp_list); @@ -1456,14 +1457,14 @@ static int do_umount(struct mount *mnt, int flags) if (flags & MNT_DETACH) { if (!list_empty(&mnt->mnt_list)) - umount_tree(mnt, 2); + umount_tree(mnt, UMOUNT_PROPAGATE); retval = 0; } else { shrink_submounts(mnt); retval = -EBUSY; if (!propagate_mount_busy(mnt, 2)) { if (!list_empty(&mnt->mnt_list)) - umount_tree(mnt, 1); + umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC); retval = 0; } } @@ -1495,7 +1496,7 @@ void __detach_mounts(struct dentry *dentry) lock_mount_hash(); while (!hlist_empty(&mp->m_list)) { mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list); - umount_tree(mnt, 2); + umount_tree(mnt, 0); } unlock_mount_hash(); put_mountpoint(mp); @@ -1662,7 +1663,7 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, out: if (res) { lock_mount_hash(); - umount_tree(res, 0); + umount_tree(res, UMOUNT_SYNC); unlock_mount_hash(); } return q; @@ -1686,7 +1687,7 @@ void drop_collected_mounts(struct vfsmount *mnt) { namespace_lock(); lock_mount_hash(); - umount_tree(real_mount(mnt), 0); + umount_tree(real_mount(mnt), UMOUNT_SYNC); unlock_mount_hash(); namespace_unlock(); } @@ -1869,7 +1870,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, out_cleanup_ids: while (!hlist_empty(&tree_list)) { child = hlist_entry(tree_list.first, struct mount, mnt_hash); - umount_tree(child, 0); + umount_tree(child, UMOUNT_SYNC); } unlock_mount_hash(); cleanup_group_ids(source_mnt, NULL); @@ -2046,7 +2047,7 @@ static int do_loopback(struct path *path, const char *old_name, err = graft_tree(mnt, parent, mp); if (err) { lock_mount_hash(); - umount_tree(mnt, 0); + umount_tree(mnt, UMOUNT_SYNC); unlock_mount_hash(); } out2: @@ -2417,7 +2418,7 @@ void mark_mounts_for_expiry(struct list_head *mounts) while (!list_empty(&graveyard)) { mnt = list_first_entry(&graveyard, struct mount, mnt_expire); touch_mnt_namespace(mnt->mnt_ns); - umount_tree(mnt, 1); + umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC); } unlock_mount_hash(); namespace_unlock(); @@ -2488,7 +2489,7 @@ static void shrink_submounts(struct mount *mnt) m = list_first_entry(&graveyard, struct mount, mnt_expire); touch_mnt_namespace(m->mnt_ns); - umount_tree(m, 1); + umount_tree(m, UMOUNT_PROPAGATE|UMOUNT_SYNC); } } } |