patch-2.1.75 linux/fs/super.c
Next file: linux/fs/sysv/namei.c
Previous file: linux/fs/nls/nls_base.c
Back to the patch index
Back to the overall index
- Lines: 147
- Date:
Sun Dec 21 17:31:17 1997
- Orig file:
v2.1.74/linux/fs/super.c
- Orig date:
Tue Dec 2 09:49:40 1997
diff -u --recursive --new-file v2.1.74/linux/fs/super.c linux/fs/super.c
@@ -419,6 +419,11 @@
current->state = TASK_RUNNING;
}
+/*
+ * Note: check the dirty flag before waiting, so we don't
+ * hold up the sync while mounting a device. (The newly
+ * mounted device won't need syncing.)
+ */
void sync_supers(kdev_t dev)
{
struct super_block * sb;
@@ -428,6 +433,9 @@
continue;
if (dev && sb->s_dev != dev)
continue;
+ if (!sb->s_dirt)
+ continue;
+ /* N.B. Should lock the superblock while writing */
wait_on_super(sb);
if (!sb->s_dev || !sb->s_dirt)
continue;
@@ -444,13 +452,14 @@
if (!dev)
return NULL;
+restart:
s = 0+super_blocks;
while (s < NR_SUPER+super_blocks)
if (s->s_dev == dev) {
wait_on_super(s);
if (s->s_dev == dev)
return s;
- s = 0+super_blocks;
+ goto restart;
} else
s++;
return NULL;
@@ -494,33 +503,44 @@
struct file_system_type *type;
if (!dev)
- return NULL;
+ goto out_fail;
check_disk_change(dev);
s = get_super(dev);
if (s)
return s;
- if (!(type = get_fs_type(name))) {
+ type = get_fs_type(name);
+ if (!type) {
printk("VFS: on device %s: get_fs_type(%s) failed\n",
kdevname(dev), name);
- return NULL;
+ goto out_fail;
}
for (s = 0+super_blocks ;; s++) {
if (s >= NR_SUPER+super_blocks)
- return NULL;
- if (!(s->s_dev))
- break;
+ goto out_fail;
+ if (s->s_dev)
+ continue;
+ if (s->s_lock) {
+ printk("VFS: empty superblock %p locked!\n", s);
+ continue;
+ }
+ break;
}
s->s_dev = dev;
s->s_flags = flags;
- if (!type->read_super(s,data, silent)) {
- s->s_dev = 0;
- return NULL;
- }
- s->s_dev = dev;
- s->s_rd_only = 0;
s->s_dirt = 0;
+ /* N.B. Should lock superblock now ... */
+ if (!type->read_super(s,data, silent))
+ goto fail;
+ s->s_dev = dev; /* N.B. why do this again?? */
+ s->s_rd_only = 0;
s->s_type = type;
return s;
+
+ /* N.B. s_dev should be cleared in type->read_super */
+fail:
+ s->s_dev = 0;
+out_fail:
+ return NULL;
}
/*
@@ -1040,35 +1060,26 @@
int retval;
#ifdef CONFIG_ROOT_NFS
- if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR)
- if (nfs_root_init(nfs_root_name, nfs_root_addrs) < 0) {
- printk(KERN_ERR "Root-NFS: Unable to contact NFS "
- "server for root fs, using /dev/fd0 instead\n");
- ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
- }
if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
ROOT_DEV = 0;
if ((fs_type = get_fs_type("nfs"))) {
- sb = &super_blocks[0];
- while (sb->s_dev) sb++;
- sb->s_dev = get_unnamed_dev();
- sb->s_flags = root_mountflags & ~MS_RDONLY;
- if (nfs_root_mount(sb) >= 0) {
- sb->s_rd_only = 0;
- sb->s_dirt = 0;
- sb->s_type = fs_type;
- current->fs->root = dget(sb->s_root);
- current->fs->pwd = dget(sb->s_root);
- ROOT_DEV = sb->s_dev;
- printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
- vfsmnt = add_vfsmnt(ROOT_DEV, "/dev/root", "/");
- if (!vfsmnt)
- panic("VFS: add_vfsmnt failed for NFS root.\n");
- vfsmnt->mnt_sb = sb;
- vfsmnt->mnt_flags = sb->s_flags;
- return;
+ if ((vfsmnt = add_vfsmnt(ROOT_DEV, "/dev/root", "/"))) {
+ sb = vfsmnt->mnt_sb;
+ sb->s_dev = get_unnamed_dev();
+ sb->s_flags = root_mountflags & ~MS_RDONLY;
+ if (nfs_root_mount(sb) >= 0) {
+ sb->s_rd_only = 0;
+ sb->s_dirt = 0;
+ sb->s_type = fs_type;
+ current->fs->root = dget(sb->s_root);
+ current->fs->pwd = dget(sb->s_root);
+ ROOT_DEV = sb->s_dev;
+ printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
+ return;
+ }
+ sb->s_dev = 0;
+ put_unnamed_dev(sb->s_dev);
}
- sb->s_dev = 0;
}
if (!ROOT_DEV) {
printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov