aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-03-28 18:23:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-03-28 18:23:01 -0400
commitaf8be4e4b316df36a00c1e52a9970c253783b57e (patch)
tree6d56665916e601ed6a933d6f85c22ee8512c6531
parentd478376cb0dc9ab16a2b6e02fd8cd1174e724c64 (diff)
parent6758f953d05378d907a164c67934cd86183d9c88 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: [PATCH] mnt_expire is protected by namespace_sem, no need for vfsmount_lock [PATCH] do shrink_submounts() for all fs types [PATCH] sanitize locking in mark_mounts_for_expiry() and shrink_submounts() [PATCH] count ghost references to vfsmounts [PATCH] reduce stack footprint in namespace.c
-rw-r--r--fs/afs/internal.h1
-rw-r--r--fs/afs/mntpt.c8
-rw-r--r--fs/afs/super.c1
-rw-r--r--fs/cifs/cifs_dfs_ref.c1
-rw-r--r--fs/namespace.c200
-rw-r--r--fs/nfs/super.c2
-rw-r--r--fs/pnode.c2
-rw-r--r--include/linux/mount.h2
8 files changed, 71 insertions, 146 deletions
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 5ca3625cd39e..9ba16edc0af2 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -573,7 +573,6 @@ extern const struct file_operations afs_mntpt_file_operations;
573 573
574extern int afs_mntpt_check_symlink(struct afs_vnode *, struct key *); 574extern int afs_mntpt_check_symlink(struct afs_vnode *, struct key *);
575extern void afs_mntpt_kill_timer(void); 575extern void afs_mntpt_kill_timer(void);
576extern void afs_umount_begin(struct vfsmount *, int);
577 576
578/* 577/*
579 * proc.c 578 * proc.c
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index a3510b8ba3e7..2f5503902c37 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -283,11 +283,3 @@ void afs_mntpt_kill_timer(void)
283 cancel_delayed_work(&afs_mntpt_expiry_timer); 283 cancel_delayed_work(&afs_mntpt_expiry_timer);
284 flush_scheduled_work(); 284 flush_scheduled_work();
285} 285}
286
287/*
288 * begin unmount by attempting to remove all automounted mountpoints we added
289 */
290void afs_umount_begin(struct vfsmount *vfsmnt, int flags)
291{
292 shrink_submounts(vfsmnt, &afs_vfsmounts);
293}
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 36bbce45f44b..4b572b801d8d 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -50,7 +50,6 @@ static const struct super_operations afs_super_ops = {
50 .write_inode = afs_write_inode, 50 .write_inode = afs_write_inode,
51 .destroy_inode = afs_destroy_inode, 51 .destroy_inode = afs_destroy_inode,
52 .clear_inode = afs_clear_inode, 52 .clear_inode = afs_clear_inode,
53 .umount_begin = afs_umount_begin,
54 .put_super = afs_put_super, 53 .put_super = afs_put_super,
55 .show_options = generic_show_options, 54 .show_options = generic_show_options,
56}; 55};
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index a1a95b027136..56c924033b78 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -33,7 +33,6 @@ void dfs_shrink_umount_helper(struct vfsmount *vfsmnt)
33{ 33{
34 mark_mounts_for_expiry(&cifs_dfs_automount_list); 34 mark_mounts_for_expiry(&cifs_dfs_automount_list);
35 mark_mounts_for_expiry(&cifs_dfs_automount_list); 35 mark_mounts_for_expiry(&cifs_dfs_automount_list);
36 shrink_submounts(vfsmnt, &cifs_dfs_automount_list);
37} 36}
38 37
39/** 38/**
diff --git a/fs/namespace.c b/fs/namespace.c
index 7953c96a2071..94f026ec990a 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -155,15 +155,15 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns)
155 } 155 }
156} 156}
157 157
158static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd) 158static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
159{ 159{
160 old_nd->path.dentry = mnt->mnt_mountpoint; 160 old_path->dentry = mnt->mnt_mountpoint;
161 old_nd->path.mnt = mnt->mnt_parent; 161 old_path->mnt = mnt->mnt_parent;
162 mnt->mnt_parent = mnt; 162 mnt->mnt_parent = mnt;
163 mnt->mnt_mountpoint = mnt->mnt_root; 163 mnt->mnt_mountpoint = mnt->mnt_root;
164 list_del_init(&mnt->mnt_child); 164 list_del_init(&mnt->mnt_child);
165 list_del_init(&mnt->mnt_hash); 165 list_del_init(&mnt->mnt_hash);
166 old_nd->path.dentry->d_mounted--; 166 old_path->dentry->d_mounted--;
167} 167}
168 168
169void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, 169void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
@@ -174,12 +174,12 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
174 dentry->d_mounted++; 174 dentry->d_mounted++;
175} 175}
176 176
177static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd) 177static void attach_mnt(struct vfsmount *mnt, struct path *path)
178{ 178{
179 mnt_set_mountpoint(nd->path.mnt, nd->path.dentry, mnt); 179 mnt_set_mountpoint(path->mnt, path->dentry, mnt);
180 list_add_tail(&mnt->mnt_hash, mount_hashtable + 180 list_add_tail(&mnt->mnt_hash, mount_hashtable +
181 hash(nd->path.mnt, nd->path.dentry)); 181 hash(path->mnt, path->dentry));
182 list_add_tail(&mnt->mnt_child, &nd->path.mnt->mnt_mounts); 182 list_add_tail(&mnt->mnt_child, &path->mnt->mnt_mounts);
183} 183}
184 184
185/* 185/*
@@ -262,10 +262,8 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
262 /* stick the duplicate mount on the same expiry list 262 /* stick the duplicate mount on the same expiry list
263 * as the original if that was on one */ 263 * as the original if that was on one */
264 if (flag & CL_EXPIRE) { 264 if (flag & CL_EXPIRE) {
265 spin_lock(&vfsmount_lock);
266 if (!list_empty(&old->mnt_expire)) 265 if (!list_empty(&old->mnt_expire))
267 list_add(&mnt->mnt_expire, &old->mnt_expire); 266 list_add(&mnt->mnt_expire, &old->mnt_expire);
268 spin_unlock(&vfsmount_lock);
269 } 267 }
270 } 268 }
271 return mnt; 269 return mnt;
@@ -548,6 +546,7 @@ void release_mounts(struct list_head *head)
548 m = mnt->mnt_parent; 546 m = mnt->mnt_parent;
549 mnt->mnt_mountpoint = mnt->mnt_root; 547 mnt->mnt_mountpoint = mnt->mnt_root;
550 mnt->mnt_parent = mnt; 548 mnt->mnt_parent = mnt;
549 m->mnt_ghosts--;
551 spin_unlock(&vfsmount_lock); 550 spin_unlock(&vfsmount_lock);
552 dput(dentry); 551 dput(dentry);
553 mntput(m); 552 mntput(m);
@@ -572,12 +571,16 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
572 __touch_mnt_namespace(p->mnt_ns); 571 __touch_mnt_namespace(p->mnt_ns);
573 p->mnt_ns = NULL; 572 p->mnt_ns = NULL;
574 list_del_init(&p->mnt_child); 573 list_del_init(&p->mnt_child);
575 if (p->mnt_parent != p) 574 if (p->mnt_parent != p) {
575 p->mnt_parent->mnt_ghosts++;
576 p->mnt_mountpoint->d_mounted--; 576 p->mnt_mountpoint->d_mounted--;
577 }
577 change_mnt_propagation(p, MS_PRIVATE); 578 change_mnt_propagation(p, MS_PRIVATE);
578 } 579 }
579} 580}
580 581
582static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts);
583
581static int do_umount(struct vfsmount *mnt, int flags) 584static int do_umount(struct vfsmount *mnt, int flags)
582{ 585{
583 struct super_block *sb = mnt->mnt_sb; 586 struct super_block *sb = mnt->mnt_sb;
@@ -650,6 +653,9 @@ static int do_umount(struct vfsmount *mnt, int flags)
650 spin_lock(&vfsmount_lock); 653 spin_lock(&vfsmount_lock);
651 event++; 654 event++;
652 655
656 if (!(flags & MNT_DETACH))
657 shrink_submounts(mnt, &umount_list);
658
653 retval = -EBUSY; 659 retval = -EBUSY;
654 if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) { 660 if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) {
655 if (!list_empty(&mnt->mnt_list)) 661 if (!list_empty(&mnt->mnt_list))
@@ -744,7 +750,7 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
744 int flag) 750 int flag)
745{ 751{
746 struct vfsmount *res, *p, *q, *r, *s; 752 struct vfsmount *res, *p, *q, *r, *s;
747 struct nameidata nd; 753 struct path path;
748 754
749 if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) 755 if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt))
750 return NULL; 756 return NULL;
@@ -769,14 +775,14 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
769 q = q->mnt_parent; 775 q = q->mnt_parent;
770 } 776 }
771 p = s; 777 p = s;
772 nd.path.mnt = q; 778 path.mnt = q;
773 nd.path.dentry = p->mnt_mountpoint; 779 path.dentry = p->mnt_mountpoint;
774 q = clone_mnt(p, p->mnt_root, flag); 780 q = clone_mnt(p, p->mnt_root, flag);
775 if (!q) 781 if (!q)
776 goto Enomem; 782 goto Enomem;
777 spin_lock(&vfsmount_lock); 783 spin_lock(&vfsmount_lock);
778 list_add_tail(&q->mnt_list, &res->mnt_list); 784 list_add_tail(&q->mnt_list, &res->mnt_list);