From: Jeff Dike The code is still there but it's not built. Below is a patch which removes it totally. Signed-off-by: Andrew Morton --- 25-akpm/arch/um/Kconfig_block | 12 25-akpm/arch/um/drivers/Makefile | 1 25-akpm/arch/um/drivers/cow_kern.c | 630 ------------------------------------- 3 files changed, 1 insertion(+), 642 deletions(-) diff -puN arch/um/drivers/cow_kern.c~uml-remove-cow-driver arch/um/drivers/cow_kern.c --- 25/arch/um/drivers/cow_kern.c~uml-remove-cow-driver Tue Aug 17 15:52:00 2004 +++ 25-akpm/arch/um/drivers/cow_kern.c Tue Aug 17 15:52:00 2004 @@ -1,630 +0,0 @@ -#define COW_MAJOR 60 -#define MAJOR_NR COW_MAJOR - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "2_5compat.h" -#include "cow.h" -#include "ubd_user.h" - -#define COW_SHIFT 4 - -struct cow { - int count; - char *cow_path; - dev_t cow_dev; - struct block_device *cow_bdev; - char *backing_path; - dev_t backing_dev; - struct block_device *backing_bdev; - int sectorsize; - unsigned long *bitmap; - unsigned long bitmap_len; - int bitmap_offset; - int data_offset; - devfs_handle_t devfs; - struct semaphore sem; - struct semaphore io_sem; - atomic_t working; - spinlock_t io_lock; - struct buffer_head *bh; - struct buffer_head *bhtail; - void *end_io; -}; - -#define DEFAULT_COW { \ - .count = 0, \ - .cow_path = NULL, \ - .cow_dev = 0, \ - .backing_path = NULL, \ - .backing_dev = 0, \ - .bitmap = NULL, \ - .bitmap_len = 0, \ - .bitmap_offset = 0, \ - .data_offset = 0, \ - .devfs = NULL, \ - .working = ATOMIC_INIT(0), \ - .io_lock = SPIN_LOCK_UNLOCKED, \ -} - -#define MAX_DEV (8) -#define MAX_MINOR (MAX_DEV << COW_SHIFT) - -struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW }; - -/* Not modified by this driver */ -static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE }; -static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 }; - -/* Protected by cow_lock */ -static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 }; - -static struct hd_struct cow_part[MAX_MINOR] = - { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } }; - -/* Protected by io_request_lock */ -static request_queue_t *cow_queue; - -static int cow_open(struct inode *inode, struct file *filp); -static int cow_release(struct inode * inode, struct file * file); -static int cow_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg); -static int cow_revalidate(kdev_t rdev); - -static struct block_device_operations cow_blops = { - .open = cow_open, - .release = cow_release, - .ioctl = cow_ioctl, - .revalidate = cow_revalidate, -}; - -/* Initialized in an initcall, and unchanged thereafter */ -devfs_handle_t cow_dir_handle; - -#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \ -{ \ - .major = maj, \ - .major_name = name, \ - .minor_shift = shift, \ - .max_p = 1 << shift, \ - .part = parts, \ - .sizes = bsizes, \ - .nr_real = max, \ - .real_devices = NULL, \ - .next = NULL, \ - .fops = blops, \ - .de_arr = NULL, \ - .flags = 0 \ -} - -static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED; - -static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part, - COW_SHIFT, sizes, MAX_DEV, - &cow_blops); - -static int cow_add(int n) -{ - struct cow *dev = &cow_dev[n]; - char name[sizeof("nnnnnn\0")]; - int err = -ENODEV; - - if(dev->cow_path == NULL) - goto out; - - sprintf(name, "%d", n); - dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE, - MAJOR_NR, n << COW_SHIFT, S_IFBLK | - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, - &cow_blops, NULL); - - init_MUTEX_LOCKED(&dev->sem); - init_MUTEX(&dev->io_sem); - - return(0); - - out: - return(err); -} - -/* - * Add buffer_head to back of pending list - */ -static void cow_add_bh(struct cow *cow, struct buffer_head *bh) -{ - unsigned long flags; - - spin_lock_irqsave(&cow->io_lock, flags); - if(cow->bhtail != NULL){ - cow->bhtail->b_reqnext = bh; - cow->bhtail = bh; - } - else { - cow->bh = bh; - cow->bhtail = bh; - } - spin_unlock_irqrestore(&cow->io_lock, flags); -} - -/* -* Grab first pending buffer -*/ -static struct buffer_head *cow_get_bh(struct cow *cow) -{ - struct buffer_head *bh; - - spin_lock_irq(&cow->io_lock); - bh = cow->bh; - if(bh != NULL){ - if(bh == cow->bhtail) - cow->bhtail = NULL; - cow->bh = bh->b_reqnext; - bh->b_reqnext = NULL; - } - spin_unlock_irq(&cow->io_lock); - - return(bh); -} - -static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, - struct buffer_head **cow_bh, int ncow_bh) -{ - int i; - - if(ncow_bh > 0) - ll_rw_block(WRITE, ncow_bh, cow_bh); - - for(i = 0; i < ncow_bh ; i++){ - wait_on_buffer(cow_bh[i]); - brelse(cow_bh[i]); - } - - ll_rw_block(WRITE, 1, &bh); - brelse(bh); -} - -static struct buffer_head *cow_new_bh(struct cow *dev, int sector) -{ - struct buffer_head *bh; - - sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize; - bh = getblk(dev->cow_dev, sector, dev->sectorsize); - memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])), - dev->sectorsize); - return(bh); -} - -/* Copied from loop.c, needed to avoid deadlocking in make_request. */ - -static int cow_thread(void *data) -{ - struct cow *dev = data; - struct buffer_head *bh; - - daemonize(); - exit_files(current); - - sprintf(current->comm, "cow%d", dev - cow_dev); - - spin_lock_irq(¤t->sigmask_lock); - sigfillset(¤t->blocked); - flush_signals(current); - spin_unlock_irq(¤t->sigmask_lock); - - atomic_inc(&dev->working); - - current->policy = SCHED_OTHER; - current->nice = -20; - - current->flags |= PF_NOIO; - - /* - * up sem, we are running - */ - up(&dev->sem); - - for(;;){ - int start, len, nbh, i, update_bitmap = 0; - struct buffer_head *cow_bh[2]; - - down_interruptible(&dev->io_sem); - /* - * could be upped because of tear-down, not because of - * pending work - */ - if(!atomic_read(&dev->working)) - break; - - bh = cow_get_bh(dev); - if(bh == NULL){ - printk(KERN_ERR "cow: missing bh\n"); - continue; - } - - start = bh->b_blocknr * bh->b_size / dev->sectorsize; - len = bh->b_size / dev->sectorsize; - for(i = 0; i < len ; i++){ - if(ubd_test_bit(start + i, - (unsigned char *) dev->bitmap)) - continue; - - update_bitmap = 1; - ubd_set_bit(start + i, (unsigned char *) dev->bitmap); - } - - cow_bh[0] = NULL; - cow_bh[1] = NULL; - nbh = 0; - if(update_bitmap){ - cow_bh[0] = cow_new_bh(dev, start); - nbh++; - if(start / dev->sectorsize != - (start + len) / dev->sectorsize){ - cow_bh[1] = cow_new_bh(dev, start + len); - nbh++; - } - } - - bh->b_dev = dev->cow_dev; - bh->b_blocknr += dev->data_offset / dev->sectorsize; - - cow_handle_bh(dev, bh, cow_bh, nbh); - - /* - * upped both for pending work and tear-down, lo_pending - * will hit zero then - */ - if(atomic_dec_and_test(&dev->working)) - break; - } - - up(&dev->sem); - return(0); -} - -static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh) -{ - struct cow *dev; - int n, minor; - - minor = MINOR(bh->b_rdev); - n = minor >> COW_SHIFT; - dev = &cow_dev[n]; - - dev->end_io = NULL; - if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){ - bh->b_rdev = dev->cow_dev; - bh->b_rsector += dev->data_offset / dev->sectorsize; - } - else if(rw == WRITE){ - bh->b_dev = dev->cow_dev; - bh->b_blocknr += dev->data_offset / dev->sectorsize; - - cow_add_bh(dev, bh); - up(&dev->io_sem); - return(0); - } - else { - bh->b_rdev = dev->backing_dev; - } - - return(1); -} - -int cow_init(void) -{ - int i; - - cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL); - if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) { - printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR); - return -1; - } - read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */ - blksize_size[MAJOR_NR] = blk_sizes; - blk_size[MAJOR_NR] = sizes; - INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes); - - cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR); - blk_init_queue(cow_queue, NULL); - INIT_ELV(cow_queue, &cow_queue->elevator); - blk_queue_make_request(cow_queue, cow_make_request); - - add_gendisk(&cow_gendisk); - - for(i=0;i 0){ - n = (left > blocksize) ? blocksize : left; - - bh = bread(dev, block, (n < 512) ? 512 : n); - if(bh == NULL) - return(-EIO); - - n -= offset; - memcpy(&buf[cur], bh->b_data + offset, n); - block++; - left -= n; - cur += n; - offset = 0; - brelse(bh); - } - - return(count); -} - -static int cow_open(struct inode *inode, struct file *filp) -{ - int (*dev_ioctl)(struct inode *, struct file *, unsigned int, - unsigned long); - mm_segment_t fs; - struct cow *dev; - __u64 size; - __u32 version, align; - time_t mtime; - char *backing_file; - int n, offset, err = 0; - - n = DEVICE_NR(inode->i_rdev); - if(n >= MAX_DEV) - return(-ENODEV); - dev = &cow_dev[n]; - offset = n << COW_SHIFT; - - spin_lock(&cow_lock); - - if(dev->count == 0){ - dev->cow_dev = name_to_kdev_t(dev->cow_path); - if(dev->cow_dev == 0){ - printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") " - "failed\n", dev->cow_path); - err = -ENODEV; - } - - dev->backing_dev = name_to_kdev_t(dev->backing_path); - if(dev->backing_dev == 0){ - printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") " - "failed\n", dev->backing_path); - err = -ENODEV; - } - - if(err) - goto out; - - dev->cow_bdev = bdget(dev->cow_dev); - if(dev->cow_bdev == NULL){ - printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", - dev->cow_path); - err = -ENOMEM; - } - dev->backing_bdev = bdget(dev->backing_dev); - if(dev->backing_bdev == NULL){ - printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", - dev->backing_path); - err = -ENOMEM; - } - - if(err) - goto out; - - err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, - BDEV_RAW); - if(err){ - printk("cow_open - blkdev_get of COW device failed, " - "error = %d\n", err); - goto out; - } - - err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW); - if(err){ - printk("cow_open - blkdev_get of backing device " - "failed, error = %d\n", err); - goto out; - } - - err = read_cow_header(reader, &dev->cow_dev, &version, - &backing_file, &mtime, &size, - &dev->sectorsize, &align, - &dev->bitmap_offset); - if(err){ - printk(KERN_ERR "cow_open - read_cow_header failed, " - "err = %d\n", err); - goto out; - } - - cow_sizes(version, size, dev->sectorsize, align, - dev->bitmap_offset, &dev->bitmap_len, - &dev->data_offset); - dev->bitmap = (void *) vmalloc(dev->bitmap_len); - if(dev->bitmap == NULL){ - err = -ENOMEM; - printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); - goto out; - } - flush_tlb_kernel_vm(); - - err = reader(dev->bitmap_offset, (char *) dev->bitmap, - dev->bitmap_len, &dev->cow_dev); - if(err < 0){ - printk(KERN_ERR "Failed to read COW bitmap\n"); - vfree(dev->bitmap); - goto out; - } - - dev_ioctl = dev->backing_bdev->bd_op->ioctl; - fs = get_fs(); - set_fs(KERNEL_DS); - err = (*dev_ioctl)(inode, filp, BLKGETSIZE, - (unsigned long) &sizes[offset]); - set_fs(fs); - if(err){ - printk(KERN_ERR "cow_open - BLKGETSIZE failed, " - "error = %d\n", err); - goto out; - } - - kernel_thread(cow_thread, dev, - CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - down(&dev->sem); - } - dev->count++; - out: - spin_unlock(&cow_lock); - return(err); -} - -static int cow_release(struct inode * inode, struct file * file) -{ - struct cow *dev; - int n, err; - - n = DEVICE_NR(inode->i_rdev); - if(n >= MAX_DEV) - return(-ENODEV); - dev = &cow_dev[n]; - - spin_lock(&cow_lock); - - if(--dev->count > 0) - goto out; - - err = blkdev_put(dev->cow_bdev, BDEV_RAW); - if(err) - printk("cow_release - blkdev_put of cow device failed, " - "error = %d\n", err); - bdput(dev->cow_bdev); - dev->cow_bdev = 0; - - err = blkdev_put(dev->backing_bdev, BDEV_RAW); - if(err) - printk("cow_release - blkdev_put of backing device failed, " - "error = %d\n", err); - bdput(dev->backing_bdev); - dev->backing_bdev = 0; - - out: - spin_unlock(&cow_lock); - return(0); -} - -static int cow_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) -{ - struct cow *dev; - int (*dev_ioctl)(struct inode *, struct file *, unsigned int, - unsigned long); - int n; - - n = DEVICE_NR(inode->i_rdev); - if(n >= MAX_DEV) - return(-ENODEV); - dev = &cow_dev[n]; - - dev_ioctl = dev->backing_bdev->bd_op->ioctl; - return((*dev_ioctl)(inode, file, cmd, arg)); -} - -static int cow_revalidate(kdev_t rdev) -{ - printk(KERN_ERR "Need to implement cow_revalidate\n"); - return(0); -} - -static int parse_unit(char **ptr) -{ - char *str = *ptr, *end; - int n = -1; - - if(isdigit(*str)) { - n = simple_strtoul(str, &end, 0); - if(end == str) - return(-1); - *ptr = end; - } - else if (('a' <= *str) && (*str <= 'h')) { - n = *str - 'a'; - str++; - *ptr = str; - } - return(n); -} - -static int cow_setup(char *str) -{ - struct cow *dev; - char *cow_name, *backing_name; - int unit; - - unit = parse_unit(&str); - if(unit < 0){ - printk(KERN_ERR "cow_setup - Couldn't parse unit number\n"); - return(1); - } - - if(*str != '='){ - printk(KERN_ERR "cow_setup - Missing '=' after unit " - "number\n"); - return(1); - } - str++; - - cow_name = str; - backing_name = strchr(str, ','); - if(backing_name == NULL){ - printk(KERN_ERR "cow_setup - missing backing device name\n"); - return(0); - } - *backing_name = '\0'; - backing_name++; - - spin_lock(&cow_lock); - - dev = &cow_dev[unit]; - dev->cow_path = cow_name; - dev->backing_path = backing_name; - - spin_unlock(&cow_lock); - return(0); -} - -__setup("cow", cow_setup); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -puN arch/um/drivers/Makefile~uml-remove-cow-driver arch/um/drivers/Makefile --- 25/arch/um/drivers/Makefile~uml-remove-cow-driver Tue Aug 17 15:52:00 2004 +++ 25-akpm/arch/um/drivers/Makefile Tue Aug 17 15:52:00 2004 @@ -39,7 +39,6 @@ obj-$(CONFIG_PTY_CHAN) += pty.o obj-$(CONFIG_TTY_CHAN) += tty.o obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o obj-$(CONFIG_UML_WATCHDOG) += harddog.o -obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o obj-y += stdio_console.o $(CHAN_OBJS) diff -puN arch/um/Kconfig_block~uml-remove-cow-driver arch/um/Kconfig_block --- 25/arch/um/Kconfig_block~uml-remove-cow-driver Tue Aug 17 15:52:00 2004 +++ 25-akpm/arch/um/Kconfig_block Tue Aug 17 15:52:00 2004 @@ -29,19 +29,9 @@ config BLK_DEV_UBD_SYNC wise choice too. In all other cases (for example, if you're just playing around with User-Mode Linux) you can choose N. -# Turn this back on when the driver actually works -# -#config BLK_DEV_COW -# tristate "COW block device" -# help -# This is a layered driver which sits above two other block devices. -# One is read-only, and the other is a read-write layer which stores -# all changes. This provides the illusion that the read-only layer -# can be mounted read-write and changed. - config BLK_DEV_COW_COMMON bool - default BLK_DEV_COW || BLK_DEV_UBD + default BLK_DEV_UBD config BLK_DEV_LOOP tristate "Loopback device support" _