*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
#include <linux/smp_lock.h>
#include <linux/swap.h>
#include <linux/slab.h>
#include <linux/completion.h>
#include <linux/highmem.h>
#include <linux/gfp.h>
-#include <linux/kthread.h>
#include <asm/uaccess.h>
{
struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */
struct address_space *mapping = file->f_mapping;
- struct address_space_operations *aops = mapping->a_ops;
+ const struct address_space_operations *aops = mapping->a_ops;
pgoff_t index;
unsigned offset, bv_offs;
int len, ret;
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
lo->lo_state = Lo_bound;
lo->lo_pending = 1;
+ /*
+ * complete it, we are running
+ */
+ complete(&lo->lo_done);
+
for (;;) {
int pending;
break;
}
+ complete(&lo->lo_done);
return 0;
}
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(). */
error = -EINVAL;
if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) {
- struct address_space_operations *aops = mapping->a_ops;
+ const struct address_space_operations *aops = mapping->a_ops;
/*
* If we can't read - sorry. If we only can't write - well,
* it's going to be read-only.
set_blocksize(bdev, lo_blocksize);
- tsk = kthread_run(loop_thread, lo, "loop%d", lo->lo_number);
- if (IS_ERR(tsk)) {
- error = PTR_ERR(tsk);
+ error = kernel_thread(loop_thread, lo, CLONE_KERNEL);
+ if (error < 0)
goto out_putf;
- }
+ wait_for_completion(&lo->lo_done);
return 0;
out_putf:
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;
complete(&lo->lo_bh_done);
spin_unlock_irq(&lo->lo_lock);
- kthread_stop(lo->lo_thread);
+ wait_for_completion(&lo->lo_done);
lo->lo_backing_file = NULL;
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);
goto out_mem3;
}
- devfs_mk_dir("loop");
-
for (i = 0; i < max_loop; i++) {
struct loop_device *lo = &loop_dev[i];
struct gendisk *disk = disks[i];
if (!lo->lo_queue)
goto out_mem4;
mutex_init(&lo->lo_ctl_mutex);
+ init_completion(&lo->lo_done);
init_completion(&lo->lo_bh_done);
lo->lo_number = i;
spin_lock_init(&lo->lo_lock);
disk->first_minor = i;
disk->fops = &lo_fops;
sprintf(disk->disk_name, "loop%d", i);
- sprintf(disk->devfs_name, "loop/%d", i);
disk->private_data = lo;
disk->queue = lo->lo_queue;
}
out_mem4:
while (i--)
blk_cleanup_queue(loop_dev[i].lo_queue);
- devfs_remove("loop");
i = max_loop;
out_mem3:
while (i--)
blk_cleanup_queue(loop_dev[i].lo_queue);
put_disk(disks[i]);
}
- devfs_remove("loop");
if (unregister_blkdev(LOOP_MAJOR, "loop"))
printk(KERN_WARNING "loop: cannot unregister blkdev\n");