X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fllite%2Flloop.c;h=b8ae0b50f440e6643c1639e67ed7f48367c4f67f;hp=5f00ab2902bf6faaeae35ae3a8ef03c2e78c5f82;hb=5e5e4ae2be4bc377f0f896163ae59bf338c4250c;hpb=3bffa4d32bc5b0bc71ba6873e262ddbca436bae1 diff --git a/lustre/llite/lloop.c b/lustre/llite/lloop.c index 5f00ab2..b8ae0b5 100644 --- a/lustre/llite/lloop.c +++ b/lustre/llite/lloop.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2014, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -82,6 +82,7 @@ #include #include +#include #include #include #include @@ -105,10 +106,9 @@ #include #include -#include #include "llite_internal.h" -#define LLOOP_MAX_SEGMENTS PTLRPC_MAX_BRW_PAGES +#define LLOOP_MAX_SEGMENTS LNET_MAX_IOV /* Possible states of device */ enum { @@ -118,19 +118,16 @@ enum { }; struct lloop_device { - int lo_number; - int lo_refcnt; - loff_t lo_offset; - loff_t lo_sizelimit; - int lo_flags; - int (*ioctl)(struct lloop_device *, int cmd, - unsigned long arg); + int lo_number; + int lo_refcnt; + loff_t lo_offset; + loff_t lo_sizelimit; + int lo_flags; + struct file *lo_backing_file; + struct block_device *lo_device; + unsigned lo_blocksize; - struct file *lo_backing_file; - struct block_device *lo_device; - unsigned lo_blocksize; - - int old_gfp_mask; + gfp_t old_gfp_mask; spinlock_t lo_lock; struct bio *lo_bio; @@ -138,20 +135,20 @@ struct lloop_device { int lo_state; struct semaphore lo_sem; struct mutex lo_ctl_mutex; - cfs_atomic_t lo_pending; - cfs_waitq_t lo_bh_wait; + atomic_t lo_pending; + wait_queue_head_t lo_bh_wait; - struct request_queue *lo_queue; + struct request_queue *lo_queue; - const struct lu_env *lo_env; - struct cl_io lo_io; - struct ll_dio_pages lo_pvec; + const struct lu_env *lo_env; + struct cl_io lo_io; + struct ll_dio_pages lo_pvec; - /* data to handle bio for lustre. */ - struct lo_request_data { - struct page *lrd_pages[LLOOP_MAX_SEGMENTS]; - loff_t lrd_offsets[LLOOP_MAX_SEGMENTS]; - } lo_requests[1]; + /* data to handle bio for lustre. */ + struct lo_request_data { + struct page *lrd_pages[LLOOP_MAX_SEGMENTS]; + loff_t lrd_offsets[LLOOP_MAX_SEGMENTS]; + } lo_requests[1]; }; /* @@ -191,14 +188,20 @@ static int do_bio_lustrebacked(struct lloop_device *lo, struct bio *head) { const struct lu_env *env = lo->lo_env; struct cl_io *io = &lo->lo_io; - struct inode *inode = lo->lo_backing_file->f_dentry->d_inode; + struct dentry *de = lo->lo_backing_file->f_path.dentry; + struct inode *inode = de->d_inode; struct cl_object *obj = ll_i2info(inode)->lli_clob; pgoff_t offset; int ret; - int i; +#ifdef HAVE_BVEC_ITER + struct bvec_iter iter; + struct bio_vec bvec; +#else + int iter; + struct bio_vec *bvec; +#endif int rw; - obd_count page_count = 0; - struct bio_vec *bvec; + size_t page_count = 0; struct bio *bio; ssize_t bytes; @@ -221,18 +224,30 @@ static int do_bio_lustrebacked(struct lloop_device *lo, struct bio *head) for (bio = head; bio != NULL; bio = bio->bi_next) { LASSERT(rw == bio->bi_rw); - offset = (pgoff_t)(bio->bi_sector << 9) + lo->lo_offset; - bio_for_each_segment(bvec, bio, i) { - BUG_ON(bvec->bv_offset != 0); - BUG_ON(bvec->bv_len != CFS_PAGE_SIZE); +#ifdef HAVE_BVEC_ITER + offset = (pgoff_t)(bio->bi_iter.bi_sector << 9) + lo->lo_offset; + bio_for_each_segment_all(bvec, bio, iter) { + BUG_ON(bvec.bv_offset != 0); + BUG_ON(bvec.bv_len != PAGE_CACHE_SIZE); - pages[page_count] = bvec->bv_page; - offsets[page_count] = offset; - page_count++; - offset += bvec->bv_len; - } - LASSERT(page_count <= LLOOP_MAX_SEGMENTS); - } + pages[page_count] = bvec.bv_page; + offsets[page_count] = offset; + page_count++; + offset += bvec.bv_len; +#else + offset = (pgoff_t)(bio->bi_sector << 9) + lo->lo_offset; + bio_for_each_segment_all(bvec, bio, iter) { + BUG_ON(bvec->bv_offset != 0); + BUG_ON(bvec->bv_len != PAGE_CACHE_SIZE); + + pages[page_count] = bvec->bv_page; + offsets[page_count] = offset; + page_count++; + offset += bvec->bv_len; +#endif + } + LASSERT(page_count <= LLOOP_MAX_SEGMENTS); + } ll_stats_ops_tally(ll_i2sbi(inode), (rw == WRITE) ? LPROC_LL_BRW_WRITE : LPROC_LL_BRW_READ, @@ -284,9 +299,9 @@ static void loop_add_bio(struct lloop_device *lo, struct bio *bio) lo->lo_bio = lo->lo_biotail = bio; spin_unlock_irqrestore(&lo->lo_lock, flags); - cfs_atomic_inc(&lo->lo_pending); - if (cfs_waitq_active(&lo->lo_bh_wait)) - cfs_waitq_signal(&lo->lo_bh_wait); + atomic_inc(&lo->lo_pending); + if (waitqueue_active(&lo->lo_bh_wait)) + wake_up(&lo->lo_bh_wait); } /* @@ -313,12 +328,17 @@ static unsigned int loop_get_bio(struct lloop_device *lo, struct bio **req) rw = first->bi_rw; bio = &lo->lo_bio; while (*bio && (*bio)->bi_rw == rw) { - CDEBUG(D_INFO, "bio sector %llu size %u count %u vcnt%u \n", - (unsigned long long)(*bio)->bi_sector, (*bio)->bi_size, - page_count, (*bio)->bi_vcnt); - if (page_count + (*bio)->bi_vcnt > LLOOP_MAX_SEGMENTS) - break; - +#ifdef HAVE_BVEC_ITER + CDEBUG(D_INFO, "bio sector %llu size %u count %u vcnt%u \n", + (unsigned long long)(*bio)->bi_iter.bi_sector, + (*bio)->bi_iter.bi_size, page_count, (*bio)->bi_vcnt); +#else + CDEBUG(D_INFO, "bio sector %llu size %u count %u vcnt%u \n", + (unsigned long long)(*bio)->bi_sector, (*bio)->bi_size, + page_count, (*bio)->bi_vcnt); +#endif + if (page_count + (*bio)->bi_vcnt > LLOOP_MAX_SEGMENTS) + break; page_count += (*bio)->bi_vcnt; count++; @@ -348,8 +368,14 @@ loop_make_request(struct request_queue *q, struct bio *old_bio) if (!lo) goto err; - CDEBUG(D_INFO, "submit bio sector %llu size %u\n", - (unsigned long long)old_bio->bi_sector, old_bio->bi_size); +#ifdef HAVE_BVEC_ITER + CDEBUG(D_INFO, "submit bio sector %llu size %u\n", + (unsigned long long)old_bio->bi_iter.bi_sector, + old_bio->bi_iter.bi_size); +#else + CDEBUG(D_INFO, "submit bio sector %llu size %u\n", + (unsigned long long)old_bio->bi_sector, old_bio->bi_size); +#endif spin_lock_irq(&lo->lo_lock); inactive = (lo->lo_state != LLOOP_BOUND); @@ -369,7 +395,7 @@ loop_make_request(struct request_queue *q, struct bio *old_bio) loop_add_bio(lo, old_bio); LL_MRF_RETURN(0); err: - cfs_bio_io_error(old_bio, old_bio->bi_size); + bio_io_error(old_bio); LL_MRF_RETURN(0); } @@ -388,20 +414,27 @@ static void loop_unplug(struct request_queue *q) static inline void loop_handle_bio(struct lloop_device *lo, struct bio *bio) { - int ret; - ret = do_bio_lustrebacked(lo, bio); - while (bio) { - struct bio *tmp = bio->bi_next; - bio->bi_next = NULL; - cfs_bio_endio(bio, bio->bi_size, ret); - bio = tmp; - } + int ret; + + ret = do_bio_lustrebacked(lo, bio); + while (bio) { + struct bio *tmp = bio->bi_next; + + bio->bi_next = NULL; +#ifdef HAVE_BIO_ENDIO_USES_ONE_ARG + bio->bi_error = ret; + bio_endio(bio); +#else + bio_endio(bio, ret); +#endif + bio = tmp; + } } static inline int loop_active(struct lloop_device *lo) { - return cfs_atomic_read(&lo->lo_pending) || - (lo->lo_state == LLOOP_RUNDOWN); + return atomic_read(&lo->lo_pending) || + (lo->lo_state == LLOOP_RUNDOWN); } /* @@ -417,11 +450,9 @@ static int loop_thread(void *data) unsigned long total_count = 0; struct lu_env *env; - int refcheck; + __u16 refcheck; int ret = 0; - daemonize("lloop%d", lo->lo_number); - set_user_nice(current, -20); lo->lo_state = LLOOP_BOUND; @@ -441,8 +472,8 @@ static int loop_thread(void *data) up(&lo->lo_sem); for (;;) { - cfs_wait_event(lo->lo_bh_wait, loop_active(lo)); - if (!cfs_atomic_read(&lo->lo_pending)) { + wait_event(lo->lo_bh_wait, loop_active(lo)); + if (!atomic_read(&lo->lo_pending)) { int exiting = 0; spin_lock_irq(&lo->lo_lock); exiting = (lo->lo_state == LLOOP_RUNDOWN); @@ -465,21 +496,21 @@ static int loop_thread(void *data) } else { times++; } - if ((times & 127) == 0) { - CDEBUG(D_INFO, "total: %lu, count: %lu, avg: %lu\n", - total_count, times, total_count / times); - } - - LASSERT(bio != NULL); - LASSERT(count <= cfs_atomic_read(&lo->lo_pending)); - loop_handle_bio(lo, bio); - cfs_atomic_sub(count, &lo->lo_pending); - } - cl_env_put(env, &refcheck); + if ((times & 127) == 0) { + CDEBUG(D_INFO, "total: %lu, count: %lu, avg: %lu\n", + total_count, times, total_count / times); + } + + LASSERT(bio != NULL); + LASSERT(count <= atomic_read(&lo->lo_pending)); + loop_handle_bio(lo, bio); + atomic_sub(count, &lo->lo_pending); + } + cl_env_put(env, &refcheck); out: up(&lo->lo_sem); - return ret; + return ret; } static int loop_set_fd(struct lloop_device *lo, struct file *unused, @@ -491,8 +522,8 @@ static int loop_set_fd(struct lloop_device *lo, struct file *unused, int error; loff_t size; - if (!cfs_try_module_get(THIS_MODULE)) - return -ENODEV; + if (!try_module_get(THIS_MODULE)) + return -ENODEV; error = -EBUSY; if (lo->lo_state != LLOOP_UNBOUND) @@ -520,11 +551,10 @@ static int loop_set_fd(struct lloop_device *lo, struct file *unused, set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); - lo->lo_blocksize = CFS_PAGE_SIZE; + lo->lo_blocksize = PAGE_CACHE_SIZE; lo->lo_device = bdev; lo->lo_flags = lo_flags; lo->lo_backing_file = file; - lo->ioctl = NULL; lo->lo_sizelimit = 0; lo->old_gfp_mask = mapping_gfp_mask(mapping); mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); @@ -541,34 +571,31 @@ static int loop_set_fd(struct lloop_device *lo, struct file *unused, lo->lo_queue->unplug_fn = loop_unplug; #endif - /* queue parameters */ - CLASSERT(CFS_PAGE_SIZE < (1 << (sizeof(unsigned short) * 8))); - blk_queue_logical_block_size(lo->lo_queue, - (unsigned short)CFS_PAGE_SIZE); - blk_queue_max_hw_sectors(lo->lo_queue, - LLOOP_MAX_SEGMENTS << (CFS_PAGE_SHIFT - 9)); - blk_queue_max_segments(lo->lo_queue, LLOOP_MAX_SEGMENTS); + /* queue parameters */ + blk_queue_max_hw_sectors(lo->lo_queue, + LLOOP_MAX_SEGMENTS << (PAGE_CACHE_SHIFT - 9)); + blk_queue_max_segments(lo->lo_queue, LLOOP_MAX_SEGMENTS); set_capacity(disks[lo->lo_number], size); bd_set_size(bdev, size << 9); - set_blocksize(bdev, lo->lo_blocksize); + set_blocksize(bdev, lo->lo_blocksize); - cfs_create_thread(loop_thread, lo, CLONE_KERNEL); + kthread_run(loop_thread, lo, "lloop%d", lo->lo_number); down(&lo->lo_sem); - return 0; + return 0; - out: - /* This is safe: open() is still holding a reference. */ - cfs_module_put(THIS_MODULE); - return error; +out: + /* This is safe: open() is still holding a reference. */ + module_put(THIS_MODULE); + return error; } static int loop_clr_fd(struct lloop_device *lo, struct block_device *bdev, int count) { struct file *filp = lo->lo_backing_file; - int gfp = lo->old_gfp_mask; + gfp_t gfp = lo->old_gfp_mask; if (lo->lo_state != LLOOP_BOUND) return -ENXIO; @@ -582,35 +609,28 @@ static int loop_clr_fd(struct lloop_device *lo, struct block_device *bdev, spin_lock_irq(&lo->lo_lock); lo->lo_state = LLOOP_RUNDOWN; spin_unlock_irq(&lo->lo_lock); - cfs_waitq_signal(&lo->lo_bh_wait); + wake_up(&lo->lo_bh_wait); down(&lo->lo_sem); lo->lo_backing_file = NULL; - lo->ioctl = NULL; lo->lo_device = NULL; lo->lo_offset = 0; lo->lo_sizelimit = 0; lo->lo_flags = 0; - ll_invalidate_bdev(bdev, 0); + invalidate_bdev(bdev); set_capacity(disks[lo->lo_number], 0); bd_set_size(bdev, 0); mapping_set_gfp_mask(filp->f_mapping, gfp); lo->lo_state = LLOOP_UNBOUND; - fput(filp); - /* This is safe: open() is still holding a reference. */ - cfs_module_put(THIS_MODULE); - return 0; + fput(filp); + /* This is safe: open() is still holding a reference. */ + module_put(THIS_MODULE); + return 0; } -#ifdef HAVE_BLKDEV_PUT_2ARGS static int lo_open(struct block_device *bdev, fmode_t mode) { struct lloop_device *lo = bdev->bd_disk->private_data; -#else -static int lo_open(struct inode *inode, struct file *file) -{ - struct lloop_device *lo = inode->i_bdev->bd_disk->private_data; -#endif mutex_lock(&lo->lo_ctl_mutex); lo->lo_refcnt++; @@ -619,63 +639,57 @@ static int lo_open(struct inode *inode, struct file *file) return 0; } -#ifdef HAVE_BLKDEV_PUT_2ARGS -static int lo_release(struct gendisk *disk, fmode_t mode) -{ - struct lloop_device *lo = disk->private_data; +#ifdef HAVE_BLKDEV_RELEASE_RETURN_INT +static int #else -static int lo_release(struct inode *inode, struct file *file) -{ - struct lloop_device *lo = inode->i_bdev->bd_disk->private_data; +static void #endif +lo_release(struct gendisk *disk, fmode_t mode) +{ + struct lloop_device *lo = disk->private_data; mutex_lock(&lo->lo_ctl_mutex); - --lo->lo_refcnt; + --lo->lo_refcnt; mutex_unlock(&lo->lo_ctl_mutex); - - return 0; +#ifdef HAVE_BLKDEV_RELEASE_RETURN_INT + return 0; +#endif } /* lloop device node's ioctl function. */ -#ifdef HAVE_BLKDEV_PUT_2ARGS static int lo_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct lloop_device *lo = bdev->bd_disk->private_data; - struct inode *inode = NULL; - int err = 0; -#else -static int lo_ioctl(struct inode *inode, struct file *unused, - unsigned int cmd, unsigned long arg) -{ - struct lloop_device *lo = inode->i_bdev->bd_disk->private_data; - struct block_device *bdev = inode->i_bdev; - int err = 0; -#endif + struct lloop_device *lo = bdev->bd_disk->private_data; + int err = 0; mutex_lock(&lloop_mutex); switch (cmd) { case LL_IOC_LLOOP_DETACH: { err = loop_clr_fd(lo, bdev, 2); if (err == 0) - ll_blkdev_put(bdev, 0); /* grabbed in LLOOP_ATTACH */ + blkdev_put(bdev, 0); /* grabbed in LLOOP_ATTACH */ break; } - case LL_IOC_LLOOP_INFO: { - struct lu_fid fid; + case LL_IOC_LLOOP_INFO: { + struct inode *inode; + struct lu_fid fid; - LASSERT(lo->lo_backing_file != NULL); - if (inode == NULL) - inode = lo->lo_backing_file->f_dentry->d_inode; - if (lo->lo_state == LLOOP_BOUND) + if (lo->lo_backing_file == NULL) { + err = -ENOENT; + break; + } + inode = lo->lo_backing_file->f_path.dentry->d_inode; + if (inode != NULL && lo->lo_state == LLOOP_BOUND) fid = ll_i2info(inode)->lli_fid; else fid_zero(&fid); - if (copy_to_user((struct lu_fid *)arg, &fid, sizeof(fid))) - err = -EFAULT; - break; + if (copy_to_user((struct lu_fid __user *)arg, + &fid, sizeof(fid))) + err = -EFAULT; + break; } default: @@ -719,10 +733,11 @@ static enum llioc_iter lloop_ioctl(struct inode *unused, struct file *file, CWARN("Enter llop_ioctl\n"); mutex_lock(&lloop_mutex); - switch (cmd) { - case LL_IOC_LLOOP_ATTACH: { - struct lloop_device *lo_free = NULL; - int i; + switch (cmd) { + case LL_IOC_LLOOP_ATTACH: { + struct inode *inode = file->f_path.dentry->d_inode; + struct lloop_device *lo_free = NULL; + int i; for (i = 0; i < max_loop; i++, lo = NULL) { lo = &loop_dev[i]; @@ -731,19 +746,19 @@ static enum llioc_iter lloop_ioctl(struct inode *unused, struct file *file, lo_free = lo; continue; } - if (lo->lo_backing_file->f_dentry->d_inode == - file->f_dentry->d_inode) - break; - } - if (lo || !lo_free) - GOTO(out, err = -EBUSY); + if (lo->lo_backing_file->f_path.dentry->d_inode == + inode) + break; + } + if (lo || !lo_free) + GOTO(out, err = -EBUSY); lo = lo_free; dev = MKDEV(lloop_major, lo->lo_number); /* quit if the used pointer is writable */ - if (put_user((long)old_encode_dev(dev), (long*)arg)) - GOTO(out, err = -EFAULT); + if (put_user((long)old_encode_dev(dev), (long __user *)arg)) + GOTO(out, err = -EFAULT); bdev = blkdev_get_by_dev(dev, file->f_mode, NULL); if (IS_ERR(bdev)) @@ -753,7 +768,7 @@ static enum llioc_iter lloop_ioctl(struct inode *unused, struct file *file, err = loop_set_fd(lo, NULL, bdev, file); if (err) { fput(file); - ll_blkdev_put(bdev, 0); + blkdev_put(bdev, 0); } break; @@ -777,7 +792,7 @@ static enum llioc_iter lloop_ioctl(struct inode *unused, struct file *file, bdev = lo->lo_device; err = loop_clr_fd(lo, bdev, 1); if (err == 0) - ll_blkdev_put(bdev, 0); /* grabbed in LLOOP_ATTACH */ + blkdev_put(bdev, 0); /* grabbed in LLOOP_ATTACH */ break; } @@ -846,7 +861,7 @@ static int __init lloop_init(void) mutex_init(&lo->lo_ctl_mutex); sema_init(&lo->lo_sem, 0); - cfs_waitq_init(&lo->lo_bh_wait); + init_waitqueue_head(&lo->lo_bh_wait); lo->lo_number = i; spin_lock_init(&lo->lo_lock); disk->major = lloop_major; @@ -879,29 +894,28 @@ out_mem1: return -ENOMEM; } -static void lloop_exit(void) +static void __exit lloop_exit(void) { - int i; + int i; - ll_iocontrol_unregister(ll_iocontrol_magic); - for (i = 0; i < max_loop; i++) { - del_gendisk(disks[i]); - blk_cleanup_queue(loop_dev[i].lo_queue); - put_disk(disks[i]); - } - if (ll_unregister_blkdev(lloop_major, "lloop")) - CWARN("lloop: cannot unregister blkdev\n"); - else - CDEBUG(D_CONFIG, "unregistered lloop major %d\n", lloop_major); + ll_iocontrol_unregister(ll_iocontrol_magic); + for (i = 0; i < max_loop; i++) { + del_gendisk(disks[i]); + blk_cleanup_queue(loop_dev[i].lo_queue); + put_disk(disks[i]); + } + unregister_blkdev(lloop_major, "lloop"); - OBD_FREE(disks, max_loop * sizeof(*disks)); - OBD_FREE(loop_dev, max_loop * sizeof(*loop_dev)); + OBD_FREE(disks, max_loop * sizeof(*disks)); + OBD_FREE(loop_dev, max_loop * sizeof(*loop_dev)); } -module_init(lloop_init); -module_exit(lloop_exit); - -CFS_MODULE_PARM(max_loop, "i", int, 0444, "maximum of lloop_device"); -MODULE_AUTHOR("Sun Microsystems, Inc. "); +module_param(max_loop, int, 0444); +MODULE_PARM_DESC(max_loop, "maximum of lloop_device"); +MODULE_AUTHOR("OpenSFS, Inc. "); MODULE_DESCRIPTION("Lustre virtual block device"); +MODULE_VERSION(LUSTRE_VERSION_STRING); MODULE_LICENSE("GPL"); + +module_init(lloop_init); +module_exit(lloop_exit);