diff --git a/lustre/llite/Makefile.in b/lustre/llite/Makefile.in index fad7b02fd057d039e9de0d8431e49fe314d3e40d..ff06efd3cdcdc47640cc4e3c23f0f09dc22fba6b 100644 --- a/lustre/llite/Makefile.in +++ b/lustre/llite/Makefile.in @@ -1,8 +1,6 @@ -MODULES := lustre llite_lloop +MODULES := lustre lustre-objs := dcache.o dir.o file.o llite_close.o llite_lib.o llite_nfs.o rw.o lproc_llite.o namei.o symlink.o llite_mmap.o xattr.o statahead.o -llite_lloop-objs := lloop.o - ifeq ($(PATCHLEVEL),4) lustre-objs += rw24.o super.o else diff --git a/lustre/llite/file.c b/lustre/llite/file.c index bd173e14bae3fcac90c6815efc92638a72203df1..365c4e34df25761a2b0fea55e20597795df4fc01 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -2236,17 +2236,10 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd, case EXT3_IOC_SETVERSION_OLD: case EXT3_IOC_SETVERSION: */ - default: { - int err; - - if (LLIOC_STOP == - ll_iocontrol_call(inode, file, cmd, arg, &err)) - RETURN(err); - + default: RETURN(obd_iocontrol(cmd, ll_i2obdexp(inode), 0, NULL, (void *)arg)); } - } } loff_t ll_file_seek(struct file *file, loff_t offset, int origin) @@ -2798,102 +2791,3 @@ struct inode_operations ll_file_inode_operations = { .removexattr = ll_removexattr, }; -/* dynamic ioctl number support routins */ -static struct llioc_ctl_data { - struct rw_semaphore ioc_sem; - struct list_head ioc_head; -} llioc = { - __RWSEM_INITIALIZER(llioc.ioc_sem), - CFS_LIST_HEAD_INIT(llioc.ioc_head) -}; - - -struct llioc_data { - struct list_head iocd_list; - unsigned int iocd_size; - llioc_callback_t iocd_cb; - unsigned int iocd_count; - unsigned int iocd_cmd[0]; -}; - -void *ll_iocontrol_register(llioc_callback_t cb, int count, unsigned int *cmd) -{ - unsigned int size; - struct llioc_data *in_data = NULL; - ENTRY; - - if (cb == NULL || cmd == NULL || - count > LLIOC_MAX_CMD || count < 0) - RETURN(NULL); - - size = sizeof(*in_data) + count * sizeof(unsigned int); - OBD_ALLOC(in_data, size); - if (in_data == NULL) - RETURN(NULL); - - memset(in_data, 0, sizeof(*in_data)); - in_data->iocd_size = size; - in_data->iocd_cb = cb; - in_data->iocd_count = count; - memcpy(in_data->iocd_cmd, cmd, sizeof(unsigned int) * count); - - down_write(&llioc.ioc_sem); - list_add_tail(&in_data->iocd_list, &llioc.ioc_head); - up_write(&llioc.ioc_sem); - - RETURN(in_data); -} - -void ll_iocontrol_unregister(void *magic) -{ - struct llioc_data *tmp; - - if (magic == NULL) - return; - - down_write(&llioc.ioc_sem); - list_for_each_entry(tmp, &llioc.ioc_head, iocd_list) { - if (tmp == magic) { - unsigned int size = tmp->iocd_size; - - list_del(&tmp->iocd_list); - up_write(&llioc.ioc_sem); - - OBD_FREE(tmp, size); - return; - } - } - up_write(&llioc.ioc_sem); - - CWARN("didn't find iocontrol register block with magic: %p\n", magic); -} - -EXPORT_SYMBOL(ll_iocontrol_register); -EXPORT_SYMBOL(ll_iocontrol_unregister); - -enum llioc_iter ll_iocontrol_call(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, int *rcp) -{ - enum llioc_iter ret = LLIOC_CONT; - struct llioc_data *data; - int rc = -EINVAL, i; - - down_read(&llioc.ioc_sem); - list_for_each_entry(data, &llioc.ioc_head, iocd_list) { - for (i = 0; i < data->iocd_count; i++) { - if (cmd != data->iocd_cmd[i]) - continue; - - ret = data->iocd_cb(inode, file, cmd, arg, data, &rc); - break; - } - - if (ret == LLIOC_STOP) - break; - } - up_read(&llioc.ioc_sem); - - if (rcp) - *rcp = rc; - return ret; -} diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index e977d0ac97d5c379fff71362514c76441b0f3271..08f0cd14717be94dec0147afbd19411c5dd14db9 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -807,51 +807,4 @@ int ll_statahead_enter(struct inode *dir, struct dentry **dentry, int lookup); void ll_statahead_exit(struct dentry *dentry, int result); void ll_stop_statahead(struct inode *inode); -/* llite ioctl register support rountine */ -#ifdef __KERNEL__ -enum llioc_iter { - LLIOC_CONT = 0, - LLIOC_STOP -}; - -#define LLIOC_MAX_CMD 256 - -/* - * Rules to write a callback function: - * - * Parameters: - * @magic: Dynamic ioctl call routine will feed this vaule with the pointer - * returned to ll_iocontrol_register. Callback functions should use this - * data to check the potential collasion of ioctl cmd. If collasion is - * found, callback function should return LLIOC_CONT. - * @rcp: The result of ioctl command. - * - * Return values: - * If @magic matches the pointer returned by ll_iocontrol_data, the - * callback should return LLIOC_STOP; return LLIOC_STOP otherwise. - */ -typedef enum llioc_iter (*llioc_callback_t)(struct inode *inode, - struct file *file, unsigned int cmd, unsigned long arg, - void *magic, int *rcp); - -enum llioc_iter ll_iocontrol_call(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, int *rcp); - -/* export functions */ -/* Register ioctl block dynamatically for a regular file. - * - * @cmd: the array of ioctl command set - * @count: number of commands in the @cmd - * @cb: callback function, it will be called if an ioctl command is found to - * belong to the command list @cmd. - * - * Return vaule: - * A magic pointer will be returned if success; - * otherwise, NULL will be returned. - * */ -void *ll_iocontrol_register(llioc_callback_t cb, int count, unsigned int *cmd); -void ll_iocontrol_unregister(void *magic); - -#endif - #endif /* LLITE_INTERNAL_H */ diff --git a/lustre/llite/lloop.c b/lustre/llite/lloop.c deleted file mode 100644 index bcba73987a3318868d3039513a8af94d7d1327e4..0000000000000000000000000000000000000000 --- a/lustre/llite/lloop.c +++ /dev/null @@ -1,759 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * Lustre virtual block device emulator. - * - * Copyright (c) 2001-2003 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * linux/drivers/block/loop.c - * - * Written by Theodore Ts'o, 3/29/93 - * - * Copyright 1993 by Theodore Ts'o. Redistribution of this file is - * permitted under the GNU General Public License. - * - * DES encryption plus some minor changes by Werner Almesberger, 30-MAY-1993 - * more DES encryption plus IDEA encryption by Nicholas J. Leon, June 20, 1996 - * - * Modularized and updated for 1.1.16 kernel - Mitch Dsouza 28th May 1994 - * Adapted for 1.3.59 kernel - Andries Brouwer, 1 Feb 1996 - * - * Fixed do_loop_request() re-entrancy - Vincent.Renardias@waw.com Mar 20, 1997 - * - * Added devfs support - Richard Gooch <rgooch@atnf.csiro.au> 16-Jan-1998 - * - * Handle sparse backing files correctly - Kenn Humborg, Jun 28, 1998 - * - * Loadable modules and other fixes by AK, 1998 - * - * Make real block number available to downstream transfer functions, enables - * CBC (and relatives) mode encryption requiring unique IVs per data block. - * Reed H. Petty, rhp@draper.net - * - * Maximum number of loop devices now dynamic via max_loop module parameter. - * Russell Kroll <rkroll@exploits.org> 19990701 - * - * 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 - * - * Completely rewrite request handling to be make_request_fn style and - * non blocking, pushing work to a helper thread. Lots of fixes from - * Al Viro too. - * Jens Axboe <axboe@suse.de>, Nov 2000 - * - * Support up to 256 loop devices - * Heinz Mauelshagen <mge@sistina.com>, Feb 2002 - * - * Support for falling back on the write file operation when the address space - * operations prepare_write and/or commit_write are not available on the - * backing filesystem. - * Anton Altaparmakov, 16 Feb 2005 - * - * Still To Fix: - * - Advisory locking is ignored here. - * - Should use an own CAP_* category instead of CAP_SYS_ADMIN - * - */ - -#include <linux/config.h> -#include <linux/module.h> - -#include <linux/sched.h> -#include <linux/fs.h> -#include <linux/file.h> -#include <linux/stat.h> -#include <linux/errno.h> -#include <linux/major.h> -#include <linux/wait.h> -#include <linux/blkdev.h> -#include <linux/blkpg.h> -#include <linux/init.h> -#include <linux/smp_lock.h> -#include <linux/swap.h> -#include <linux/slab.h> -#include <linux/suspend.h> -#include <linux/writeback.h> -#include <linux/buffer_head.h> /* for invalidate_bdev() */ -#include <linux/completion.h> -#include <linux/highmem.h> -#include <linux/gfp.h> -#include <linux/swap.h> -#include <linux/pagevec.h> - -#include <asm/uaccess.h> - -#include <lustre_lib.h> -#include <lustre_lite.h> -#include "llite_internal.h" - -#define LLOOP_MAX_SEGMENTS PTLRPC_MAX_BRW_PAGES - -/* Possible states of device */ -enum { - LLOOP_UNBOUND, - LLOOP_BOUND, - LLOOP_RUNDOWN, -}; - -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); - - struct file * lo_backing_file; - struct block_device *lo_device; - unsigned lo_blocksize; - - int old_gfp_mask; - - spinlock_t lo_lock; - struct bio *lo_bio; - struct bio *lo_biotail; - int lo_state; - struct semaphore lo_sem; - struct semaphore lo_ctl_mutex; - struct semaphore lo_bh_mutex; - atomic_t lo_pending; - - request_queue_t *lo_queue; - - /* data to handle bio for lustre. */ - struct lo_request_data { - struct brw_page lrd_pages[LLOOP_MAX_SEGMENTS]; - struct obdo lrd_oa; - } lo_requests[1]; - -}; - -/* - * Loop flags - */ -enum { - LO_FLAGS_READ_ONLY = 1, -}; - -static int lloop_major; -static int max_loop = 8; -static struct lloop_device *loop_dev; -static struct gendisk **disks; -static struct semaphore lloop_mutex; -static void *ll_iocontrol_magic = NULL; - -static loff_t get_loop_size(struct lloop_device *lo, struct file *file) -{ - loff_t size, offset, loopsize; - - /* Compute loopsize in bytes */ - size = i_size_read(file->f_mapping->host); - offset = lo->lo_offset; - loopsize = size - offset; - if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize) - loopsize = lo->lo_sizelimit; - - /* - * Unfortunately, if we want to do I/O on the device, - * the number of 512-byte sectors has to fit into a sector_t. - */ - return loopsize >> 9; -} - -static int do_bio_filebacked(struct lloop_device *lo, struct bio *bio) -{ - struct inode *inode = lo->lo_backing_file->f_dentry->d_inode; - struct ll_inode_info *lli = ll_i2info(inode); - struct lov_stripe_md *lsm = lli->lli_smd; - struct obd_info oinfo = {{{0}}}; - struct brw_page *pg = lo->lo_requests[0].lrd_pages; - struct obdo *oa = &lo->lo_requests[0].lrd_oa; - pgoff_t offset; - int ret, cmd, i; - struct bio_vec *bvec; - - BUG_ON(bio->bi_hw_segments > LLOOP_MAX_SEGMENTS); - - 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); - - pg->pg = bvec->bv_page; - pg->off = offset; - pg->count = bvec->bv_len; - pg->flag = OBD_BRW_SRVLOCK; - - pg++; - offset += bvec->bv_len; - } - - oa->o_mode = inode->i_mode; - oa->o_id = lsm->lsm_object_id; - oa->o_valid = OBD_MD_FLID | OBD_MD_FLMODE | OBD_MD_FLTYPE; - obdo_from_inode(oa, inode, OBD_MD_FLFID | OBD_MD_FLGENER); - - cmd = OBD_BRW_READ; - if (bio_rw(bio) == WRITE) - cmd = OBD_BRW_WRITE; - - if (cmd == OBD_BRW_WRITE) - ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_BRW_WRITE, bio->bi_size); - else - ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_BRW_READ, bio->bi_size); - oinfo.oi_oa = oa; - oinfo.oi_md = lsm; - ret = obd_brw(cmd, ll_i2obdexp(inode), &oinfo, - (obd_count)(i - bio->bi_idx), - lo->lo_requests[0].lrd_pages, NULL); - if (ret == 0) - obdo_to_inode(inode, oa, OBD_MD_FLBLOCKS); - return ret; -} - - -/* - * Add bio to back of pending list - */ -static void loop_add_bio(struct lloop_device *lo, struct bio *bio) -{ - unsigned long flags; - - spin_lock_irqsave(&lo->lo_lock, flags); - if (lo->lo_biotail) { - lo->lo_biotail->bi_next = bio; - lo->lo_biotail = bio; - } else - lo->lo_bio = lo->lo_biotail = bio; - spin_unlock_irqrestore(&lo->lo_lock, flags); - - up(&lo->lo_bh_mutex); -} - -/* - * Grab first pending buffer - */ -static struct bio *loop_get_bio(struct lloop_device *lo) -{ - struct bio *bio; - - spin_lock_irq(&lo->lo_lock); - if ((bio = lo->lo_bio)) { - if (bio == lo->lo_biotail) - lo->lo_biotail = NULL; - lo->lo_bio = bio->bi_next; - bio->bi_next = NULL; - } - spin_unlock_irq(&lo->lo_lock); - - return bio; -} - -static int loop_make_request(request_queue_t *q, struct bio *old_bio) -{ - struct lloop_device *lo = q->queuedata; - int rw = bio_rw(old_bio); - - if (!lo) - goto out; - - spin_lock_irq(&lo->lo_lock); - if (lo->lo_state != LLOOP_BOUND) - goto inactive; - atomic_inc(&lo->lo_pending); - spin_unlock_irq(&lo->lo_lock); - - if (rw == WRITE) { - if (lo->lo_flags & LO_FLAGS_READ_ONLY) - goto err; - } else if (rw == READA) { - rw = READ; - } else if (rw != READ) { - CERROR("lloop: unknown command (%x)\n", rw); - goto err; - } - loop_add_bio(lo, old_bio); - return 0; -err: - if (atomic_dec_and_test(&lo->lo_pending)) - up(&lo->lo_bh_mutex); -out: - bio_io_error(old_bio, old_bio->bi_size); - return 0; -inactive: - spin_unlock_irq(&lo->lo_lock); - goto out; -} - -/* - * kick off io on the underlying address space - */ -static void loop_unplug(request_queue_t *q) -{ - struct lloop_device *lo = q->queuedata; - - clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags); - blk_run_address_space(lo->lo_backing_file->f_mapping); -} - -static inline void loop_handle_bio(struct lloop_device *lo, struct bio *bio) -{ - int ret; - ret = do_bio_filebacked(lo, bio); - bio_endio(bio, bio->bi_size, ret); -} - -/* - * worker thread that handles reads/writes to file backed loop devices, - * to avoid blocking in our make_request_fn. it also does loop decrypting - * on reads for block backed loop, as that is too heavy to do from - * b_end_io context where irqs may be disabled. - */ -static int loop_thread(void *data) -{ - struct lloop_device *lo = data; - struct bio *bio; - - daemonize("lloop%d", lo->lo_number); - - set_user_nice(current, -20); - - lo->lo_state = LLOOP_BOUND; - atomic_inc(&lo->lo_pending); - - /* - * up sem, we are running - */ - up(&lo->lo_sem); - - for (;;) { - down_interruptible(&lo->lo_bh_mutex); - /* - * could be upped because of tear-down, not because of - * pending work - */ - if (!atomic_read(&lo->lo_pending)) - break; - - bio = loop_get_bio(lo); - if (!bio) { - CWARN("lloop(minor: %d): missing bio\n", lo->lo_number); - continue; - } - loop_handle_bio(lo, bio); - - /* - * upped both for pending work and tear-down, lo_pending - * will hit zero then - */ - if (atomic_dec_and_test(&lo->lo_pending)) - break; - } - - up(&lo->lo_sem); - return 0; -} - -static int loop_set_fd(struct lloop_device *lo, struct file *unused, - struct block_device *bdev, struct file *file) -{ - struct inode *inode; - struct address_space *mapping; - int lo_flags = 0; - int error; - loff_t size; - - if (!try_module_get(THIS_MODULE)) - return -ENODEV; - - error = -EBUSY; - if (lo->lo_state != LLOOP_UNBOUND) - goto out; - - mapping = file->f_mapping; - inode = mapping->host; - - error = -EINVAL; - if (!S_ISREG(inode->i_mode) || inode->i_sb->s_magic != LL_SUPER_MAGIC) - goto out; - - if (!(file->f_mode & FMODE_WRITE)) - lo_flags |= LO_FLAGS_READ_ONLY; - - size = get_loop_size(lo, file); - - if ((loff_t)(sector_t)size != size) { - error = -EFBIG; - goto out; - } - - /* remove all pages in cache so as dirty pages not to be existent. */ - truncate_inode_pages(mapping, 0); - - set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); - - lo->lo_blocksize = CFS_PAGE_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)); - - lo->lo_bio = lo->lo_biotail = NULL; - - /* - * set queue make_request_fn, and add limits based on lower level - * device - */ - blk_queue_make_request(lo->lo_queue, loop_make_request); - lo->lo_queue->queuedata = lo; - lo->lo_queue->unplug_fn = loop_unplug; - - /* queue parameters */ - blk_queue_hardsect_size(lo->lo_queue, CFS_PAGE_SIZE); - blk_queue_max_sectors(lo->lo_queue, LLOOP_MAX_SEGMENTS); - blk_queue_max_phys_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); - - kernel_thread(loop_thread, lo, CLONE_KERNEL); - down(&lo->lo_sem); - return 0; - - 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; - - if (lo->lo_state != LLOOP_BOUND) - return -ENXIO; - - if (lo->lo_refcnt > count) /* we needed one fd for the ioctl */ - return -EBUSY; - - if (filp == NULL) - return -EINVAL; - - spin_lock_irq(&lo->lo_lock); - lo->lo_state = LLOOP_RUNDOWN; - if (atomic_dec_and_test(&lo->lo_pending)) - up(&lo->lo_bh_mutex); - spin_unlock_irq(&lo->lo_lock); - - 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; - invalidate_bdev(bdev, 0); - 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. */ - module_put(THIS_MODULE); - return 0; -} - -static int lo_open(struct inode *inode, struct file *file) -{ - struct lloop_device *lo = inode->i_bdev->bd_disk->private_data; - - down(&lo->lo_ctl_mutex); - lo->lo_refcnt++; - up(&lo->lo_ctl_mutex); - - return 0; -} - -static int lo_release(struct inode *inode, struct file *file) -{ - struct lloop_device *lo = inode->i_bdev->bd_disk->private_data; - - down(&lo->lo_ctl_mutex); - --lo->lo_refcnt; - up(&lo->lo_ctl_mutex); - - return 0; -} - -/* lloop device node's ioctl function. */ -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; - - down(&lloop_mutex); - switch (cmd) { - case LL_IOC_LLOOP_DETACH: { - err = loop_clr_fd(lo, bdev, 2); - if (err == 0) - blkdev_put(bdev); /* grabbed in LLOOP_ATTACH */ - break; - } - - case LL_IOC_LLOOP_INFO: { - __u64 ino = 0; - - if (lo->lo_state == LLOOP_BOUND) - ino = lo->lo_backing_file->f_dentry->d_inode->i_ino; - - if (put_user(ino, (__u64 *)arg)) - err = -EFAULT; - break; - } - - default: - err = -EINVAL; - break; - } - up(&lloop_mutex); - - return err; -} - -static struct block_device_operations lo_fops = { - .owner = THIS_MODULE, - .open = lo_open, - .release = lo_release, - .ioctl = lo_ioctl, -}; - -/* dynamic iocontrol callback. - * This callback is registered in lloop_init and will be called by - * ll_iocontrol_call. - * This is a llite regular file ioctl function. It takes the responsibility - * of attaching a file, and detaching a file by a lloop's device numner. - */ -static enum llioc_iter lloop_ioctl(struct inode *unused, struct file *file, - unsigned int cmd, unsigned long arg, - void *magic, int *rcp) -{ - struct lloop_device *lo = NULL; - struct block_device *bdev = NULL; - int err = 0; - dev_t dev; - - if (magic != ll_iocontrol_magic) - return LLIOC_CONT; - - if (disks == NULL) - GOTO(out1, err = -ENODEV); - - down(&lloop_mutex); - switch (cmd) { - case LL_IOC_LLOOP_ATTACH: { - struct lloop_device *lo_free = NULL; - int i; - - for (i = 0; i < max_loop; i++, lo = NULL) { - lo = &loop_dev[i]; - if (lo->lo_state == LLOOP_UNBOUND) { - if (!lo_free) - 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); - - 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); - - bdev = open_by_devnum(dev, file->f_mode); - if (IS_ERR(bdev)) - GOTO(out, err = PTR_ERR(bdev)); - - get_file(file); - err = loop_set_fd(lo, NULL, bdev, file); - if (err) { - fput(file); - blkdev_put(bdev); - } - - break; - } - - case LL_IOC_LLOOP_DETACH_BYDEV: { - int minor; - - dev = old_decode_dev(arg); - if (MAJOR(dev) != lloop_major) - GOTO(out, err = -EINVAL); - - minor = MINOR(dev); - if (minor > max_loop - 1) - GOTO(out, err = -EINVAL); - - lo = &loop_dev[minor]; - if (lo->lo_state != LLOOP_BOUND) - GOTO(out, err = -EINVAL); - - bdev = lo->lo_device; - err = loop_clr_fd(lo, bdev, 1); - if (err == 0) - blkdev_put(bdev); /* grabbed in LLOOP_ATTACH */ - - break; - } - - default: - err = -EINVAL; - break; - } - -out: - up(&lloop_mutex); -out1: - if (rcp) - *rcp = err; - return LLIOC_STOP; -} - -static int __init lloop_init(void) -{ - int i; - unsigned int cmdlist[] = { - LL_IOC_LLOOP_ATTACH, - LL_IOC_LLOOP_DETACH_BYDEV, - }; - - if (max_loop < 1 || max_loop > 256) { - CWARN("lloop: invalid max_loop (must be between" - " 1 and 256), using default (8)\n"); - max_loop = 8; - } - - lloop_major = register_blkdev(0, "lloop"); - if (lloop_major < 0) - return -EIO; - - ll_iocontrol_magic = ll_iocontrol_register(lloop_ioctl, 2, cmdlist); - if (ll_iocontrol_magic == NULL) - goto out_mem1; - - loop_dev = kmalloc(max_loop * sizeof(struct lloop_device), GFP_KERNEL); - if (!loop_dev) - goto out_mem1; - memset(loop_dev, 0, max_loop * sizeof(struct lloop_device)); - - disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL); - if (!disks) - goto out_mem2; - - for (i = 0; i < max_loop; i++) { - disks[i] = alloc_disk(1); - if (!disks[i]) - goto out_mem3; - } - - init_MUTEX(&lloop_mutex); - - for (i = 0; i < max_loop; i++) { - struct lloop_device *lo = &loop_dev[i]; - struct gendisk *disk = disks[i]; - - memset(lo, 0, sizeof(*lo)); - 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); - lo->lo_number = i; - spin_lock_init(&lo->lo_lock); - disk->major = lloop_major; - disk->first_minor = i; - disk->fops = &lo_fops; - sprintf(disk->disk_name, "lloop%d", i); - disk->private_data = lo; - disk->queue = lo->lo_queue; - } - - /* We cannot fail after we call this, so another loop!*/ - for (i = 0; i < max_loop; i++) - add_disk(disks[i]); - return 0; - -out_mem4: - while (i--) - blk_put_queue(loop_dev[i].lo_queue); - i = max_loop; -out_mem3: - while (i--) - put_disk(disks[i]); - kfree(disks); -out_mem2: - kfree(loop_dev); -out_mem1: - unregister_blkdev(lloop_major, "lloop"); - ll_iocontrol_unregister(ll_iocontrol_magic); - CERROR("lloop: ran out of memory\n"); - return -ENOMEM; -} - -static void lloop_exit(void) -{ - int i; - - ll_iocontrol_unregister(ll_iocontrol_magic); - for (i = 0; i < max_loop; i++) { - del_gendisk(disks[i]); - blk_put_queue(loop_dev[i].lo_queue); - put_disk(disks[i]); - } - if (unregister_blkdev(lloop_major, "lloop")) - CWARN("lloop: cannot unregister blkdev\n"); - - kfree(disks); - kfree(loop_dev); -} - -module_init(lloop_init); -module_exit(lloop_exit); - -CFS_MODULE_PARM(max_loop, "i", int, 0444, "maximum of lloop_device"); diff --git a/lustre/llite/lproc_llite.c b/lustre/llite/lproc_llite.c index 47af372108342968559273f725bce7ded933ca30..29ccf1513ae9096a9f5bf8d829e8a307e954b09a 100644 --- a/lustre/llite/lproc_llite.c +++ b/lustre/llite/lproc_llite.c @@ -615,7 +615,6 @@ void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count) sbi->ll_stats_track_id == current->gid) lprocfs_counter_add(sbi->ll_stats, op, count); } -EXPORT_SYMBOL(ll_stats_ops_tally); int lprocfs_register_mountpoint(struct proc_dir_entry *parent, struct super_block *sb, char *osc, char *mdc)