]> git.hungrycats.org Git - linux/commitdiff
v2.5.0.6 -> v2.5.0.7
authorLinus Torvalds <torvalds@athlon.transmeta.com>
Tue, 5 Feb 2002 07:58:33 +0000 (23:58 -0800)
committerLinus Torvalds <torvalds@athlon.transmeta.com>
Tue, 5 Feb 2002 07:58:33 +0000 (23:58 -0800)
- Jens Axboe: more bio fixes/cleanups/breakage ;)
- Al Viro: superblock cleanups, boot/root mounting.

18 files changed:
Makefile
arch/i386/kernel/pci-pc.c
drivers/block/elevator.c
drivers/block/floppy.c
drivers/block/ll_rw_blk.c
drivers/char/pc_keyb.c
fs/bio.c
fs/namespace.c
fs/super.c
include/linux/bio.h
include/linux/blk.h
include/linux/device.h
include/linux/fs.h
include/linux/pci_ids.h
init/do_mounts.c [new file with mode: 0644]
init/main.c
kernel/device.c
mm/highmem.c

index 098baecc6dde3ed00aa01c93020fde68c6158d02..6f809123df89189418de0ba86922f322af177822 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 1
-EXTRAVERSION =-pre6
+EXTRAVERSION =-pre7
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -257,8 +257,8 @@ Version: dummy
 boot: vmlinux
        @$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C arch/$(ARCH)/boot
 
-vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
-       $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o \
+vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o init/do_mounts.o linuxsubdirs
+       $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \
                --start-group \
                $(CORE_FILES) \
                $(DRIVERS) \
@@ -335,6 +335,9 @@ init/version.o: init/version.c include/linux/compile.h include/config/MARKER
 init/main.o: init/main.c include/config/MARKER
        $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $<
 
+init/do_mounts.o: init/do_mounts.c include/config/MARKER
+       $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $<
+
 fs lib mm ipc kernel drivers net: dummy
        $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
 
index d22a0d0f1b8009dcbce8de3ba04a22383dfed207..bf3fad221750514d514aba4abd5da56b7ce6076a 100644 (file)
@@ -1114,17 +1114,26 @@ static void __devinit pci_fixup_piix4_acpi(struct pci_dev *d)
  * But it does seem to fix some unspecified problem
  * with 'movntq' copies on Athlons.
  *
- * VIA 8363 chipset:
- *  - bit 7 at offset 0x55: Debug (RW)
+ * VIA 8363,8622,8361 Northbridges:
+ *  - bits  5, 6, 7 at offset 0x55 need to be turned off
+ * VIA 8367 (KT266x) Northbridges:
+ *  - bits  5, 6, 7 at offset 0x95 need to be turned off
  */
 static void __init pci_fixup_via_athlon_bug(struct pci_dev *d)
 {
        u8 v;
-       pci_read_config_byte(d, 0x55, &v);
-       if (v & 0x80) {
+       int where = 0x55;
+
+       if (d->device == PCI_DEVICE_ID_VIA_8367_0) {
+               where = 0x95; /* the memory write queue timer register is 
+                                 different for the kt266x's: 0x95 not 0x55 */
+       }
+
+        pci_read_config_byte(d, where, &v);
+       if (v & 0xe0) {
                printk("Trying to stomp on Athlon bug...\n");
-               v &= 0x7f; /* clear bit 55.7 */
-               pci_write_config_byte(d, 0x55, v);
+               v &= 0x1f; /* clear bits 5, 6, 7 */
+               pci_write_config_byte(d, where, v);
        }
 }
 
@@ -1138,6 +1147,9 @@ struct pci_fixup pcibios_fixups[] = {
        { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_5598,          pci_fixup_latency },
        { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82371AB_3,  pci_fixup_piix4_acpi },
        { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_8363_0,       pci_fixup_via_athlon_bug },
+       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_8622,         pci_fixup_via_athlon_bug },
+       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_8361,         pci_fixup_via_athlon_bug },
+       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_8367_0,       pci_fixup_via_athlon_bug },
        { 0 }
 };
 
