linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alexander Viro <viro@math.psu.edu>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] lazy umount (2/4)
Date: Fri, 14 Sep 2001 15:02:31 -0400 (EDT)	[thread overview]
Message-ID: <Pine.GSO.4.21.0109141502090.11172-100000@weyl.math.psu.edu> (raw)
In-Reply-To: <Pine.GSO.4.21.0109141427070.11172-100000@weyl.math.psu.edu>

Part 2/4:
	Added minimal rootfs (read-only root directory - absolute minimum,
just to have something to go with root vfsmount), Now we have a fixed
root vfsmount and that allows to kill a lot of special-casing,

diff -urN S10-pre9-move_vfsmnt/fs/super.c S10-pre9-root_vfsmnt/fs/super.c
--- S10-pre9-move_vfsmnt/fs/super.c	Fri Sep 14 14:02:32 2001
+++ S10-pre9-root_vfsmnt/fs/super.c	Fri Sep 14 14:03:34 2001
@@ -280,6 +280,7 @@
 }
 
 static LIST_HEAD(vfsmntlist);
+static struct vfsmount *root_vfsmnt;
 
 static struct list_head *mount_hashtable;
 static int hash_mask, hash_bits;
@@ -346,52 +347,6 @@
 	nd->dentry->d_mounted++;
 }
 
-/**
- *	add_vfsmnt - add a new mount node
- *	@nd: location of mountpoint or %NULL if we want a root node
- *	@root: root of (sub)tree to be mounted
- *	@dev_name: device name to show in /proc/mounts or %NULL (for "none").
- *
- *	This is VFS idea of mount. New node is allocated, bound to a tree
- *	we are mounting and optionally (OK, usually) registered as mounted
- *	on a given mountpoint. Returns a pointer to new node or %NULL in
- *	case of failure.
- *
- *	Potential reason for failure (aside of trivial lack of memory) is a
- *	deleted mountpoint. Caller must hold ->i_zombie on mountpoint
- *	dentry (if any).
- */
-
-static struct vfsmount *add_vfsmnt(struct dentry *root, const char *dev_name)
-{
-	struct vfsmount *mnt;
-	struct super_block *sb = root->d_inode->i_sb;
-	char *name;
-
-	mnt = alloc_vfsmnt();
-	if (!mnt)
-		goto out;
-
-	/* It may be NULL, but who cares? */
-	if (dev_name) {
-		name = kmalloc(strlen(dev_name)+1, GFP_KERNEL);
-		if (name) {
-			strcpy(name, dev_name);
-			mnt->mnt_devname = name;
-		}
-	}
-	mnt->mnt_sb = sb;
-	mnt->mnt_root = dget(root);
-	mnt->mnt_mountpoint = mnt->mnt_root;
-	mnt->mnt_parent = mnt;
-
-	spin_lock(&dcache_lock);
-	list_add(&mnt->mnt_list, vfsmntlist.prev);
-	spin_unlock(&dcache_lock);
-out:
-	return mnt;
-}
-
 static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root)
 {
 	char *name = old->mnt_devname;
@@ -1200,8 +1155,7 @@
 		list_del(&mnt->mnt_list);
 		spin_unlock(&dcache_lock);
 		mntput(mnt);
-		if (parent_nd.mnt != mnt)
-			path_release(&parent_nd);
+		path_release(&parent_nd);
 		return 0;
 	}
 	spin_unlock(&dcache_lock);
@@ -1241,8 +1195,7 @@
 	list_del(&mnt->mnt_list);
 	spin_unlock(&dcache_lock);
 	mntput(mnt);
-	if (parent_nd.mnt != mnt)
-		path_release(&parent_nd);
+	path_release(&parent_nd);
 	return 0;
 }
 
