]> err.no Git - linux-2.6/blobdiff - drivers/block/loop.c
[PATCH] Correct tty doc
[linux-2.6] / drivers / block / loop.c
index a452b13620a228739fe60f296e85720643bf03e0..9dc294a74953f3793a71cb179f36224421d333e8 100644 (file)
@@ -74,6 +74,7 @@
 #include <linux/completion.h>
 #include <linux/highmem.h>
 #include <linux/gfp.h>
+#include <linux/kthread.h>
 
 #include <asm/uaccess.h>
 
@@ -215,7 +216,7 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
        unsigned offset, bv_offs;
        int len, ret;
 
-       down(&mapping->host->i_sem);
+       mutex_lock(&mapping->host->i_mutex);
        index = pos >> PAGE_CACHE_SHIFT;
        offset = pos & ((pgoff_t)PAGE_CACHE_SIZE - 1);
        bv_offs = bvec->bv_offset;
@@ -278,7 +279,7 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
        }
        ret = 0;
 out:
-       up(&mapping->host->i_sem);
+       mutex_unlock(&mapping->host->i_mutex);
        return ret;
 unlock:
        unlock_page(page);
@@ -294,7 +295,7 @@ fail:
  * This helper just factors out common code between do_lo_send_direct_write()
  * and do_lo_send_write().
  */
