From: Ram <linuxram@us.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org,
viro@parcelfarce.linux.theplanet.co.uk,
Andrew Morton <akpm@osdl.org>,
mike@waychison.com, bfields@fieldses.org,
Miklos Szeredi <miklos@szeredi.hu>
Subject: [RFC PATCH 7/8] automounter support for shared/slave/private/unclone
Date: Fri, 08 Jul 2005 03:26:06 -0700 [thread overview]
Message-ID: <1120817846.30164.56.camel@localhost> (raw)
In-Reply-To: <1120816835.30164.31.camel@localhost>
[-- Attachment #1: Type: text/plain, Size: 81 bytes --]
adds support for mount/umount propogation for autofs initiated
operations,
RP
[-- Attachment #2: automount.patch --]
[-- Type: text/x-patch, Size: 9709 bytes --]
adds support for mount/umount propogation for autofs initiated operations,
RP
Index: 2.6.12/fs/namespace.c
===================================================================
--- 2.6.12.orig/fs/namespace.c
+++ 2.6.12/fs/namespace.c
@@ -205,9 +205,12 @@ struct vfsmount *do_attach_prepare_mnt(s
struct vfsmount *child_mnt;
struct nameidata nd;
- if (clone_flag)
+ if (clone_flag) {
child_mnt = clone_mnt(template_mnt, template_mnt->mnt_root);
- else
+ spin_lock(&vfsmount_lock);
+ list_del_init(&child_mnt->mnt_fslink);
+ spin_unlock(&vfsmount_lock);
+ } else
child_mnt = template_mnt;
nd.mnt = mnt;
@@ -344,38 +347,16 @@ struct seq_operations mounts_op = {
* open files, pwds, chroots or sub mounts that are
* busy.
*/
-//TOBEFIXED
int may_umount_tree(struct vfsmount *mnt)
{
- struct list_head *next;
- struct vfsmount *this_parent = mnt;
- int actual_refs;
- int minimum_refs;
+ int actual_refs=0;
+ int minimum_refs=0;
+ struct vfsmount *p;
spin_lock(&vfsmount_lock);
- actual_refs = atomic_read(&mnt->mnt_count);
- minimum_refs = 2;
-repeat:
- next = this_parent->mnt_mounts.next;
-resume:
- while (next != &this_parent->mnt_mounts) {
- struct vfsmount *p = list_entry(next, struct vfsmount, mnt_child);
-
- next = next->next;
-
+ for (p = mnt; p; p = next_mnt(p, mnt)) {
actual_refs += atomic_read(&p->mnt_count);
minimum_refs += 2;
-
- if (!list_empty(&p->mnt_mounts)) {
- this_parent = p;
- goto repeat;
- }
- }
-
- if (this_parent != mnt) {
- next = this_parent->mnt_child.next;
- this_parent = this_parent->mnt_parent;
- goto resume;
}
spin_unlock(&vfsmount_lock);
@@ -387,18 +368,18 @@ resume:
EXPORT_SYMBOL(may_umount_tree);
-int mount_busy(struct vfsmount *mnt)
+int mount_busy(struct vfsmount *mnt, int refcnt)
{
struct vfspnode *parent_pnode;
if (mnt == mnt->mnt_parent || !IS_MNT_SHARED(mnt->mnt_parent))
- return do_refcount_check(mnt, 2);
+ return do_refcount_check(mnt, refcnt);
parent_pnode = mnt->mnt_parent->mnt_pnode;
BUG_ON(!parent_pnode);
return pnode_mount_busy(parent_pnode,
mnt->mnt_mountpoint,
- mnt->mnt_root, mnt);
+ mnt->mnt_root, mnt, refcnt);
}
/**
@@ -416,7 +397,9 @@ int mount_busy(struct vfsmount *mnt)
*/
int may_umount(struct vfsmount *mnt)
{
- return (!mount_busy(mnt));
+ if (mount_busy(mnt,2))
+ return -EBUSY;
+ return 0;
}
EXPORT_SYMBOL(may_umount);
@@ -435,6 +418,25 @@ void do_detach_mount(struct vfsmount *mn
spin_lock(&vfsmount_lock);
}
+void umount_mnt(struct vfsmount *mnt)
+{
+ if (mnt->mnt_parent != mnt &&
+ IS_MNT_SHARED(mnt->mnt_parent)) {
+ struct vfspnode *parent_pnode
+ = mnt->mnt_parent->mnt_pnode;
+ BUG_ON(!parent_pnode);
+ pnode_umount(parent_pnode,
+ mnt->mnt_mountpoint,
+ mnt->mnt_root);
+ } else {
+ if (IS_MNT_SHARED(mnt) || IS_MNT_SLAVE(mnt)) {
+ BUG_ON(!mnt->mnt_pnode);
+ pnode_disassociate_mnt(mnt);
+ }
+ do_detach_mount(mnt);
+ }
+}
+
void umount_tree(struct vfsmount *mnt)
{
struct vfsmount *p;
@@ -449,21 +451,7 @@ void umount_tree(struct vfsmount *mnt)
mnt = list_entry(kill.next, struct vfsmount, mnt_list);
list_del_init(&mnt->mnt_list);
list_del_init(&mnt->mnt_fslink);
- if (mnt->mnt_parent != mnt &&
- IS_MNT_SHARED(mnt->mnt_parent)) {
- struct vfspnode *parent_pnode
- = mnt->mnt_parent->mnt_pnode;
- BUG_ON(!parent_pnode);
- pnode_umount(parent_pnode,
- mnt->mnt_mountpoint,
- mnt->mnt_root);
- } else {
- if (IS_MNT_SHARED(mnt) || IS_MNT_SLAVE(mnt)) {
- BUG_ON(!mnt->mnt_pnode);
- pnode_disassociate_mnt(mnt);
- }
- do_detach_mount(mnt);
- }
+ umount_mnt(mnt);
}
}
@@ -558,7 +546,7 @@ int do_umount(struct vfsmount *mnt, int
spin_lock(&vfsmount_lock);
}
retval = -EBUSY;
- if (flags & MNT_DETACH || !mount_busy(mnt)) {
+ if (flags & MNT_DETACH || !mount_busy(mnt, 2)) {
if (!list_empty(&mnt->mnt_list))
umount_tree(mnt);
retval = 0;
@@ -964,14 +952,13 @@ struct vfsmount *do_make_mounted(struct
newmnt->mnt_pnode = NULL;
if (newmnt) {
- /* put in code for mount expiry */
- /* TOBEDONE */
-
/*
* walk through the mount list of mnt and move
* them under the new mount
*/
spin_lock(&vfsmount_lock);
+ list_del_init(&newmnt->mnt_fslink);
+
list_for_each_entry_safe(child_mnt, next,
&mnt->mnt_mounts, mnt_child) {
@@ -1412,6 +1399,8 @@ void mark_mounts_for_expiry(struct list_
if (list_empty(mounts))
return;
+ down_write(&namespace_sem);
+
spin_lock(&vfsmount_lock);
/* extract from the expiration list every vfsmount that matches the
@@ -1421,8 +1410,7 @@ void mark_mounts_for_expiry(struct list_
* cleared by mntput())
*/
list_for_each_entry_safe(mnt, next, mounts, mnt_fslink) {
- if (!xchg(&mnt->mnt_expiry_mark, 1) ||
- atomic_read(&mnt->mnt_count) != 1)
+ if (!xchg(&mnt->mnt_expiry_mark, 1) || mount_busy(mnt, 1))
continue;
mntget(mnt);
@@ -1430,12 +1418,13 @@ void mark_mounts_for_expiry(struct list_
}
/*
- * go through the vfsmounts we've just consigned to the graveyard to
- * - check that they're still dead
+ * go through the vfsmounts we've just consigned to the graveyard
* - delete the vfsmount from the appropriate namespace under lock
* - dispose of the corpse
*/
while (!list_empty(&graveyard)) {
+ struct super_block *sb;
+
mnt = list_entry(graveyard.next, struct vfsmount, mnt_fslink);
list_del_init(&mnt->mnt_fslink);
@@ -1446,60 +1435,25 @@ void mark_mounts_for_expiry(struct list_
continue;
get_namespace(namespace);
- spin_unlock(&vfsmount_lock);
- down_write(&namespace_sem);
- spin_lock(&vfsmount_lock);
-
- /* check that it is still dead: the count should now be 2 - as
- * contributed by the vfsmount parent and the mntget above */
- if (atomic_read(&mnt->mnt_count) == 2) {
- struct vfsmount *xdmnt;
- struct dentry *xdentry;
-
- /* delete from the namespace */
- list_del_init(&mnt->mnt_list);
- list_del_init(&mnt->mnt_child);
- list_del_init(&mnt->mnt_hash);
- mnt->mnt_mountpoint->d_mounted--;
-
- xdentry = mnt->mnt_mountpoint;
- mnt->mnt_mountpoint = mnt->mnt_root;
- xdmnt = mnt->mnt_parent;
- mnt->mnt_parent = mnt;
-
- spin_unlock(&vfsmount_lock);
-
- mntput(xdmnt);
- dput(xdentry);
-
- /* now lay it to rest if this was the last ref on the
- * superblock */
- if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
- /* last instance - try to be smart */
- lock_kernel();
- DQUOT_OFF(mnt->mnt_sb);
- acct_auto_close(mnt->mnt_sb);
- unlock_kernel();
- }
-
- mntput(mnt);
- } else {
- /* someone brought it back to life whilst we didn't
- * have any locks held so return it to the expiration
- * list */
- list_add_tail(&mnt->mnt_fslink, mounts);
- spin_unlock(&vfsmount_lock);
+ sb = mnt->mnt_sb;
+ umount_mnt(mnt);
+ /*
+ * now lay it to rest if this was the last ref on the
+ * superblock
+ */
+ if (atomic_read(&sb->s_active) == 1) {
+ /* last instance - try to be smart */
+ lock_kernel();
+ DQUOT_OFF(sb);
+ acct_auto_close(sb);
+ unlock_kernel();
}
-
- up_write(&namespace_sem);
-
mntput(mnt);
- put_namespace(namespace);
- spin_lock(&vfsmount_lock);
+ put_namespace(namespace);
}
-
spin_unlock(&vfsmount_lock);
+ up_write(&namespace_sem);
}
EXPORT_SYMBOL_GPL(mark_mounts_for_expiry);
Index: 2.6.12/fs/pnode.c
===================================================================
--- 2.6.12.orig/fs/pnode.c
+++ 2.6.12/fs/pnode.c
@@ -230,7 +230,7 @@ pnode_add_member_mnt(struct vfspnode *pn
static int
vfs_busy(struct vfsmount *mnt, struct dentry *dentry, struct dentry *rootdentry,
- struct vfsmount *origmnt)
+ struct vfsmount *origmnt, int refcnt)
{
struct vfsmount *child_mnt;
int ret=0;
@@ -244,9 +244,9 @@ vfs_busy(struct vfsmount *mnt, struct de
if (list_empty(&child_mnt->mnt_mounts)) {
if (origmnt == child_mnt)
- ret = do_refcount_check(child_mnt, 3);
+ ret = do_refcount_check(child_mnt, refcnt+1);
else
- ret = do_refcount_check(child_mnt, 2);
+ ret = do_refcount_check(child_mnt, refcnt);
}
mntput(child_mnt);
return ret;
@@ -254,7 +254,7 @@ vfs_busy(struct vfsmount *mnt, struct de
int
pnode_mount_busy(struct vfspnode *pnode, struct dentry *mntpt, struct dentry *root,
- struct vfsmount *mnt)
+ struct vfsmount *mnt, int refcnt)
{
int ret=0,traversal;
struct vfsmount *slave_mnt, *member_mnt, *t_m;
@@ -271,14 +271,14 @@ pnode_mount_busy(struct vfspnode *pnode,
list_for_each_entry_safe(member_mnt,
t_m, &pnode->pnode_vfs, mnt_pnode_mntlist) {
spin_unlock(&vfspnode_lock);
- if ((ret = vfs_busy(member_mnt, mntpt, root, mnt)))
+ if ((ret = vfs_busy(member_mnt, mntpt, root, mnt, refnt)))
goto out;
spin_lock(&vfspnode_lock);
}
list_for_each_entry_safe(slave_mnt,
t_m, &pnode->pnode_slavevfs, mnt_pnode_mntlist) {
spin_unlock(&vfspnode_lock);
- if ((ret = vfs_busy(slave_mnt, mntpt, root, mnt)))
+ if ((ret = vfs_busy(slave_mnt, mntpt, root, mnt, refcnt)))
goto out;
spin_lock(&vfspnode_lock);
}
Index: 2.6.12/include/linux/pnode.h
===================================================================
--- 2.6.12.orig/include/linux/pnode.h
+++ 2.6.12/include/linux/pnode.h
@@ -83,6 +83,6 @@ int pnode_prepare_mount(struct vfspnode
struct vfsmount *, struct vfsmount *);
int pnode_real_mount(struct vfspnode *, int);
int pnode_umount(struct vfspnode *, struct dentry *, struct dentry *);
-int pnode_mount_busy(struct vfspnode *, struct dentry *, struct dentry *, struct vfsmount *);
+int pnode_mount_busy(struct vfspnode *, struct dentry *, struct dentry *, struct vfsmount *, int);
#endif /* KERNEL */
#endif /* _LINUX_PNODE_H */
next prev parent reply other threads:[~2005-07-08 10:32 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1120816072.30164.10.camel@localhost>
2005-07-08 10:25 ` [RFC PATCH 0/8] shared subtree Ram
[not found] ` <1120816229.30164.13.camel@localhost>
2005-07-08 10:25 ` [RFC PATCH 1/8] share/private/slave a subtree Ram
2005-07-08 11:17 ` Pekka Enberg
2005-07-08 12:19 ` Roman Zippel
2005-07-08 12:26 ` Pekka J Enberg
2005-07-08 12:46 ` Roman Zippel
2005-07-08 12:58 ` Pekka J Enberg
2005-07-08 13:34 ` Roman Zippel
2005-07-08 16:17 ` Pekka Enberg
2005-07-08 16:33 ` share/private/slave a subtree - define vs enum Bryan Henderson
2005-07-08 16:57 ` Roman Zippel
2005-07-08 17:16 ` Bryan Henderson
2005-07-08 18:21 ` Pekka J Enberg
2005-07-08 19:11 ` Roman Zippel
2005-07-08 19:33 ` Pekka Enberg
2005-07-08 19:59 ` Roman Zippel
2005-07-10 18:21 ` Pekka Enberg
2005-07-10 18:40 ` randy_dunlap
2005-07-10 19:14 ` Roman Zippel
2005-07-11 6:37 ` Pekka J Enberg
2005-07-11 17:13 ` Horst von Brand
2005-07-11 17:57 ` Roman Zippel
2005-07-10 19:16 ` Vojtech Pavlik
2005-07-11 17:18 ` Horst von Brand
2005-07-08 19:38 ` Ram
2005-07-08 22:12 ` Bryan Henderson
2005-07-10 10:55 ` Denis Vlasenko
2005-07-08 18:03 ` Wichert Akkerman
2005-07-08 18:10 ` Mike Waychison
2005-07-08 18:15 ` Wichert Akkerman
2005-07-08 20:23 ` Mike Waychison
2005-07-10 21:57 ` Pavel Machek
2005-07-08 16:29 ` [RFC PATCH 1/8] share/private/slave a subtree Ram
2005-07-08 14:32 ` Miklos Szeredi
2005-07-08 16:19 ` Ram
2005-07-08 16:51 ` Miklos Szeredi
2005-07-08 17:52 ` Ram
2005-07-08 19:49 ` Miklos Szeredi
2005-07-14 1:27 ` Ram
2005-07-18 11:06 ` shared subtrees implementation writeup Miklos Szeredi
2005-07-18 17:18 ` Ram Pai
[not found] ` <1120816355.30164.16.camel@localhost>
2005-07-08 10:25 ` [RFC PATCH 2/8] unclone a subtree Ram
[not found] ` <1120816436.30164.19.camel@localhost>
2005-07-08 10:25 ` [RFC PATCH 3/8] bind/rbind a shared/private/slave/unclone tree Ram
[not found] ` <1120816521.30164.22.camel@localhost>
2005-07-08 10:25 ` [RFC PATCH 4/8] move " Ram
[not found] ` <1120816600.30164.25.camel@localhost>
2005-07-08 10:25 ` [RFC PATCH 5/8] umount " Ram
[not found] ` <1120816720.30164.28.camel@localhost>
2005-07-08 10:26 ` [RFC PATCH 6/8] clone a namespace containing " Ram
[not found] ` <1120816835.30164.31.camel@localhost>
2005-07-08 10:26 ` Ram [this message]
2005-07-08 10:26 ` [RFC PATCH 8/8] pnode.c optimization Ram
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1120817846.30164.56.camel@localhost \
--to=linuxram@us.ibm.com \
--cc=akpm@osdl.org \
--cc=bfields@fieldses.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mike@waychison.com \
--cc=miklos@szeredi.hu \
--cc=viro@parcelfarce.linux.theplanet.co.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.