@@ -1601,6 +1554,7 @@
 
 void __init mount_root(void)
 {
+	struct nameidata root_nd;
 	struct file_system_type * fs_type;
 	struct super_block * sb;
 	struct vfsmount *vfsmnt;
@@ -1610,6 +1564,7 @@
 	void *handle;
 	char path[64];
 	int path_start = -1;
+	char *name = "/dev/root";
 
 #ifdef CONFIG_ROOT_NFS
 	void *data;
@@ -1746,13 +1701,26 @@
 		fs_type->name,
 		(sb->s_flags & MS_RDONLY) ? " readonly" : "");
 	if (path_start >= 0) {
+		name = path + path_start;
 		devfs_mk_symlink (NULL, "root", DEVFS_FL_DEFAULT,
-				  path + 5 + path_start, NULL, NULL);
-		memcpy (path + path_start, "/dev/", 5);
-		vfsmnt = add_vfsmnt(sb->s_root, path + path_start);
+				  name + 5, NULL, NULL);
+		memcpy (name, "/dev/", 5);
 	}
-	else
-		vfsmnt = add_vfsmnt(sb->s_root, "/dev/root");
+	vfsmnt = alloc_vfsmnt();
+	if (!vfsmnt)
+		panic("VFS: alloc_vfsmnt failed for root fs");
+
+	vfsmnt->mnt_devname = kmalloc(strlen(name)+1, GFP_KERNEL);
+	if (vfsmnt->mnt_devname)
+		strcpy(vfsmnt->mnt_devname, name);
+	vfsmnt->mnt_sb = sb;
+	vfsmnt->mnt_root = dget(sb->s_root);
+
+	root_nd.mnt = root_vfsmnt;
+	root_nd.dentry = root_vfsmnt->mnt_sb->s_root;
+	graft_tree(vfsmnt, &root_nd);
+	mntput(vfsmnt);
+
 	/* FIXME: if something will try to umount us right now... */
 	if (vfsmnt) {
 		set_fs_root(current->fs, vfsmnt, sb->s_root);
@@ -1761,10 +1729,8 @@
 			bdput(bdev); /* sb holds a reference */
 		return;
 	}
-	panic("VFS: add_vfsmnt failed for root fs");
 }
 
-
 static void chroot_fs_refs(struct dentry *old_root,
 			   struct vfsmount *old_rootmnt,
 			   struct dentry *new_root,
@@ -1878,15 +1844,12 @@
 	detach_mnt(new_nd.mnt, &parent_nd);
 	detach_mnt(root_mnt, &root_parent);
 	attach_mnt(root_mnt, &old_nd);
-	if (root_parent.mnt != root_mnt)
-		attach_mnt(new_nd.mnt, &root_parent);
+	attach_mnt(new_nd.mnt, &root_parent);
 	spin_unlock(&dcache_lock);
 	chroot_fs_refs(root,root_mnt,new_nd.dentry,new_nd.mnt);
 	error = 0;
-	if (root_parent.mnt != root_mnt)
-		path_release(&root_parent);
-	if (parent_nd.mnt != new_nd.mnt)
-		path_release(&parent_nd);
+	path_release(&root_parent);
+	path_release(&parent_nd);
 out2:
 	up(&old_nd.dentry->d_inode->i_zombie);
 	up(&mount_sem);
@@ -1959,24 +1922,19 @@
 		if (!blivet) {
 			spin_lock(&dcache_lock);
 			list_del(&old_rootmnt->mnt_list);
-			if (atomic_read(&old_rootmnt->mnt_count) > 2) {
-				spin_unlock(&dcache_lock);
-				mntput(old_rootmnt);
-				blivet = -EBUSY;
-			} else {
-				spin_unlock(&dcache_lock);
-				mntput(old_rootmnt);
-				if (parent_nd.mnt != old_rootmnt)
-					path_release(&parent_nd);
-				mntput(old_rootmnt);
-				ioctl_by_bdev(ramdisk, BLKFLSBUF, 0);
-				printk("okay\n");
-				error = 0;
-			}
+			spin_unlock(&dcache_lock);
+			mntput(old_rootmnt);
+			mntput(old_rootmnt);
+			blivet = ioctl_by_bdev(ramdisk, BLKFLSBUF, 0);
+			path_release(&parent_nd);
 			blkdev_put(ramdisk, BDEV_FS);
 		}
-		if (blivet)
+		if (blivet) {
 			printk(KERN_ERR "error %d\n", blivet);
+		} else  {
+			printk("okay\n");
+			error = 0;
+		}
 		kfree(new_devname);
 		return error;
 	}
@@ -1991,8 +1949,7 @@
 	spin_unlock(&dcache_lock);
 
 	/* put the old stuff */