-static inline int __do_lo_send_write(struct file *file,
+static int __do_lo_send_write(struct file *file,
                u8 __user *buf, const int len, loff_t pos)
 {
        ssize_t bw;
@@ -527,12 +528,12 @@ static int loop_make_request(request_queue_t *q, struct bio *old_bio)
        lo->lo_pending++;
        loop_add_bio(lo, old_bio);
        spin_unlock_irq(&lo->lo_lock);
-       up(&lo->lo_bh_mutex);
+       complete(&lo->lo_bh_done);
        return 0;
 
 out:
        if (lo->lo_pending == 0)
-               up(&lo->lo_bh_mutex);
+               complete(&lo->lo_bh_done);
        spin_unlock_irq(&lo->lo_lock);
        bio_io_error(old_bio, old_bio->bi_size);
        return 0;
@@ -578,8 +579,6 @@ static int loop_thread(void *data)
        struct loop_device *lo = data;
        struct bio *bio;
 
-       daemonize("loop%d", lo->lo_number);
-
        /*
         * loop can be used in an encrypted device,
         * hence, it mustn't be stopped at all
@@ -592,24 +591,16 @@ static int loop_thread(void *data)
        lo->lo_state = Lo_bound;
        lo->lo_pending = 1;
 
-       /*
-        * up sem, we are running
-        */
-       up(&lo->lo_sem);
-
        for (;;) {
                int pending;
 
-               /*
-                * interruptible just to not contribute to load avg
-                */
-               if (down_interruptible(&lo->lo_bh_mutex))
+               if (wait_for_completion_interruptible(&lo->lo_bh_done))
                        continue;
 
                spin_lock_irq(&lo->lo_lock);
 
                /*
-                * could be upped because of tear-down, not pending work
+                * could be completed because of tear-down, not pending work
                 */
                if (unlikely(!lo->lo_pending)) {
                        spin_unlock_irq(&lo->lo_lock);
@@ -632,7 +623,6 @@ static int loop_thread(void *data)
                        break;
        }
 
-       up(&lo->lo_sem);
        return 0;
 }
 
@@ -749,6 +739,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
        unsigned lo_blocksize;
        int             lo_flags = 0;
        int             error;
+       struct task_struct *tsk;
        loff_t          size;
 
        /* This is safe, since we have a reference from open(). */
@@ -821,7 +812,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
        lo->lo_device = bdev;
        lo->lo_flags = lo_flags;
        lo->lo_backing_file = file;
-       lo->transfer = NULL;
+       lo->transfer = transfer_none;
        lo->ioctl = NULL;
        lo->lo_sizelimit = 0;
        lo->old_gfp_mask = mapping_gfp_mask(mapping);
@@ -842,8 +833,11 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
 
        set_blocksize(bdev, lo_blocksize);
 
-       kernel_thread(loop_thread, lo, CLONE_KERNEL);
-       down(&lo->lo_sem);
+       tsk = kthread_run(loop_thread, lo, "loop%d", lo->lo_number);
+       if (IS_ERR(tsk)) {
+               error = PTR_ERR(tsk);
+               goto out_putf;
+       }
        return 0;
 
  out_putf:
@@ -899,6 +893,9 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
        if (lo->lo_state != Lo_bound)
                return -ENXIO;
 
+       if (!lo->lo_thread)
+               return -EINVAL;
+
        if (lo->lo_refcnt > 1)  /* we needed one fd for the ioctl */
                return -EBUSY;
 
@@ -909,10 +906,10 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
        lo->lo_state = Lo_rundown;
        lo->lo_pending--;
        if (!lo->lo_pending)
-               up(&lo->lo_bh_mutex);
+               complete(&lo->lo_bh_done);
        spin_unlock_irq(&lo->lo_lock);
 
-       down(&lo->lo_sem);
+       kthread_stop(lo->lo_thread);
 
        lo->lo_backing_file = NULL;
 
@@ -925,6 +922,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
        lo->lo_sizelimit = 0;
        lo->lo_encrypt_key_size = 0;
        lo->lo_flags = 0;
+       lo->lo_thread = NULL;
        memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
        memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
        memset(lo->lo_file_name, 0, LO_NAME_SIZE);
@@ -1147,7 +1145,7 @@ static int lo_ioctl(struct inode * inode, struct file * file,
        struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
        int err;
 
-       down(&lo->lo_ctl_mutex);
+       mutex_lock(&lo->lo_ctl_mutex);
        switch (cmd) {
        case LOOP_SET_FD:
                err = loop_set_fd(lo, file, inode->i_bdev, arg);
@@ -1173,7 +1171,7 @@ static int lo_ioctl(struct inode * inode, struct file * file,
        default:
                err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
        }
-       up(&lo->lo_ctl_mutex);
+       mutex_unlock(&lo->lo_ctl_mutex);
        return err;
 }
 
@@ -1181,9 +1179,9 @@ static int lo_open(struct inode *inode, struct file *file)
 {
        struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
 
-       down(&lo->lo_ctl_mutex);
+       mutex_lock(&lo->lo_ctl_mutex);
        lo->lo_refcnt++;
-       up(&lo->lo_ctl_mutex);
+       mutex_unlock(&lo->lo_ctl_mutex);
 
        return 0;
 }
@@ -1192,9 +1190,9 @@ static int lo_release(struct inode *inode, struct file *file)
 {
        struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
 
-       down(&lo->lo_ctl_mutex);
+       mutex_lock(&lo->lo_ctl_mutex);
        --lo->lo_refcnt;
-       up(&lo->lo_ctl_mutex);
+       mutex_unlock(&lo->lo_ctl_mutex);
 
        return 0;
 }
@@ -1236,12 +1234,12 @@ int loop_unregister_transfer(int number)
        xfer_funcs[n] = NULL;
 
        for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
-               down(&lo->lo_ctl_mutex);
+               mutex_lock(&lo->lo_ctl_mutex);
 
                if (lo->lo_encryption == xfer)
                        loop_release_xfer(lo);
 
-               up(&lo->lo_ctl_mutex);
+               mutex_unlock(&lo->lo_ctl_mutex);
        }
 
        return 0;
@@ -1288,9 +1286,8 @@ static int __init loop_init(void)
                lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
                if (!lo->lo_queue)
                        goto out_mem4;
-               init_MUTEX(&lo->lo_ctl_mutex);
-               init_MUTEX_LOCKED(&lo->lo_sem);
-               init_MUTEX_LOCKED(&lo->lo_bh_mutex);
+               mutex_init(&lo->lo_ctl_mutex);
+               init_completion(&lo->lo_bh_done);
                lo->lo_number = i;
                spin_lock_init(&lo->lo_lock);
                disk->major = LOOP_MAJOR;
@@ -1310,7 +1307,7 @@ static int __init loop_init(void)
 
 out_mem4:
        while (i--)
-               blk_put_queue(loop_dev[i].lo_queue);
+               blk_cleanup_queue(loop_dev[i].lo_queue);
        devfs_remove("loop");
        i = max_loop;
 out_mem3:
@@ -1331,7 +1328,7 @@ static void loop_exit(void)
 
        for (i = 0; i < max_loop; i++) {
                del_gendisk(disks[i]);
-               blk_put_queue(loop_dev[i].lo_queue);
+               blk_cleanup_queue(loop_dev[i].lo_queue);
                put_disk(disks[i]);
        }
        devfs_remove("loop");