index a904e75416548de893a0cc1b48c7a2287abe61e9..c6a23542eb2581dde95cc881efe309125f83fa8f 100644 (file)
@@ -60,6 +60,12 @@ inline int bio_rq_in_between(struct bio *bio, struct request *rq,
 
        BUG_ON(next_rq->flags & REQ_STARTED);
 
+       /*
+        * not a sector based request
+        */
+       if (!(next_rq->flags & REQ_CMD))
+               return 0;
+
        /*
         * if the device is different (not a normal case) just check if
         * bio is after rq
@@ -95,6 +101,9 @@ inline int bio_rq_in_between(struct bio *bio, struct request *rq,
  */
 inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
 {
+       if (!(rq->flags & REQ_CMD))
+               return 0;
+
        /*
         * different data direction or already started, don't merge
         */
@@ -133,6 +142,8 @@ int elevator_linus_merge(request_queue_t *q, struct request **req,
                        break;
                if (__rq->flags & (REQ_BARRIER | REQ_STARTED))
                        break;
+               if (!(__rq->flags & REQ_CMD))
+                       continue;
 
                if (!*req && bio_rq_in_between(bio, __rq, &q->queue_head))
                        *req = __rq;
@@ -226,6 +237,9 @@ int elevator_noop_merge(request_queue_t *q, struct request **req,
                if (__rq->flags & (REQ_BARRIER | REQ_STARTED))
                        break;
 
+               if (!(__rq->flags & REQ_CMD))
+                       continue;
+
                if (!elv_rq_merge_ok(__rq, bio))
                        continue;
 
index 837587bc5b64371d20b4fc66d3cbe72a587cb14c..897f3c886b4505d2f5065af70a36bf41f6d6a701 100644 (file)
@@ -3914,7 +3914,7 @@ static void __init register_devfs_entries (int drive)
     {NULL, t360, t1200, t3in+5+8, t3in+5, t3in, t3in};
 
     base_minor = (drive < 4) ? drive : (124 + drive);
-    if (UDP->cmos <= NUMBER(default_drive_params)) {
+    if (UDP->cmos < NUMBER(default_drive_params)) {
        i = 0;
        do {
            char name[16];
index 1242a790b3fa83b88402ebe24ea7d14d29c59edb..6b92a30291c66f7c610afb1eda90fba13e26dbeb 100644 (file)
@@ -291,13 +291,13 @@ static int ll_10byte_cmd_build(request_queue_t *q, struct request *rq)
        if (!(rq->flags & REQ_CMD))
                return 0;
 
+       memset(rq->cmd, 0, sizeof(rq->cmd));
+
        if (rq_data_dir(rq) == READ)
                rq->cmd[0] = READ_10;
        else 
                rq->cmd[0] = WRITE_10;
 
-       rq->cmd[1] = 0;
-
        /*
         * fill in lba
         */
@@ -305,7 +305,6 @@ static int ll_10byte_cmd_build(request_queue_t *q, struct request *rq)
        rq->cmd[3] = (block >> 16) & 0xff;
        rq->cmd[4] = (block >>  8) & 0xff;
        rq->cmd[5] = block & 0xff;
-       rq->cmd[6] = 0;
 
        /*
         * and transfer length
@@ -347,7 +346,7 @@ int blk_rq_map_sg(request_queue_t *q, struct request *rq, struct scatterlist *sg
        unsigned long long lastend;
        struct bio_vec *bvec;
        struct bio *bio;
-       int nsegs, i, cluster, j;
+       int nsegs, i, cluster;
 
        nsegs = 0;
        bio = rq->bio;
@@ -357,9 +356,7 @@ int blk_rq_map_sg(request_queue_t *q, struct request *rq, struct scatterlist *sg
        /*
         * for each bio in rq
         */
-       j = 0;
        rq_for_each_bio(bio, rq) {
-               j++;
                /*
                 * for each segment in bio
                 */
@@ -386,7 +383,6 @@ int blk_rq_map_sg(request_queue_t *q, struct request *rq, struct scatterlist *sg
 new_segment:
                                if (nsegs > q->max_segments) {
                                        printk("map: %d >= %d\n", nsegs, q->max_segments);
-                                       printk("map %d, %d, bio_sectors %d, vcnt %d\n", i, j, bio_sectors(bio), bio->bi_vcnt);
                                        BUG();
                                }
 
@@ -411,7 +407,7 @@ new_segment:
 static inline int ll_new_segment(request_queue_t *q, struct request *req,
                                 struct bio *bio)
 {
-       if (req->nr_segments + bio->bi_vcnt < q->max_segments) {
+       if (req->nr_segments + bio->bi_vcnt <= q->max_segments) {
                req->nr_segments += bio->bi_vcnt;
                return 1;
        }
@@ -480,9 +476,17 @@ void blk_plug_device(request_queue_t *q)
  */
 static inline void __generic_unplug_device(request_queue_t *q)
 {
-       if (test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))
-               if (!elv_queue_empty(q))
-                       q->request_fn(q);
+       /*
+        * not plugged
+        */
+       if (!test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))
+               return;
+
+       /*
+        * was plugged, fire request_fn if queue has stuff to do
+        */
+       if (!elv_queue_empty(q))
+               q->request_fn(q);
 }
 
 /**
index 657e4488b1897943ec69e6267a46f0619da36ab8..2fc5e15be60bfbab9d1d283641ddd9a028f391bf 100644 (file)
@@ -1090,6 +1090,7 @@ static int open_aux(struct inode * inode, struct file * file)
                spin_unlock_irqrestore(&aux_count_lock, flags);
                return -EBUSY;
        }
+       spin_unlock_irqrestore(&aux_count_lock, flags);
        kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE);     /* Enable the
                                                           auxiliary port on
                                                           controller. */
@@ -1099,7 +1100,6 @@ static int open_aux(struct inode * inode, struct file * file)
        mdelay(2);                      /* Ensure we follow the kbc access delay rules.. */
 
        send_data(KBD_CMD_ENABLE);      /* try to workaround toshiba4030cdt problem */
-       spin_unlock_irqrestore(&aux_count_lock, flags);
        return 0;
 }
 
index 09080065709941ff15b5e5b59383544689c8ddc7..76539b360ad731400397bcd2151bcc08bce054c7 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -377,7 +377,7 @@ struct bio *bio_copy(struct bio *bio, int gfp_mask, int copy)
                /*
                 * iterate iovec list and alloc pages + copy data
                 */
-               bio_for_each_segment(bv, bio, i) {
+               __bio_for_each_segment(bv, bio, i, 0) {
                        struct bio_vec *bbv = &b->bi_io_vec[i];
                        char *vfrom, *vto;
 
@@ -392,8 +392,7 @@ struct bio *bio_copy(struct bio *bio, int gfp_mask, int copy)
                                vfrom = kmap(bv->bv_page);
                                vto = kmap(bbv->bv_page);
                        } else {
-                               __save_flags(flags);
-                               __cli();
+                               local_irq_save(flags);
                                vfrom = kmap_atomic(bv->bv_page, KM_BIO_IRQ);
                                vto = kmap_atomic(bbv->bv_page, KM_BIO_IRQ);
                        }
@@ -405,7 +404,7 @@ struct bio *bio_copy(struct bio *bio, int gfp_mask, int copy)
                        } else {
                                kunmap_atomic(vto, KM_BIO_IRQ);
                                kunmap_atomic(vfrom, KM_BIO_IRQ);
-                               __restore_flags(flags);
+                               local_irq_restore(flags);
                        }
 
 fill_in:
@@ -424,10 +423,8 @@ fill_in:
        return b;
 
 oom:
-       while (i >= 0) {
+       while (--i >= 0)
                __free_page(b->bi_io_vec[i].bv_page);
-               i--;
-       }
 
        bio_pool_put(b);
        return NULL;
@@ -613,6 +610,11 @@ out:
        if (err)
                kio->errno = err;
 
+       /*
+        * final atomic_dec of io_count to match our initial setting of 1.
+        * I/O may or may not have completed at this point, final completion
+        * handler is only run on last decrement.
+        */
        end_kio_request(kio, !err);
 }
 
index 327e314a2575316c2b73a0927d0e162bb123b8fb..d790be367296192c5cd72076b5f60bd029a553ce 100644 (file)
 #include <linux/quotaops.h>
 #include <linux/acct.h>
 #include <linux/module.h>
-#include <linux/devfs_fs_kernel.h>
+#include <linux/seq_file.h>
 
 #include <asm/uaccess.h>
 
-#include <linux/seq_file.h>
-
 struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
 int do_remount_sb(struct super_block *sb, int flags, void * data);
 void kill_super(struct super_block *sb);
@@ -31,9 +29,7 @@ static kmem_cache_t *mnt_cache;
 
 static LIST_HEAD(vfsmntlist);
 static DECLARE_MUTEX(mount_sem);
-
-/* Will be static */
-struct vfsmount *root_vfsmnt;
+static struct vfsmount *root_vfsmnt;
 
 static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
 {
@@ -462,8 +458,7 @@ Enomem:
        return NULL;
 }
 
-/* Will become static */
-int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
+static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
 {
        int err;
        if (mnt->mnt_sb->s_flags & MS_NOUSER)
@@ -928,6 +923,44 @@ out3:
  * 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 inode_operations rootfs_dir_inode_operations;
+static struct file_operations rootfs_dir_operations;
+static int rootfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+       struct inode * inode = new_inode(dir->i_sb);
+       int error = -ENOSPC;
+       if (inode) {
+               inode->i_mode = S_IFDIR|mode;
+               inode->i_uid = current->fsuid;
+               inode->i_gid = current->fsgid;
+               inode->i_op = &rootfs_dir_inode_operations;
+               inode->i_fop = &rootfs_dir_operations;
+               d_instantiate(dentry, inode);
+               dget(dentry);
+               error = 0;
+       }
+       return error;
+}
+static int rootfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
+{
+       struct inode * inode = new_inode(dir->i_sb);
+       int error = -ENOSPC;
+       if (inode) {
+               inode->i_uid = current->fsuid;
+               inode->i_gid = current->fsgid;
+               init_special_inode(inode, mode, dev);
+               d_instantiate(dentry, inode);
+               dget(dentry);
+               error = 0;
+       }
+       return error;
+}
+static int rootfs_unlink(struct inode * dir, struct dentry *dentry)
+{
+       dentry->d_inode->i_nlink--;
+       dput(dentry);
+       return 0;
+}
 static struct dentry *rootfs_lookup(struct inode *dir, struct dentry *dentry)
 {
        d_add(dentry, NULL);
@@ -939,6 +972,9 @@ static struct file_operations rootfs_dir_operations = {
 };
 static struct inode_operations rootfs_dir_inode_operations = {
        lookup:         rootfs_lookup,
+       mkdir:          rootfs_mkdir,
+       mknod:          rootfs_mknod,
+       unlink:         rootfs_unlink,
 };
 static struct super_block *rootfs_read_super(struct super_block * sb, void * data, int silent)
 {
@@ -1030,93 +1066,3 @@ void __init mnt_init(unsigned long mempages)
        } while (i);
        init_mount_tree();
 }
-
-#ifdef CONFIG_BLK_DEV_INITRD
-
-int __init change_root(kdev_t new_root_dev,const char *put_old)
-{
-       struct vfsmount *old_rootmnt;
-       struct nameidata devfs_nd, nd;
-       struct nameidata parent_nd;
-       char *new_devname = kmalloc(strlen("/dev/root.old")+1, GFP_KERNEL);
-       int error = 0;
-
-       if (new_devname)
-               strcpy(new_devname, "/dev/root.old");
-
-       read_lock(&current->fs->lock);
-       old_rootmnt = mntget(current->fs->rootmnt);
-       read_unlock(&current->fs->lock);
-       /*  First unmount devfs if mounted  */
-       if (path_init("/dev", LOOKUP_FOLLOW|LOOKUP_POSITIVE, &devfs_nd))
-               error = path_walk("/dev", &devfs_nd);
-       if (!error) {
-               if (devfs_nd.mnt->mnt_sb->s_magic == DEVFS_SUPER_MAGIC &&
-                   devfs_nd.dentry == devfs_nd.mnt->mnt_root) {
-                       do_umount(devfs_nd.mnt, 0);
-               }
-               path_release(&devfs_nd);
-       }
-       set_fs_pwd(current->fs, root_vfsmnt, root_vfsmnt->mnt_root);
-       set_fs_root(current->fs, root_vfsmnt, root_vfsmnt->mnt_root);
-       spin_lock(&dcache_lock);
-       detach_mnt(old_rootmnt, &parent_nd);
-       spin_unlock(&dcache_lock);
-       ROOT_DEV = new_root_dev;
-       mount_root();
-#if 1
-       shrink_dcache();
-       printk("change_root: old root has d_count=%d\n", 
-              atomic_read(&old_rootmnt->mnt_root->d_count));
-#endif
-       mount_devfs_fs ();
-       /*
-        * Get the new mount directory
-        */
-       error = 0;
-       if (path_init(put_old, LOOKUP_FOLLOW|LOOKUP_POSITIVE|LOOKUP_DIRECTORY, &nd))
-               error = path_walk(put_old, &nd);
-       if (error) {
-               int blivet;
-               struct block_device *ramdisk = old_rootmnt->mnt_sb->s_bdev;
-
-               atomic_inc(&ramdisk->bd_count);
-               blivet = blkdev_get(ramdisk, FMODE_READ, 0, BDEV_FS);
-               printk(KERN_NOTICE "Trying to unmount old root ... ");
-               if (!blivet) {
-                       spin_lock(&dcache_lock);
-                       list_del_init(&old_rootmnt->mnt_list);
-                       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) {
-                       printk(KERN_ERR "error %d\n", blivet);
-               } else {
-                       printk("okay\n");
-                       error = 0;
-               }                       
-               kfree(new_devname);
-               return error;
-       }
-
-       spin_lock(&dcache_lock);
-       attach_mnt(old_rootmnt, &nd);
-       if (new_devname) {
-               if (old_rootmnt->mnt_devname)
-                       kfree(old_rootmnt->mnt_devname);
-               old_rootmnt->mnt_devname = new_devname;
-       }
-       spin_unlock(&dcache_lock);
-
-       /* put the old stuff */
-       path_release(&parent_nd);
-       mntput(old_rootmnt);
-       path_release(&nd);
-       return 0;
-}
-
-#endif
index 6e486444c64319699fcf9461bf8207623ffa9536..368a1087e4eb0aa12f84cb35bf8b5616a5c631de 100644 (file)
  */
 
 #include <linux/config.h>
-#include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/locks.h>
 #include <linux/smp_lock.h>
 #include <linux/devfs_fs_kernel.h>
-#include <linux/fd.h>
-#include <linux/init.h>
 #include <linux/major.h>
-#include <linux/quotaops.h>
 #include <linux/acct.h>
 
 #include <asm/uaccess.h>
 
-#include <linux/nfs_fs.h>
-#include <linux/nfs_fs_sb.h>
-#include <linux/nfs_mount.h>
-
 #include <linux/kmod.h>
 #define __NO_VERSION__
 #include <linux/module.h>
 
-extern void wait_for_keypress(void);
-
-extern int root_mountflags;
-
 int do_remount_sb(struct super_block *sb, int flags, void * data);
 
-/* this is initialized in init/main.c */
-kdev_t ROOT_DEV;
-
 LIST_HEAD(super_blocks);
 spinlock_t sb_lock = SPIN_LOCK_UNLOCKED;
 
@@ -429,10 +414,6 @@ struct vfsmount *alloc_vfsmnt(void);
 void free_vfsmnt(struct vfsmount *mnt);
 void set_devname(struct vfsmount *mnt, const char *name);
 
-/* Will go away */
-extern struct vfsmount *root_vfsmnt;
-extern int graft_tree(struct vfsmount *mnt, struct nameidata *nd);
-
 static inline struct super_block * find_super(kdev_t dev)
 {
        struct list_head *p;
@@ -549,37 +530,6 @@ out:
        return err;
 }
 
-static struct super_block * read_super(kdev_t dev, struct block_device *bdev,
-                                      struct file_system_type *type, int flags,
-                                      void *data)
-{
-       struct super_block * s;
-       s = alloc_super();
-       if (!s)
-               goto out;
-       s->s_dev = dev;
-       s->s_bdev = bdev;
-       s->s_flags = flags;
-       spin_lock(&sb_lock);
-       insert_super(s, type);
-       lock_super(s);
-       if (!type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
-               goto out_fail;
-       s->s_flags |= MS_ACTIVE;
-       unlock_super(s);
-       /* tell bdcache that we are going to keep this one */
-       if (bdev)
-               atomic_inc(&bdev->bd_count);
-out:
-       return s;
-
-out_fail:
-       unlock_super(s);
-       deactivate_super(s);
-       remove_super(s);
-       return NULL;
-}
-
 /*
  * Unnamed block devices are dummy devices used by virtual
  * filesystems which don't use real block-devices.  -- jrs
@@ -708,17 +658,30 @@ out:
 static struct super_block *get_sb_nodev(struct file_system_type *fs_type,
        int flags, void * data)
 {
-       kdev_t dev;
-       int error = -EMFILE;
-       dev = get_unnamed_dev();
-       if (dev) {
-               struct super_block * sb;
-               error = -EINVAL;
-               sb = read_super(dev, NULL, fs_type, flags, data);
-               if (sb)
-                       return sb;
+       struct super_block *s = alloc_super();
+
+       if (!s)
+               return ERR_PTR(-ENOMEM);
+       s->s_dev = get_unnamed_dev();
+       if (!s->s_dev) {
+               destroy_super(s);
+               return ERR_PTR(-EMFILE);
        }
-       return ERR_PTR(error);
+       s->s_flags = flags;
+       spin_lock(&sb_lock);
+       insert_super(s, fs_type);
+       lock_super(s);
+       if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
+               goto out_fail;
+       s->s_flags |= MS_ACTIVE;
+       unlock_super(s);
+       return s;
+
+out_fail:
+       unlock_super(s);
+       deactivate_super(s);
+       remove_super(s);
+       return ERR_PTR(-EINVAL);
 }
 
 static struct super_block *get_sb_single(struct file_system_type *fs_type,
@@ -743,13 +706,12 @@ retry:
                do_remount_sb(old, flags, data);
                return old;
        } else {
-               kdev_t dev = get_unnamed_dev();
-               if (!dev) {
+               s->s_dev = get_unnamed_dev();
+               if (!s->s_dev) {
                        spin_unlock(&sb_lock);
                        destroy_super(s);
                        return ERR_PTR(-EMFILE);
                }
-               s->s_dev = dev;
                s->s_flags = flags;
                insert_super(s, fs_type);
                lock_super(s);
@@ -899,212 +861,3 @@ struct vfsmount *kern_mount(struct file_system_type *type)
 {
        return do_kern_mount((char *)type->name, 0, (char *)type->name, NULL);
 }
-
-static char * __initdata root_mount_data;
-static int __init root_data_setup(char *str)
-{
-       root_mount_data = str;
-       return 1;
-}
-
-static char * __initdata root_fs_names;
-static int __init fs_names_setup(char *str)
-{
-       root_fs_names = str;
-       return 1;
-}
-
-__setup("rootflags=", root_data_setup);
-__setup("rootfstype=", fs_names_setup);
-
-static void __init get_fs_names(char *page)
-{
-       char *s = page;
-
-       if (root_fs_names) {
-               strcpy(page, root_fs_names);
-               while (*s++) {
-                       if (s[-1] == ',')
-                               s[-1] = '\0';
-               }
-       } else {
-               int len = get_filesystem_list(page);
-               char *p, *next;
-
-               page[len] = '\0';
-               for (p = page-1; p; p = next) {
-                       next = strchr(++p, '\n');
-                       if (*p++ != '\t')
-                               continue;
-                       while ((*s++ = *p++) != '\n')
-                               ;
-                       s[-1] = '\0';
-               }
-       }
-       *s = '\0';
-}
-
-void __init mount_root(void)
-{
-       struct nameidata root_nd;
-       struct super_block * sb;
-       struct vfsmount *vfsmnt;
-       struct block_device *bdev = NULL;
-       mode_t mode;
-       int retval;
-       void *handle;
-       char path[64];
-       char *name = "/dev/root";
-       char *fs_names, *p;
-#ifdef CONFIG_ROOT_NFS
-       void *data;
-#endif
-       root_mountflags |= MS_VERBOSE;
-
-#ifdef CONFIG_ROOT_NFS
-       if (MAJOR(ROOT_DEV) != UNNAMED_MAJOR)
-               goto skip_nfs;
-       data = nfs_root_data();
-       if (!data)
-               goto no_nfs;
-       vfsmnt = do_kern_mount("nfs", root_mountflags, "/dev/root", data);
-       if (!IS_ERR(vfsmnt)) {
-               printk ("VFS: Mounted root (%s filesystem).\n", "nfs");
-               ROOT_DEV = vfsmnt->mnt_sb->s_dev;
-               goto attach_it;
-       }
-no_nfs:
-       printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
-       ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
-skip_nfs:
-#endif
-
-#ifdef CONFIG_BLK_DEV_FD
-       if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
-#ifdef CONFIG_BLK_DEV_RAM
-               extern int rd_doload;
-               extern void rd_load_secondary(void);
-#endif
-               floppy_eject();
-#ifndef CONFIG_BLK_DEV_RAM
-               printk(KERN_NOTICE "(Warning, this kernel has no ramdisk support)\n");
-#else
-               /* rd_doload is 2 for a dual initrd/ramload setup */
-               if(rd_doload==2)
-                       rd_load_secondary();
-               else
-#endif
-               {
-                       printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
-                       wait_for_keypress();
-               }
-       }
-#endif
-
-       fs_names = __getname();
-       get_fs_names(fs_names);
-
-       devfs_make_root (root_device_name);
-       handle = devfs_find_handle (NULL, ROOT_DEVICE_NAME,
-                                   MAJOR (ROOT_DEV), MINOR (ROOT_DEV),
-                                   DEVFS_SPECIAL_BLK, 1);
-       if (handle) {
-               int n;
-               unsigned major, minor;
-
-               devfs_get_maj_min (handle, &major, &minor);
-               ROOT_DEV = MKDEV (major, minor);
-               if (!ROOT_DEV)
-                       panic("I have no root and I want to scream");
-               n = devfs_generate_path (handle, path + 5, sizeof (path) - 5);
-               if (n >= 0) {
-                       name = path + n;
-                       devfs_mk_symlink (NULL, "root", DEVFS_FL_DEFAULT,
-                                         name + 5, NULL, NULL);
-                       memcpy (name, "/dev/", 5);
-               }
-       }
-
-retry:
-       bdev = bdget(kdev_t_to_nr(ROOT_DEV));
-       if (!bdev)
-               panic(__FUNCTION__ ": unable to allocate root device");
-       bdev->bd_op = devfs_get_ops (handle);
-       mode = FMODE_READ;
-       if (!(root_mountflags & MS_RDONLY))
-               mode |= FMODE_WRITE;
-       retval = blkdev_get(bdev, mode, 0, BDEV_FS);
-       if (retval == -EROFS) {
-               root_mountflags |= MS_RDONLY;
-               goto retry;
-       }
-       if (retval) {
-               /*
-                * Allow the user to distinguish between failed open
-                * and bad superblock on root device.
-                */
-Eio:
-               printk ("VFS: Cannot open root device \"%s\" or %s\n",
-                       root_device_name, kdevname (ROOT_DEV));
-               printk ("Please append a correct \"root=\" boot option\n");
-               panic("VFS: Unable to mount root fs on %s",
-                       kdevname(ROOT_DEV));
-       }
-
-       check_disk_change(ROOT_DEV);
-       sb = get_super(ROOT_DEV);
-       if (sb) {
-               /* FIXME */
-               p = (char *)sb->s_type->name;
-               atomic_inc(&sb->s_active);
-               up_read(&sb->s_umount);
-               down_write(&sb->s_umount);
-               goto mount_it;
-       }
-
-       for (p = fs_names; *p; p += strlen(p)+1) {
-               struct file_system_type * fs_type = get_fs_type(p);
-               if (!fs_type)
-                       continue;
-               atomic_inc(&bdev->bd_count);
-               retval = blkdev_get(bdev, mode, 0, BDEV_FS);
-               if (retval)
-                       goto Eio;
-               sb = read_super(ROOT_DEV, bdev, fs_type,
-                               root_mountflags, root_mount_data);
-               put_filesystem(fs_type);
-               if (sb) {
-                       blkdev_put(bdev, BDEV_FS);
-                       goto mount_it;
-               }
-       }
-       panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
-
-mount_it:
-       /* FIXME */
-       up_write(&sb->s_umount);
-       printk ("VFS: Mounted root (%s filesystem)%s.\n", p,
-               (sb->s_flags & MS_RDONLY) ? " readonly" : "");
-       putname(fs_names);
-       vfsmnt = alloc_vfsmnt();
-       if (!vfsmnt)
-               panic("VFS: alloc_vfsmnt failed for root fs");
-
-       set_devname(vfsmnt, name);
-       vfsmnt->mnt_sb = sb;
-       vfsmnt->mnt_root = dget(sb->s_root);
-       bdput(bdev); /* sb holds a reference */
-
-
-#ifdef CONFIG_ROOT_NFS
-attach_it:
-#endif
-       root_nd.mnt = root_vfsmnt;
-       root_nd.dentry = root_vfsmnt->mnt_sb->s_root;
-       graft_tree(vfsmnt, &root_nd);
-
-       set_fs_root(current->fs, vfsmnt, vfsmnt->mnt_root);
-       set_fs_pwd(current->fs, vfsmnt, vfsmnt->mnt_root);
-
-       mntput(vfsmnt);
-}
index 550679134fd81312ea412627d9a9d580045e0796..85e518c1c1e6e6512e4410c4d14b942ed21446c2 100644 (file)
@@ -100,7 +100,6 @@ struct bio {
 #define bio_iovec_idx(bio, idx)        (&((bio)->bi_io_vec[(idx)]))
 #define bio_iovec(bio)         bio_iovec_idx((bio), (bio)->bi_idx)
 #define bio_page(bio)          bio_iovec((bio))->bv_page
-#define __bio_offset(bio, idx) bio_iovec_idx((bio), (idx))->bv_offset
 #define bio_offset(bio)                bio_iovec((bio))->bv_offset
 #define bio_sectors(bio)       ((bio)->bi_size >> 9)
 #define bio_data(bio)          (page_address(bio_page((bio))) + bio_offset((bio)))
@@ -136,11 +135,18 @@ struct bio {
 
 #define bio_io_error(bio) bio_endio((bio), 0, bio_sectors((bio)))
 
-#define bio_for_each_segment(bvl, bio, i)                              \
-       for (bvl = bio_iovec((bio)), i = (bio)->bi_idx;                 \
+/*
+ * drivers should not use the __ version unless they _really_ want to
+ * run through the entire bio and not just pending pieces
+ */
+#define __bio_for_each_segment(bvl, bio, i, start_idx)                 \
+       for (bvl = bio_iovec_idx((bio), (start_idx)), i = (start_idx);  \
             i < (bio)->bi_vcnt;                                        \
             bvl++, i++)
 
+#define bio_for_each_segment(bvl, bio, i)                              \
+       __bio_for_each_segment(bvl, bio, i, (bio)->bi_idx)
+
 /*
  * get a reference to a bio, so it won't disappear. the intended use is
  * something like:
index 29db6a337ef54b61cfc774311df80702dfbcb4d3..e54f03ebbf0283ab7c9a0df2374314fa1ecf658c 100644 (file)
@@ -22,6 +22,9 @@ extern void add_blkdev_randomness(int major);
 extern unsigned long initrd_start,initrd_end;
 extern int mount_initrd; /* zero if initrd should not be mounted */
 extern int initrd_below_start_ok; /* 1 if it is not an error if initrd_start < memory_start */
+extern int rd_doload;          /* 1 = load ramdisk, 0 = don't load */
+extern int rd_prompt;          /* 1 = prompt for ramdisk, 0 = don't prompt */
+extern int rd_image_start;     /* starting block # of image */
 void initrd_init(void);
 
 #endif
index df9e1724d3e78aa4d7ad0d804fe94407ccaca41f..32a2fed4dddddcf56e9b769e682275dce81d873e 100644 (file)
@@ -113,10 +113,6 @@ struct iobus_driver {
        int     (*add_device)   (struct iobus*, char*);
 };
 
-extern int iobus_register_driver(struct iobus_driver * driver);
-extern void iobus_unregister_driver(struct iobus_driver * driver);
-extern struct iobus_driver * iobus_find_driver(char *name);
-
 struct iobus {
        spinlock_t      lock;           /* lock for bus */
        atomic_t        refcount;
index 2bc05a6b28b5073b8b1a8a281f7c677bf782086c..7f52b46d619f85d0135315ecd8a7c098da2b3f6e 100644 (file)
@@ -1447,11 +1447,9 @@ extern char root_device_name[];
 
 
 extern void show_buffers(void);
-extern void mount_root(void);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 extern unsigned int real_root_dev;
-extern int change_root(kdev_t, const char *);
 #endif
 
 extern ssize_t char_read(struct file *, char *, size_t, loff_t *);
index a8753bec73cbb2b97e2e93656d7aeff8da8b0a9e..d73d486aba93f292a8e28f34dcc12618292d69e4 100644 (file)
 #define PCI_DEVICE_ID_TTI_HPT366       0x0004
 
 #define PCI_VENDOR_ID_VIA              0x1106
-#define PCI_DEVICE_ID_VIA_8363_0       0x0305
+#define PCI_DEVICE_ID_VIA_8363_0       0x0305 
 #define PCI_DEVICE_ID_VIA_8371_0       0x0391
 #define PCI_DEVICE_ID_VIA_8501_0       0x0501
 #define PCI_DEVICE_ID_VIA_82C505       0x0505
 #define PCI_DEVICE_ID_VIA_8233_7       0x3065
 #define PCI_DEVICE_ID_VIA_82C686_6     0x3068
 #define PCI_DEVICE_ID_VIA_8233_0       0x3074
+#define PCI_DEVICE_ID_VIA_8622          0x3102 
 #define PCI_DEVICE_ID_VIA_8233C_0      0x3109
+#define PCI_DEVICE_ID_VIA_8361          0x3112 
 #define PCI_DEVICE_ID_VIA_8633_0       0x3091
-#define PCI_DEVICE_ID_VIA_8367_0       0x3099
+#define PCI_DEVICE_ID_VIA_8367_0       0x3099 
 #define PCI_DEVICE_ID_VIA_86C100A      0x6100
 #define PCI_DEVICE_ID_VIA_8231         0x8231
 #define PCI_DEVICE_ID_VIA_8231_4       0x8235
diff --git a/init/do_mounts.c b/init/do_mounts.c
new file mode 100644 (file)
index 0000000..8d16e3f
--- /dev/null
@@ -0,0 +1,558 @@
+#define __KERNEL_SYSCALLS__
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/unistd.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/smp_lock.h>
+#include <linux/blk.h>
+#include <linux/tty.h>
+
+#include <linux/nfs_fs.h>
+#include <linux/nfs_fs_sb.h>
+#include <linux/nfs_mount.h>
+
+#include <asm/uaccess.h>
+
+/* syscalls missing from unistd.h */
+static inline _syscall2(int,mkdir,char *,name,int,mode);
+static inline _syscall1(int,chdir,char *,name);
+static inline _syscall1(int,chroot,char *,name);
+static inline _syscall1(int,unlink,char *,name);
+static inline _syscall3(int,mknod,char *,name,int,mode,dev_t,dev);
+static inline _syscall5(int,mount,char *,dev,char *,dir,char *,type,
+                       unsigned long,flags,void *,data);
+static inline _syscall2(int,umount,char *,name,int,flags);
+
+extern void rd_load(void);
+extern void initrd_load(void);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+unsigned int real_root_dev;    /* do_proc_dointvec cannot handle kdev_t */
+#endif
+int root_mountflags = MS_RDONLY;
+char root_device_name[64];
+
+/* this is initialized in init/main.c */
+kdev_t ROOT_DEV;
+
+static int __init readonly(char *str)
+{
+       if (*str)
+               return 0;
+       root_mountflags |= MS_RDONLY;
+       return 1;
+}
+
+static int __init readwrite(char *str)
+{
+       if (*str)
+               return 0;
+       root_mountflags &= ~MS_RDONLY;
+       return 1;
+}
+
+__setup("ro", readonly);
+__setup("rw", readwrite);
+
+static struct dev_name_struct {
+       const char *name;
+       const int num;
+} root_dev_names[] __initdata = {
+       { "nfs",     0x00ff },
+       { "hda",     0x0300 },
+       { "hdb",     0x0340 },
+       { "loop",    0x0700 },
+       { "hdc",     0x1600 },
+       { "hdd",     0x1640 },
+       { "hde",     0x2100 },
+       { "hdf",     0x2140 },
+       { "hdg",     0x2200 },
+       { "hdh",     0x2240 },
+       { "hdi",     0x3800 },
+       { "hdj",     0x3840 },
+       { "hdk",     0x3900 },
+       { "hdl",     0x3940 },
+       { "hdm",     0x5800 },
+       { "hdn",     0x5840 },
+       { "hdo",     0x5900 },
+       { "hdp",     0x5940 },
+       { "hdq",     0x5A00 },
+       { "hdr",     0x5A40 },
+       { "hds",     0x5B00 },
+       { "hdt",     0x5B40 },
+       { "sda",     0x0800 },
+       { "sdb",     0x0810 },
+       { "sdc",     0x0820 },
+       { "sdd",     0x0830 },
+       { "sde",     0x0840 },
+       { "sdf",     0x0850 },
+       { "sdg",     0x0860 },
+       { "sdh",     0x0870 },
+       { "sdi",     0x0880 },
+       { "sdj",     0x0890 },
+       { "sdk",     0x08a0 },
+       { "sdl",     0x08b0 },
+       { "sdm",     0x08c0 },
+       { "sdn",     0x08d0 },
+       { "sdo",     0x08e0 },
+       { "sdp",     0x08f0 },
+       { "ada",     0x1c00 },
+       { "adb",     0x1c10 },
+       { "adc",     0x1c20 },
+       { "add",     0x1c30 },
+       { "ade",     0x1c40 },
+       { "fd",      0x0200 },
+       { "md",      0x0900 },       
+       { "xda",     0x0d00 },
+       { "xdb",     0x0d40 },
+       { "ram",     0x0100 },
+       { "scd",     0x0b00 },
+       { "mcd",     0x1700 },
+       { "cdu535",  0x1800 },
+       { "sonycd",  0x1800 },
+       { "aztcd",   0x1d00 },
+       { "cm206cd", 0x2000 },
+       { "gscd",    0x1000 },
+       { "sbpcd",   0x1900 },
+       { "eda",     0x2400 },
+       { "edb",     0x2440 },
+       { "pda",        0x2d00 },
+       { "pdb",        0x2d10 },
+       { "pdc",        0x2d20 },
+       { "pdd",        0x2d30 },
+       { "pcd",        0x2e00 },
+       { "pf",         0x2f00 },
+       { "apblock", APBLOCK_MAJOR << 8},
+       { "ddv", DDV_MAJOR << 8},
+       { "jsfd",    JSFD_MAJOR << 8},
+#if defined(CONFIG_ARCH_S390)
+       { "dasda", (DASD_MAJOR << MINORBITS) },
+       { "dasdb", (DASD_MAJOR << MINORBITS) + (1 << 2) },
+       { "dasdc", (DASD_MAJOR << MINORBITS) + (2 << 2) },
+       { "dasdd", (DASD_MAJOR << MINORBITS) + (3 << 2) },
+       { "dasde", (DASD_MAJOR << MINORBITS) + (4 << 2) },
+       { "dasdf", (DASD_MAJOR << MINORBITS) + (5 << 2) },
+       { "dasdg", (DASD_MAJOR << MINORBITS) + (6 << 2) },
+       { "dasdh", (DASD_MAJOR << MINORBITS) + (7 << 2) },
+#endif
+#if defined(CONFIG_BLK_CPQ_DA) || defined(CONFIG_BLK_CPQ_DA_MODULE)
+       { "ida/c0d0p",0x4800 },
+       { "ida/c0d1p",0x4810 },
+       { "ida/c0d2p",0x4820 },
+       { "ida/c0d3p",0x4830 },
+       { "ida/c0d4p",0x4840 },
+       { "ida/c0d5p",0x4850 },
+       { "ida/c0d6p",0x4860 },
+       { "ida/c0d7p",0x4870 },
+       { "ida/c0d8p",0x4880 },
+       { "ida/c0d9p",0x4890 },
+       { "ida/c0d10p",0x48A0 },
+       { "ida/c0d11p",0x48B0 },
+       { "ida/c0d12p",0x48C0 },
+       { "ida/c0d13p",0x48D0 },
+       { "ida/c0d14p",0x48E0 },
+       { "ida/c0d15p",0x48F0 },
+#endif
+#if defined(CONFIG_BLK_CPQ_CISS_DA) || defined(CONFIG_BLK_CPQ_CISS_DA_MODULE)
+       { "cciss/c0d0p",0x6800 },
+       { "cciss/c0d1p",0x6810 },
+       { "cciss/c0d2p",0x6820 },
+       { "cciss/c0d3p",0x6830 },
+       { "cciss/c0d4p",0x6840 },
+       { "cciss/c0d5p",0x6850 },
+       { "cciss/c0d6p",0x6860 },
+       { "cciss/c0d7p",0x6870 },
+       { "cciss/c0d8p",0x6880 },
+       { "cciss/c0d9p",0x6890 },
+       { "cciss/c0d10p",0x68A0 },
+       { "cciss/c0d11p",0x68B0 },
+       { "cciss/c0d12p",0x68C0 },
+       { "cciss/c0d13p",0x68D0 },
+       { "cciss/c0d14p",0x68E0 },
+       { "cciss/c0d15p",0x68F0 },
+#endif
+       { "nftla", 0x5d00 },
+       { "nftlb", 0x5d10 },
+       { "nftlc", 0x5d20 },
+       { "nftld", 0x5d30 },
+       { "ftla", 0x2c00 },
+       { "ftlb", 0x2c08 },
+       { "ftlc", 0x2c10 },
+       { "ftld", 0x2c18 },
+       { "mtdblock", 0x1f00 },
+       { NULL, 0 }
+};
+
+kdev_t __init name_to_kdev_t(char *line)
+{
+       int base = 0;
+
+       if (strncmp(line,"/dev/",5) == 0) {
+               struct dev_name_struct *dev = root_dev_names;
+               line += 5;
+               do {
+                       int len = strlen(dev->name);
+                       if (strncmp(line,dev->name,len) == 0) {
+                               line += len;
+                               base = dev->num;
+                               break;
+                       }
+                       dev++;
+               } while (dev->name);
+       }
+       return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
+}
+
+static int __init root_dev_setup(char *line)
+{
+       int i;
+       char ch;
+
+       ROOT_DEV = name_to_kdev_t(line);
+       memset (root_device_name, 0, sizeof root_device_name);
+       if (strncmp (line, "/dev/", 5) == 0) line += 5;
+       for (i = 0; i < sizeof root_device_name - 1; ++i)
+       {
+           ch = line[i];
+           if ( isspace (ch) || (ch == ',') || (ch == '\0') ) break;
+           root_device_name[i] = ch;
+       }
+       return 1;
+}
+
+__setup("root=", root_dev_setup);
+
+static char * __initdata root_mount_data;
+static int __init root_data_setup(char *str)
+{
+       root_mount_data = str;
+       return 1;
+}
+
+static char * __initdata root_fs_names;
+static int __init fs_names_setup(char *str)
+{
+       root_fs_names = str;
+       return 1;
+}
+
+__setup("rootflags=", root_data_setup);
+__setup("rootfstype=", fs_names_setup);
+
+static void __init get_fs_names(char *page)
+{
+       char *s = page;
+
+       if (root_fs_names) {
+               strcpy(page, root_fs_names);
+               while (*s++) {
+                       if (s[-1] == ',')
+                               s[-1] = '\0';
+               }
+       } else {
+               int len = get_filesystem_list(page);
+               char *p, *next;
+
+               page[len] = '\0';
+               for (p = page-1; p; p = next) {
+                       next = strchr(++p, '\n');
+                       if (*p++ != '\t')
+                               continue;
+                       while ((*s++ = *p++) != '\n')
+                               ;
+                       s[-1] = '\0';
+               }
+       }
+       *s = '\0';
+}
+
+static void __init mount_root(void)
+{
+       void *handle;
+       char path[64];
+       char *name = "/dev/root";
+       char *fs_names, *p;
+       int err;
+       int do_devfs = 0;
+#ifdef CONFIG_ROOT_NFS
+       void *data;
+#endif
+       root_mountflags |= MS_VERBOSE;
+
+       fs_names = __getname();
+       get_fs_names(fs_names);
+
+#ifdef CONFIG_ROOT_NFS
+       if (MAJOR(ROOT_DEV) != UNNAMED_MAJOR)
+               goto skip_nfs;
+       data = nfs_root_data();
+       if (!data)
+               goto no_nfs;
+       err = mount("/dev/root", "/root", "nfs", root_mountflags, data);
+       if (!err)
+               goto done;
+no_nfs:
+       printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
+       ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
+skip_nfs:
+#endif
+
+#ifdef CONFIG_BLK_DEV_FD
+       if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
+#ifdef CONFIG_BLK_DEV_RAM
+               extern int rd_doload;
+               extern void rd_load_secondary(void);
+#endif
+               floppy_eject();
+#ifndef CONFIG_BLK_DEV_RAM
+               printk(KERN_NOTICE "(Warning, this kernel has no ramdisk support)\n");
+#else
+               /* rd_doload is 2 for a dual initrd/ramload setup */
+               if(rd_doload==2)
+                       rd_load_secondary();
+               else
+#endif
+               {
+                       printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
+                       wait_for_keypress();
+               }
+       }
+#endif
+
+       devfs_make_root (root_device_name);
+       handle = devfs_find_handle (NULL, ROOT_DEVICE_NAME,
+                                   MAJOR (ROOT_DEV), MINOR (ROOT_DEV),
+                                   DEVFS_SPECIAL_BLK, 1);
+       if (handle) {
+               int n;
+               unsigned major, minor;
+
+               devfs_get_maj_min (handle, &major, &minor);
+               ROOT_DEV = MKDEV (major, minor);
+               if (!ROOT_DEV)
+                       panic("I have no root and I want to scream");
+               n = devfs_generate_path (handle, path + 5, sizeof (path) - 5);
+               if (n >= 0) {
+                       name = path + n;
+                       devfs_mk_symlink (NULL, "root", DEVFS_FL_DEFAULT,
+                                         name + 5, NULL, NULL);
+                       memcpy (name, "/dev/", 5);
+                       do_devfs = 1;
+               }
+       }
+       chdir("/dev");
+       unlink("root");
+       mknod("root", S_IFBLK|0600, kdev_t_to_nr(ROOT_DEV));
+       if (do_devfs)
+               mount("devfs", ".", "devfs", 0, NULL);
+retry:
+       for (p = fs_names; *p; p += strlen(p)+1) {
+               err = mount(name,"/root",p,root_mountflags,root_mount_data);
+               switch (err) {
+                       case 0:
+                               goto done;
+                       case -EACCES:
+                               root_mountflags |= MS_RDONLY;
+                               goto retry;
+                       case -EINVAL:
+                               continue;
+               }
+               /*
+                * Allow the user to distinguish between failed open
+                * and bad superblock on root device.
+                */
+               printk ("VFS: Cannot open root device \"%s\" or %s\n",
+                       root_device_name, kdevname (ROOT_DEV));
+               printk ("Please append a correct \"root=\" boot option\n");
+               panic("VFS: Unable to mount root fs on %s",
+                       kdevname(ROOT_DEV));
+       }
+       panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
+
+done:
+       putname(fs_names);
+       if (do_devfs)
+               umount(".", 0);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+
+static int __init change_root(kdev_t new_root_dev,const char *put_old)
+{
+       struct vfsmount *old_rootmnt;
+       struct nameidata devfs_nd;
+       char *new_devname = kmalloc(strlen("/dev/root.old")+1, GFP_KERNEL);
+       int error = 0;
+
+       if (new_devname)
+               strcpy(new_devname, "/dev/root.old");
+
+       /* .. here is directory mounted over root */
+       mount("..", ".", NULL, MS_MOVE, NULL);
+       chdir("/old");
+
+       read_lock(&current->fs->lock);
+       old_rootmnt = mntget(current->fs->pwdmnt);
+       read_unlock(&current->fs->lock);
+
+       /*  First unmount devfs if mounted  */
+       if (path_init("/old/dev", LOOKUP_FOLLOW|LOOKUP_POSITIVE, &devfs_nd))
+               error = path_walk("/old/dev", &devfs_nd);
+       if (!error) {
+               if (devfs_nd.mnt->mnt_sb->s_magic == DEVFS_SUPER_MAGIC &&
+                   devfs_nd.dentry == devfs_nd.mnt->mnt_root)
+                       umount("/old/dev", 0);
+               path_release(&devfs_nd);
+       }
+
+       ROOT_DEV = new_root_dev;
+       mount_root();
+
+       chdir("/root");
+       ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
+       printk("VFS: Mounted root (%s filesystem)%s.\n",
+               current->fs->pwdmnt->mnt_sb->s_type->name,
+               (current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY) ? " readonly" : "");
+
+#if 1
+       shrink_dcache();
+       printk("change_root: old root has d_count=%d\n", 
+              atomic_read(&old_rootmnt->mnt_root->d_count));
+#endif
+
+       error = mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
+       if (error) {
+               int blivet;
+               struct block_device *ramdisk = old_rootmnt->mnt_sb->s_bdev;
+
+               atomic_inc(&ramdisk->bd_count);
+               blivet = blkdev_get(ramdisk, FMODE_READ, 0, BDEV_FS);
+               printk(KERN_NOTICE "Trying to unmount old root ... ");
+               umount("/old", MNT_DETACH);
+               if (!blivet) {
+                       blivet = ioctl_by_bdev(ramdisk, BLKFLSBUF, 0);
+                       blkdev_put(ramdisk, BDEV_FS);
+               }
+               if (blivet) {
+                       printk(KERN_ERR "error %d\n", blivet);
+               } else {
+                       printk("okay\n");
+                       error = 0;
+               }
+       } else {
+               spin_lock(&dcache_lock);
+               if (new_devname) {
+                       void *p = old_rootmnt->mnt_devname;
+                       old_rootmnt->mnt_devname = new_devname;
+                       new_devname = p;
+               }
+               spin_unlock(&dcache_lock);
+       }
+
+       /* put the old stuff */
+       mntput(old_rootmnt);
+       kfree(new_devname);
+       return error;
+}
+
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+static int do_linuxrc(void * shell)
+{
+       static char *argv[] = { "linuxrc", NULL, };
+       extern char * envp_init[];
+
+       chdir("/root");
+       mount(".", "/", NULL, MS_MOVE, NULL);
+       chroot(".");
+
+       mount_devfs_fs ();
+
+       close(0);close(1);close(2);
+       setsid();
+       (void) open("/dev/console",O_RDWR,0);
+       (void) dup(0);
+       (void) dup(0);
+       return execve(shell, argv, envp_init);
+}
+
+#endif
+
+/*
+ * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
+ */
+void prepare_namespace(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+       int real_root_mountflags = root_mountflags;
+       if (!initrd_start)
+               mount_initrd = 0;
+       if (mount_initrd)
+               root_mountflags &= ~MS_RDONLY;
+       real_root_dev = ROOT_DEV;
+#endif
+       mkdir("/dev", 0700);
+       mkdir("/root", 0700);
+
+#ifdef CONFIG_BLK_DEV_RAM
+#ifdef CONFIG_BLK_DEV_INITRD
+       if (mount_initrd)
+               initrd_load();
+       else
+#endif
+       rd_load();
+#endif
+
+       /* Mount the root filesystem.. */
+       mount_root();
+       chdir("/root");
+       ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
+       printk("VFS: Mounted root (%s filesystem)%s.\n",
+               current->fs->pwdmnt->mnt_sb->s_type->name,
+               (current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY) ? " readonly" : "");
+
+#ifdef CONFIG_BLK_DEV_INITRD
+       root_mountflags = real_root_mountflags;
+       if (mount_initrd && ROOT_DEV != real_root_dev
+           && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) {
+               int error;
+               int i, pid;
+               mkdir("/old", 0700);
+               chdir("/old");
+
+               pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
+               if (pid > 0) {
+                       while (pid != wait(&i)) {
+                               current->policy |= SCHED_YIELD;
+                               schedule();
+                       }
+               }
+               if (MAJOR(real_root_dev) != RAMDISK_MAJOR
+                    || MINOR(real_root_dev) != 0) {
+                       error = change_root(real_root_dev,"/initrd");
+                       if (error)
+                               printk(KERN_ERR "Change root to /initrd: "
+                                   "error %d\n",error);
+
+                       chdir("/root");
+                       mount(".", "/", NULL, MS_MOVE, NULL);
+                       chroot(".");
+
+                       mount_devfs_fs ();
+                       return;
+               }
+               chroot("..");
+               chdir("/");
+               return;
+       }
+#endif
+       mount(".", "/", NULL, MS_MOVE, NULL);
+       chroot(".");
+
+       mount_devfs_fs ();
+}
index b0e3304513e8f295b743dc11cb3195d53df9682a..c7e9d0faa42a8f2aebff572082bbef7a366df1bf 100644 (file)
@@ -120,17 +120,10 @@ extern void softirq_init(void);
 
 int rows, cols;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-unsigned int real_root_dev;    /* do_proc_dointvec cannot handle kdev_t */
-#endif
-
-int root_mountflags = MS_RDONLY;
 char *execute_command;
-char root_device_name[64];
-
 
 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
-static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
+char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
 
 static int __init profile_setup(char *str)
 {
@@ -141,175 +134,6 @@ static int __init profile_setup(char *str)
 
 __setup("profile=", profile_setup);
 
-
-static struct dev_name_struct {
-       const char *name;
-       const int num;
-} root_dev_names[] __initdata = {
-       { "nfs",     0x00ff },
-       { "hda",     0x0300 },
-       { "hdb",     0x0340 },
-       { "loop",    0x0700 },
-       { "hdc",     0x1600 },
-       { "hdd",     0x1640 },
-       { "hde",     0x2100 },
-       { "hdf",     0x2140 },
-       { "hdg",     0x2200 },
-       { "hdh",     0x2240 },
-       { "hdi",     0x3800 },
-       { "hdj",     0x3840 },
-       { "hdk",     0x3900 },
-       { "hdl",     0x3940 },
-       { "hdm",     0x5800 },
-       { "hdn",     0x5840 },
-       { "hdo",     0x5900 },
-       { "hdp",     0x5940 },
-       { "hdq",     0x5A00 },
-       { "hdr",     0x5A40 },
-       { "hds",     0x5B00 },
-       { "hdt",     0x5B40 },
-       { "sda",     0x0800 },
-       { "sdb",     0x0810 },
-       { "sdc",     0x0820 },
-       { "sdd",     0x0830 },
-       { "sde",     0x0840 },
-       { "sdf",     0x0850 },
-       { "sdg",     0x0860 },
-       { "sdh",     0x0870 },
-       { "sdi",     0x0880 },
-       { "sdj",     0x0890 },
-       { "sdk",     0x08a0 },
-       { "sdl",     0x08b0 },
-       { "sdm",     0x08c0 },
-       { "sdn",     0x08d0 },
-       { "sdo",     0x08e0 },
-       { "sdp",     0x08f0 },
-       { "ada",     0x1c00 },
-       { "adb",     0x1c10 },
-       { "adc",     0x1c20 },
-       { "add",     0x1c30 },
-       { "ade",     0x1c40 },
-       { "fd",      0x0200 },
-       { "md",      0x0900 },       
-       { "xda",     0x0d00 },
-       { "xdb",     0x0d40 },
-       { "ram",     0x0100 },
-       { "scd",     0x0b00 },
-       { "mcd",     0x1700 },
-       { "cdu535",  0x1800 },
-       { "sonycd",  0x1800 },
-       { "aztcd",   0x1d00 },
-       { "cm206cd", 0x2000 },
-       { "gscd",    0x1000 },
-       { "sbpcd",   0x1900 },
-       { "eda",     0x2400 },
-       { "edb",     0x2440 },
-       { "pda",        0x2d00 },
-       { "pdb",        0x2d10 },
-       { "pdc",        0x2d20 },
-       { "pdd",        0x2d30 },
-       { "pcd",        0x2e00 },
-       { "pf",         0x2f00 },
-       { "apblock", APBLOCK_MAJOR << 8},
-       { "ddv", DDV_MAJOR << 8},
-       { "jsfd",    JSFD_MAJOR << 8},
-#if defined(CONFIG_ARCH_S390)
-       { "dasda", (DASD_MAJOR << MINORBITS) },
-       { "dasdb", (DASD_MAJOR << MINORBITS) + (1 << 2) },
-       { "dasdc", (DASD_MAJOR << MINORBITS) + (2 << 2) },
-       { "dasdd", (DASD_MAJOR << MINORBITS) + (3 << 2) },
-       { "dasde", (DASD_MAJOR << MINORBITS) + (4 << 2) },
-       { "dasdf", (DASD_MAJOR << MINORBITS) + (5 << 2) },
-       { "dasdg", (DASD_MAJOR << MINORBITS) + (6 << 2) },
-       { "dasdh", (DASD_MAJOR << MINORBITS) + (7 << 2) },
-#endif
-#if defined(CONFIG_BLK_CPQ_DA) || defined(CONFIG_BLK_CPQ_DA_MODULE)
-       { "ida/c0d0p",0x4800 },
-       { "ida/c0d1p",0x4810 },
-       { "ida/c0d2p",0x4820 },
-       { "ida/c0d3p",0x4830 },
-       { "ida/c0d4p",0x4840 },
-       { "ida/c0d5p",0x4850 },
-       { "ida/c0d6p",0x4860 },
-       { "ida/c0d7p",0x4870 },
-       { "ida/c0d8p",0x4880 },
-       { "ida/c0d9p",0x4890 },
-       { "ida/c0d10p",0x48A0 },
-       { "ida/c0d11p",0x48B0 },
-       { "ida/c0d12p",0x48C0 },
-       { "ida/c0d13p",0x48D0 },
-       { "ida/c0d14p",0x48E0 },
-       { "ida/c0d15p",0x48F0 },
-#endif
-#if defined(CONFIG_BLK_CPQ_CISS_DA) || defined(CONFIG_BLK_CPQ_CISS_DA_MODULE)
-       { "cciss/c0d0p",0x6800 },
-       { "cciss/c0d1p",0x6810 },
-       { "cciss/c0d2p",0x6820 },
-       { "cciss/c0d3p",0x6830 },
-       { "cciss/c0d4p",0x6840 },
-       { "cciss/c0d5p",0x6850 },
-       { "cciss/c0d6p",0x6860 },
-       { "cciss/c0d7p",0x6870 },
-       { "cciss/c0d8p",0x6880 },
-       { "cciss/c0d9p",0x6890 },
-       { "cciss/c0d10p",0x68A0 },
-       { "cciss/c0d11p",0x68B0 },
-       { "cciss/c0d12p",0x68C0 },
-       { "cciss/c0d13p",0x68D0 },
-       { "cciss/c0d14p",0x68E0 },
-       { "cciss/c0d15p",0x68F0 },
-#endif
-       { "nftla", 0x5d00 },
-       { "nftlb", 0x5d10 },
-       { "nftlc", 0x5d20 },
-       { "nftld", 0x5d30 },
-       { "ftla", 0x2c00 },
-       { "ftlb", 0x2c08 },
-       { "ftlc", 0x2c10 },
-       { "ftld", 0x2c18 },
-       { "mtdblock", 0x1f00 },
-       { NULL, 0 }
-};
-
-kdev_t __init name_to_kdev_t(char *line)
-{
-       int base = 0;
-
-       if (strncmp(line,"/dev/",5) == 0) {
-               struct dev_name_struct *dev = root_dev_names;
-               line += 5;
-               do {
-                       int len = strlen(dev->name);
-                       if (strncmp(line,dev->name,len) == 0) {
-                               line += len;
-                               base = dev->num;
-                               break;
-                       }
-                       dev++;
-               } while (dev->name);
-       }
-       return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
-}
-
-static int __init root_dev_setup(char *line)
-{
-       int i;
-       char ch;
-
-       ROOT_DEV = name_to_kdev_t(line);
-       memset (root_device_name, 0, sizeof root_device_name);
-       if (strncmp (line, "/dev/", 5) == 0) line += 5;
-       for (i = 0; i < sizeof root_device_name - 1; ++i)
-       {
-           ch = line[i];
-           if ( isspace (ch) || (ch == ',') || (ch == '\0') ) break;
-           root_device_name[i] = ch;
-       }
-       return 1;
-}
-
-__setup("root=", root_dev_setup);
-
 static int __init checksetup(char *line)
 {
        struct kernel_param *p;
@@ -376,22 +200,6 @@ void __init calibrate_delay(void)
                (loops_per_jiffy/(5000/HZ)) % 100);
 }
 
-static int __init readonly(char *str)
-{
-       if (*str)
-               return 0;
-       root_mountflags |= MS_RDONLY;
-       return 1;
-}
-
-static int __init readwrite(char *str)
-{
-       if (*str)
-               return 0;
-       root_mountflags &= ~MS_RDONLY;
-       return 1;
-}
-
 static int __init debug_kernel(char *str)
 {
        if (*str)
@@ -408,8 +216,6 @@ static int __init quiet_kernel(char *str)
        return 1;
 }
 
-__setup("ro", readonly);
-__setup("rw", readwrite);
 __setup("debug", debug_kernel);
 __setup("quiet", quiet_kernel);
 
@@ -624,21 +430,6 @@ asmlinkage void __init start_kernel(void)
        rest_init();
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
-static int do_linuxrc(void * shell)
-{
-       static char *argv[] = { "linuxrc", NULL, };
-
-       close(0);close(1);close(2);
-       setsid();
-       (void) open("/dev/console",O_RDWR,0);
-       (void) dup(0);
-       (void) dup(0);
-       return execve(shell, argv, envp_init);
-}
-
-#endif
-
 struct task_struct *child_reaper = &init_task;
 
 static void __init do_initcalls(void)
@@ -745,61 +536,7 @@ static void __init do_basic_setup(void)
 #endif
 }
 
-extern void rd_load(void);
-extern void initrd_load(void);
-
-/*
- * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
- */
-static void prepare_namespace(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-       int real_root_mountflags = root_mountflags;
-       if (!initrd_start)
-               mount_initrd = 0;
-       if (mount_initrd)
-               root_mountflags &= ~MS_RDONLY;
-       real_root_dev = ROOT_DEV;
-#endif
-
-#ifdef CONFIG_BLK_DEV_RAM
-#ifdef CONFIG_BLK_DEV_INITRD
-       if (mount_initrd)
-               initrd_load();
-       else
-#endif
-       rd_load();
-#endif
-
-       /* Mount the root filesystem.. */
-       mount_root();
-
-       mount_devfs_fs ();
-
-#ifdef CONFIG_BLK_DEV_INITRD
-       root_mountflags = real_root_mountflags;
-       if (mount_initrd && ROOT_DEV != real_root_dev
-           && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) {
-               int error;
-               int i, pid;
-
-               pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
-               if (pid > 0) {
-                       while (pid != wait(&i)) {
-                               current->policy |= SCHED_YIELD;
-                               schedule();
-                       }
-               }
-               if (MAJOR(real_root_dev) != RAMDISK_MAJOR
-                    || MINOR(real_root_dev) != 0) {
-                       error = change_root(real_root_dev,"/initrd");
-                       if (error)
-                               printk(KERN_ERR "Change root to /initrd: "
-                                   "error %d\n",error);
-               }
-       }
-#endif
-}
+extern void prepare_namespace(void);
 
 static int init(void * unused)
 {
index 353421226835db02a5a02ff3b45e03ecae3403cf..06798d64990fbf43741e52a0d325cf4b6480d58a 100644 (file)
@@ -50,11 +50,6 @@ int (*platform_notify)(struct device * dev) = NULL;
 int (*platform_notify_remove)(struct device * dev) = NULL;
 
 static spinlock_t device_lock;
-static LIST_HEAD(device_gc_list);
-
-static int kdeviced_pid = 0;
-static DECLARE_WAIT_QUEUE_HEAD(kdeviced_wait);
-static DECLARE_COMPLETION(kdeviced_exited);
 
 static ssize_t device_read_status(char *, size_t, loff_t, void *);
 static ssize_t device_write_status(const char *, size_t, loff_t, void *);
@@ -379,12 +374,24 @@ void put_device(struct device * dev)
        list_del_init(&dev->node);
        unlock_iobus(parent);
 
-       /* queue the device to be removed by the reaper. */
-       spin_lock(&device_lock);
-       list_add_tail(&dev->node,&device_gc_list);
-       spin_unlock(&device_lock);
+       /* remove the driverfs directory */
+       device_remove_dir(dev);
+
+       if (dev->subordinate)
+               iobus_remove_dir(dev->subordinate);
 
-       wake_up(&kdeviced_wait);
+       /* Notify the platform of the removal, in case they
+        * need to do anything...
+        */
+       if (platform_notify_remove)
+               platform_notify_remove(dev);
+
+       /* Tell the driver to clean up after itself.
+        * Note that we likely didn't allocate the device,
+        * so this is the driver's chance to free that up...
+        */
+       if (dev->driver && dev->driver->remove)
+               dev->driver->remove(dev,REMOVE_FREE_RESOURCES);
 
        put_iobus(parent);
 }
@@ -875,76 +882,6 @@ static ssize_t iobus_write_status(const char *buf, size_t count, loff_t off, voi
        return error < 0 ? error : count;
 }
 
-/* Device Garbage Collection
- * When a device's reference count reaches 0, it is removed from it's
- * parent's list and added to a list of devices waiting to be removed.
- *
- * We don't directly remove it ourselves, because someone could have an
- * open file.
- *
- * We don't allocate an event for keventd, becuase we may be here from
- * an interrupt; and how do those things get freed, anyway?
- *
- * Instead, when a device's reference count reaches 0, it is removed
- * from its parent's list of children and added to the list of devices
- * to be reaped.
- *
- * When we spawn a thread that gets woken up every time a device is added
- * to the unused list.
- */
-static inline void __reap_device(struct device * dev)
-{
-       /* FIXME: What do we do for a bridge? */
-
-       /* remove the driverfs directory */
-       device_remove_dir(dev);
-
-       if (dev->subordinate)
-               iobus_remove_dir(dev->subordinate);
-
-       /* Notify the platform of the removal, in case they
-        * need to do anything...
-        */
-       if (platform_notify_remove)
-               platform_notify_remove(dev);
-
-       /* Tell the driver to clean up after itself.
-        * Note that we likely didn't allocate the device,
-        * so this is the driver's chance to free that up...
-        */
-       if (dev->driver && dev->driver->remove)
-               dev->driver->remove(dev,REMOVE_FREE_RESOURCES);
-}
-
-static int device_cleanup_thread(void * data)
-{
-       daemonize();
-
-       strcpy(current->comm,"kdeviced");
-
-       do {
-               struct list_head * node;
-
-               spin_lock(&device_lock);
-               node = device_gc_list.next;
-               while(node != &device_gc_list) {
-                       list_del_init(node);
-                       spin_unlock(&device_lock);
-                       __reap_device(list_to_dev(node));
-
-                       spin_lock(&device_lock);
-                       node = device_gc_list.next;
-               }
-               spin_unlock(&device_lock);
-
-               interruptible_sleep_on(&kdeviced_wait);
-       } while(!signal_pending(current));
-
-       DBG("kdeviced exiting\n");
-       complete_and_exit(&kdeviced_exited,0);
-       return 0;
-}
-
 static int __init device_init_root(void)
 {
        /* initialize parent bus lists */
@@ -981,27 +918,13 @@ int __init device_driver_init(void)
                return error;
        }
 
-       /* initialise the garbage collection */
-       pid = kernel_thread(device_cleanup_thread,NULL,
-                           (CLONE_FS | CLONE_FILES | CLONE_SIGHAND));
-       if (pid > 0)
-               kdeviced_pid = pid;
-       else {
-               DBG("DEV: Could not start cleanup thread\n");
-               return pid;
-       }
-
        DBG("DEV: Done Initialising\n");
        return error;
 }
 
 void __exit device_driver_exit(void)
 {
-       if (kdeviced_pid) {
-               kill_proc(kdeviced_pid,SIGTERM,1);
-               kdeviced_pid = 0;
-               wait_for_completion(&kdeviced_exited);
-       }
+
 }
 
 static int __init device_setup(char *str)
index c353ab73123cc64b2c72f38542e2234a45288c4e..4d248a59c314a6e39de44f6de7d678920d3a8d7e 100644 (file)
@@ -214,7 +214,7 @@ static inline void copy_to_high_bio_irq(struct bio *to, struct bio *from)
        struct bio_vec *tovec, *fromvec;
        int i;
 
-       bio_for_each_segment(tovec, to, i) {
+       __bio_for_each_segment(tovec, to, i, 0) {
                fromvec = &from->bi_io_vec[i];
 
                /*
@@ -225,12 +225,11 @@ static inline void copy_to_high_bio_irq(struct bio *to, struct bio *from)
 
                vfrom = page_address(fromvec->bv_page) + fromvec->bv_offset;
 
-               __save_flags(flags);
-               __cli();
+               local_irq_save(flags);
                vto = kmap_atomic(tovec->bv_page, KM_BOUNCE_READ);
-               memcpy(vto + tovec->bv_offset, vfrom, to->bi_size);
+               memcpy(vto + tovec->bv_offset, vfrom, tovec->bv_len);
                kunmap_atomic(vto, KM_BOUNCE_READ);
-               __restore_flags(flags);
+               local_irq_restore(flags);
        }
 }
 
@@ -263,28 +262,39 @@ __initcall(init_emergency_pool);
 static inline int bounce_end_io (struct bio *bio, int nr_sectors)
 {
        struct bio *bio_orig = bio->bi_private;
-       struct page *page = bio_page(bio);
+       struct bio_vec *bvec, *org_vec;
        unsigned long flags;
-       int ret;
+       int ret, i;
 
-       if (test_bit(BIO_UPTODATE, &bio->bi_flags))
-               set_bit(BIO_UPTODATE, &bio_orig->bi_flags);
+       if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+               goto out_eio;
 
-       ret = bio_orig->bi_end_io(bio_orig, nr_sectors);
+       set_bit(BIO_UPTODATE, &bio_orig->bi_flags);
 
+       /*
+        * free up bounce indirect pages used
+        */
        spin_lock_irqsave(&emergency_lock, flags);
-       if (nr_emergency_pages >= POOL_SIZE) {
-               spin_unlock_irqrestore(&emergency_lock, flags);
-               __free_page(page);
-       } else {
-               /*
-                * We are abusing page->list to manage
-                * the highmem emergency pool:
-                */
-               list_add(&page->list, &emergency_pages);
-               nr_emergency_pages++;
-               spin_unlock_irqrestore(&emergency_lock, flags);
+       __bio_for_each_segment(bvec, bio, i, 0) {
+               org_vec = &bio_orig->bi_io_vec[i];
+               if (bvec->bv_page == org_vec->bv_page)
+                       continue;
+       
+               if (nr_emergency_pages >= POOL_SIZE)
+                       __free_page(bvec->bv_page);
+               else {
+                       /*
+                        * We are abusing page->list to manage
+                        * the highmem emergency pool:
+                        */
+                       list_add(&bvec->bv_page->list, &emergency_pages);
+                       nr_emergency_pages++;
+               }
        }
+       spin_unlock_irqrestore(&emergency_lock, flags);
+
+out_eio:
+       ret = bio_orig->bi_end_io(bio_orig, nr_sectors);
 
        bio_put(bio);
        return ret;