-	if (parent_nd.mnt != old_rootmnt)
-		path_release(&parent_nd);
+	path_release(&parent_nd);
 	mntput(old_rootmnt);
 	path_release(&nd);
 	return 0;
@@ -2000,6 +1957,54 @@
 
 #endif
 
+/*
+ * Absolutely minimal fake fs - only empty root directory and nothing else.
+ * In 2.5 we'll use ramfs or tmpfs, but for now it's all we need - just
+ * something to go with root vfsmount.
+ */
+static struct dentry *rootfs_lookup(struct inode *dir, struct dentry *dentry)
+{
+	d_add(dentry, NULL);
+	return NULL;
+}
+static struct file_operations rootfs_dir_operations = {
+	read:		generic_read_dir,
+	readdir:	dcache_readdir,
+};
+static struct inode_operations rootfs_dir_inode_operations = {
+	lookup:		rootfs_lookup,
+};
+static struct super_block *rootfs_read_super(struct super_block * sb, void * data, int silent)
+{
+	struct inode * inode;
+	struct dentry * root;
+	static struct super_operations s_ops = {};
+	sb->s_op = &s_ops;
+	inode = new_inode(sb);
+	if (!inode)
+		return NULL;
+	inode->i_mode = S_IFDIR|0555;
+	inode->i_uid = inode->i_gid = 0;
+	inode->i_op = &rootfs_dir_inode_operations;
+	inode->i_fop = &rootfs_dir_operations;
+	root = d_alloc_root(inode);
+	if (!root) {
+		iput(inode);
+		return NULL;
+	}
+	sb->s_root = root;
+	return sb;
+}
+static DECLARE_FSTYPE(root_fs_type, "rootfs", rootfs_read_super, FS_NOMOUNT);
+
+static void __init init_mount_tree(void)
+{
+	register_filesystem(&root_fs_type);
+	root_vfsmnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
+	if (IS_ERR(root_vfsmnt))
+		panic("can't allocate root vfsmount");
+}
+
 void __init mnt_init(unsigned long mempages)
 {
 	struct list_head *d;
@@ -2055,4 +2060,5 @@
 		d++;
 		i--;
 	} while (i);
+	init_mount_tree();
 }



  reply	other threads:[~2001-09-14 19:02 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-09-14 19:01 [PATCH] lazy umount (1/4) Alexander Viro
2001-09-14 19:02 ` Alexander Viro [this message]
2001-09-14 19:03   ` [PATCH] lazy umount (3/4) Alexander Viro
2001-09-14 19:03     ` [PATCH] lazy umount (4/4) Alexander Viro
2001-09-14 20:43 ` [PATCH] lazy umount (1/4) Linus Torvalds
2001-09-14 20:54   ` Alexander Viro
2001-09-15 12:32 ` jlnance
2001-09-15 20:51   ` Mike Fedyk
2001-09-17 10:06     ` Matthias Andree
2001-09-16 16:37 ` Alex Stewart
2001-09-17  6:57   ` Forced umount (was lazy umount) Ville Herva
2001-09-17  7:03     ` Aaron Lehmann
2001-09-17  8:38       ` Alexander Viro
2001-09-17 10:21         ` Matthias Andree
2001-09-17 10:47           ` Tigran Aivazian
2001-09-17 23:21             ` Alex Stewart
2001-09-17 23:23             ` Xavier Bestel
2001-09-18  1:04               ` Alex Stewart
2001-09-18 20:19                 ` Pavel Machek
2001-09-17  8:29   ` Xavier Bestel
2001-09-17  8:39     ` Alexander Viro
2001-09-17 10:04 ` [PATCH] lazy umount (1/4) Matthias Andree
2001-09-17 12:13   ` Alan Cox
2001-09-18  0:24     ` Alex Stewart
2001-09-18  0:39       ` Matthias Andree
2001-09-18  8:56         ` Alexander Viro
2001-09-18  9:08           ` Matthias Andree
2001-09-18 13:03             ` Alan Cox
2001-09-18  9:07     ` David Woodhouse
2001-09-17 14:43 ` David Woodhouse

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=Pine.GSO.4.21.0109141502090.11172-100000@weyl.math.psu.edu \
    --to=viro@math.psu.edu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).