return pfn from direct_access, for XIP
[safe/jmp/linux-2.6] / drivers / block / loop.c
index a5f993a..f7f1635 100644 (file)
@@ -29,7 +29,7 @@
  *
  * Maximum number of loop devices when compiled-in now selectable by passing
  * max_loop=<1-255> to the kernel on boot.
- * Erik I. Bolsø, <eriki@himolde.no>, Oct 31, 1999
+ * Erik I. Bolsø, <eriki@himolde.no>, Oct 31, 1999
  *
  * Completely rewrite request handling to be make_request_fn style and
  * non blocking, pushing work to a helper thread. Lots of fixes from
@@ -82,6 +82,9 @@
 static LIST_HEAD(loop_devices);
 static DEFINE_MUTEX(loop_devices_mutex);
 
+static int max_part;
+static int part_shift;
+
 /*
  * Transfer functions
  */
@@ -245,10 +248,8 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
 
                ret = pagecache_write_end(file, mapping, pos, size, copied,
                                                        page, fsdata);
-               if (ret < 0)
+               if (ret < 0 || ret != copied)
                        goto fail;
-               if (ret < copied)
-                       copied = ret;
 
                if (unlikely(transfer_result))
                        goto fail;
@@ -612,7 +613,7 @@ static int loop_thread(void *data)
 static int loop_switch(struct loop_device *lo, struct file *file)
 {
        struct switch_request w;
-       struct bio *bio = bio_alloc(GFP_KERNEL, 1);
+       struct bio *bio = bio_alloc(GFP_KERNEL, 0);
        if (!bio)
                return -ENOMEM;
        init_completion(&w.wait);
@@ -694,6 +695,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
                goto out_putf;
 
        fput(old_file);
+       if (max_part > 0)
+               ioctl_by_bdev(bdev, BLKRRPART, 0);
        return 0;
 
  out_putf:
@@ -821,6 +824,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
        }
        lo->lo_state = Lo_bound;
        wake_up_process(lo->lo_thread);
+       if (max_part > 0)
+               ioctl_by_bdev(bdev, BLKRRPART, 0);
        return 0;
 
 out_clr:
@@ -921,6 +926,8 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
        fput(filp);
        /* This is safe: open() is still holding a reference. */
        module_put(THIS_MODULE);
+       if (max_part > 0)
+               ioctl_by_bdev(bdev, BLKRRPART, 0);
        return 0;
 }
 
@@ -975,6 +982,10 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
        lo->transfer = xfer->transfer;
        lo->ioctl = xfer->ioctl;
 
+       if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) !=
+            (info->lo_flags & LO_FLAGS_AUTOCLEAR))
+               lo->lo_flags ^= LO_FLAGS_AUTOCLEAR;
+
        lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
        lo->lo_init[0] = info->lo_init[0];
        lo->lo_init[1] = info->lo_init[1];
@@ -1287,7 +1298,6 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
        struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
        int err;
 
-       lock_kernel();
        switch(cmd) {
        case LOOP_SET_STATUS:
                mutex_lock(&lo->lo_ctl_mutex);
@@ -1313,7 +1323,6 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
                err = -ENOIOCTLCMD;
                break;
        }
-       unlock_kernel();
        return err;
 }
 #endif
@@ -1335,6 +1344,10 @@ static int lo_release(struct inode *inode, struct file *file)
 
        mutex_lock(&lo->lo_ctl_mutex);
        --lo->lo_refcnt;
+
+       if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) && !lo->lo_refcnt)
+               loop_clr_fd(lo, inode->i_bdev);
+
        mutex_unlock(&lo->lo_ctl_mutex);
 
        return 0;
@@ -1356,6 +1369,8 @@ static struct block_device_operations lo_fops = {
 static int max_loop;
 module_param(max_loop, int, 0);
 MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
+module_param(max_part, int, 0);
+MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
 
@@ -1408,7 +1423,7 @@ static struct loop_device *loop_alloc(int i)
        if (!lo->lo_queue)
                goto out_free_dev;
 
-       disk = lo->lo_disk = alloc_disk(1);
+       disk = lo->lo_disk = alloc_disk(1 << part_shift);
        if (!disk)
                goto out_free_queue;
 
@@ -1418,7 +1433,7 @@ static struct loop_device *loop_alloc(int i)
        init_waitqueue_head(&lo->lo_event);
        spin_lock_init(&lo->lo_lock);
        disk->major             = LOOP_MAJOR;
-       disk->first_minor       = i;
+       disk->first_minor       = i << part_shift;
        disk->fops              = &lo_fops;
        disk->private_data      = lo;
        disk->queue             = lo->lo_queue;
@@ -1498,7 +1513,12 @@ static int __init loop_init(void)
         *     themselves and have kernel automatically instantiate actual
         *     device on-demand.
         */
-       if (max_loop > 1UL << MINORBITS)
+
+       part_shift = 0;
+       if (max_part > 0)
+               part_shift = fls(max_part);
+
+       if (max_loop > 1UL << (MINORBITS - part_shift))
                return -EINVAL;
 
        if (max_loop) {
@@ -1506,7 +1526,7 @@ static int __init loop_init(void)
                range = max_loop;
        } else {
                nr = 8;
-               range = 1UL << MINORBITS;
+               range = 1UL << (MINORBITS - part_shift);
        }
 
        if (register_blkdev(LOOP_MAJOR, "loop"))
@@ -1545,7 +1565,7 @@ static void __exit loop_exit(void)
        unsigned long range;
        struct loop_device *lo, *next;
 
-       range = max_loop ? max_loop :  1UL << MINORBITS;
+       range = max_loop ? max_loop :  1UL << (MINORBITS - part_shift);
 
        list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
                loop_del_one(lo);