diff -u -r linux-2.4.19-rc3.orig/drivers/md/lvm-fs.c linux-2.4.19-rc3/drivers/md/lvm-fs.c --- linux-2.4.19-rc3.orig/drivers/md/lvm-fs.c Thu Jul 25 13:05:13 2002 +++ linux-2.4.19-rc3/drivers/md/lvm-fs.c Thu Jul 25 13:46:01 2002 @@ -1,9 +1,10 @@ /* * kernel/lvm-fs.c * - * Copyright (C) 2001 Sistina Software + * Copyright (C) 2001-2002 Sistina Software * - * January-April 2001 + * January-May,December 2001 + * May 2002 * * LVM driver is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -108,6 +109,9 @@ void lvm_fs_create_vg(vg_t *vg_ptr) { struct proc_dir_entry *pde; + if (!vg_ptr) + return; + vg_devfs_handle[vg_ptr->vg_number] = devfs_mk_dir(0, vg_ptr->vg_name, NULL); @@ -135,22 +139,24 @@ void lvm_fs_remove_vg(vg_t *vg_ptr) { int i; + if (!vg_ptr) + return; + devfs_unregister(ch_devfs_handle[vg_ptr->vg_number]); ch_devfs_handle[vg_ptr->vg_number] = NULL; - /* remove pv's */ - for(i = 0; i < vg_ptr->pv_max; i++) - if(vg_ptr->pv[i]) lvm_fs_remove_pv(vg_ptr, vg_ptr->pv[i]); - /* remove lv's */ for(i = 0; i < vg_ptr->lv_max; i++) if(vg_ptr->lv[i]) lvm_fs_remove_lv(vg_ptr, vg_ptr->lv[i]); - /* must not remove directory before leaf nodes */ devfs_unregister(vg_devfs_handle[vg_ptr->vg_number]); vg_devfs_handle[vg_ptr->vg_number] = NULL; + /* remove pv's */ + for(i = 0; i < vg_ptr->pv_max; i++) + if(vg_ptr->pv[i]) lvm_fs_remove_pv(vg_ptr, vg_ptr->pv[i]); + if(vg_ptr->vg_dir_pde) { remove_proc_entry(LVM_LV_SUBDIR, vg_ptr->vg_dir_pde); vg_ptr->lv_subdir_pde = NULL; @@ -174,7 +180,12 @@ devfs_handle_t lvm_fs_create_lv(vg_t *vg_ptr, lv_t *lv) { struct proc_dir_entry *pde; - const char *name = _basename(lv->lv_name); + const char *name; + + if (!vg_ptr || !lv) + return NULL; + + name = _basename(lv->lv_name); lv_devfs_handle[MINOR(lv->lv_dev)] = devfs_register( vg_devfs_handle[vg_ptr->vg_number], name, @@ -191,6 +202,10 @@ } void lvm_fs_remove_lv(vg_t *vg_ptr, lv_t *lv) { + + if (!vg_ptr || !lv) + return; + devfs_unregister(lv_devfs_handle[MINOR(lv->lv_dev)]); lv_devfs_handle[MINOR(lv->lv_dev)] = NULL; @@ -219,6 +234,9 @@ struct proc_dir_entry *pde; char name[NAME_LEN]; + if (!vg_ptr || !pv) + return; + if(!vg_ptr->pv_subdir_pde) return; @@ -232,6 +250,9 @@ void lvm_fs_remove_pv(vg_t *vg_ptr, pv_t *pv) { char name[NAME_LEN]; + if (!vg_ptr || !pv) + return; + if(!vg_ptr->pv_subdir_pde) return; diff -u -r linux-2.4.19-rc3.orig/drivers/md/lvm-internal.h linux-2.4.19-rc3/drivers/md/lvm-internal.h --- linux-2.4.19-rc3.orig/drivers/md/lvm-internal.h Thu Jul 25 13:05:13 2002 +++ linux-2.4.19-rc3/drivers/md/lvm-internal.h Thu Jul 25 13:46:01 2002 @@ -49,6 +49,10 @@ extern vg_t *vg[]; extern struct file_operations lvm_chr_fops; +#ifndef uchar +typedef unsigned char uchar; +#endif + extern struct block_device_operations lvm_blk_dops; #define lvm_sectsize(dev) get_hardsect_size(dev) diff -u -r linux-2.4.19-rc3.orig/drivers/md/lvm-snap.c linux-2.4.19-rc3/drivers/md/lvm-snap.c --- linux-2.4.19-rc3.orig/drivers/md/lvm-snap.c Thu Jul 25 13:05:13 2002 +++ linux-2.4.19-rc3/drivers/md/lvm-snap.c Thu Jul 25 13:46:01 2002 @@ -2,7 +2,7 @@ * kernel/lvm-snap.c * * Copyright (C) 2000 Andrea Arcangeli SuSE - * 2000 - 2001 Heinz Mauelshagen, Sistina Software + * 2000 - 2002 Heinz Mauelshagen, Sistina Software * * LVM snapshot driver is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,6 +41,7 @@ * lvm_snapshot_fill_COW_table has a return value too. * 15/10/2001 - fix snapshot alignment problem [CM] * - fix snapshot full oops (always check lv_block_exception) [CM] + * 26/06/2002 - support for new list_move macro [patch@luckynet.dynu.com] * */ @@ -125,8 +126,11 @@ if (i) { /* fun, isn't it? :) */ +#ifdef list_move + list_move(next, hash_table); +#else list_del(next); - list_add(next, hash_table); +#endif list_add(next, hash_table); } ret = exception; break; diff -u -r linux-2.4.19-rc3.orig/drivers/md/lvm.c linux-2.4.19-rc3/drivers/md/lvm.c --- linux-2.4.19-rc3.orig/drivers/md/lvm.c Thu Jul 25 13:05:13 2002 +++ linux-2.4.19-rc3/drivers/md/lvm.c Thu Jul 25 13:46:01 2002 @@ -1,13 +1,14 @@ /* * kernel/lvm.c * - * Copyright (C) 1997 - 2001 Heinz Mauelshagen, Sistina Software + * Copyright (C) 1997 - 2002 Heinz Mauelshagen, Sistina Software * * February-November 1997 * April-May,July-August,November 1998 * January-March,May,July,September,October 1999 * January,February,July,September-November 2000 - * January-April 2001 + * January-May,June,October 2001 + * May-July 2002 * * * LVM driver is free software; you can redistribute it and/or modify @@ -214,6 +215,11 @@ * in the LV each time. [AED] * 12/10/2001 - Use add/del_gendisk() routines in 2.4.10+ * 01/11/2001 - Backport read_ahead change from Linus kernel [AED] + * 24/05/2002 - fixed locking bug in lvm_do_le_remap() introduced with 1.0.4 + * 13/06/2002 - use blk_ioctl() to support various standard block ioctls + * - support HDIO_GETGEO_BIG ioctl + * 05/07/2002 - fixed OBO error on vg array access [benh@kernel.crashing.org] + * 22/07/2002 - streamlined blk_ioctl() call * */ @@ -277,14 +283,13 @@ /* * External function prototypes */ -static int lvm_make_request_fn(request_queue_t *, int, - struct buffer_head *); +static int lvm_make_request_fn(request_queue_t*, int, struct buffer_head*); static int lvm_blk_ioctl(struct inode *, struct file *, uint, ulong); static int lvm_blk_open(struct inode *, struct file *); static int lvm_blk_close(struct inode *, struct file *); -static int lvm_get_snapshot_use_rate(lv_t * lv_ptr, void *arg); +static int lvm_get_snapshot_use_rate(lv_t *lv_ptr, void *arg); static int lvm_user_bmap(struct inode *, struct lv_bmap *); static int lvm_chr_open(struct inode *, struct file *); @@ -314,13 +319,13 @@ static int lvm_do_lv_extend_reduce(int, char *, lv_t *); static int lvm_do_lv_remove(int, char *, int); static int lvm_do_lv_rename(vg_t *, lv_req_t *, lv_t *); -static int lvm_do_lv_status_byname(vg_t * r, void *); +static int lvm_do_lv_status_byname(vg_t *r, void *); static int lvm_do_lv_status_byindex(vg_t *, void *); static int lvm_do_lv_status_bydev(vg_t *, void *); -static int lvm_do_pe_lock_unlock(vg_t * r, void *); +static int lvm_do_pe_lock_unlock(vg_t *r, void *); -static int lvm_do_pv_change(vg_t *, void *); +static int lvm_do_pv_change(vg_t*, void*); static int lvm_do_pv_status(vg_t *, void *); static int lvm_do_pv_flush(void *); @@ -330,15 +335,15 @@ static int lvm_do_vg_rename(vg_t *, void *); static int lvm_do_vg_remove(int); static void lvm_geninit(struct gendisk *); -static void __update_hardsectsize(lv_t * lv); +static void __update_hardsectsize(lv_t *lv); static void _queue_io(struct buffer_head *bh, int rw); static struct buffer_head *_dequeue_io(void); static void _flush_io(struct buffer_head *bh); -static int _open_pv(pv_t * pv); -static void _close_pv(pv_t * pv); +static int _open_pv(pv_t *pv); +static void _close_pv(pv_t *pv); static unsigned long _sectors_to_k(unsigned long sect); @@ -349,22 +354,20 @@ /* variables */ -char *lvm_version = - "LVM version " LVM_RELEASE_NAME "(" LVM_RELEASE_DATE ")"; +char *lvm_version = "LVM version "LVM_RELEASE_NAME"("LVM_RELEASE_DATE")"; ushort lvm_iop_version = LVM_DRIVER_IOP_VERSION; int loadtime = 0; const char *const lvm_name = LVM_NAME; /* volume group descriptor area pointers */ -vg_t *vg[ABS_MAX_VG]; +vg_t *vg[ABS_MAX_VG + 1]; /* map from block minor number to VG and LV numbers */ -typedef struct { +static struct { int vg_number; int lv_number; -} vg_lv_map_t; -static vg_lv_map_t vg_lv_map[ABS_MAX_LV]; +} vg_lv_map[ABS_MAX_LV]; /* Request structures (lvm_chr_ioctl()) */ @@ -394,17 +397,19 @@ struct file_operations lvm_chr_fops = { - open:lvm_chr_open, - release:lvm_chr_close, - ioctl:lvm_chr_ioctl, + owner: THIS_MODULE, + open: lvm_chr_open, + release: lvm_chr_close, + ioctl: lvm_chr_ioctl, }; /* block device operations structure needed for 2.3.38? and above */ -struct block_device_operations lvm_blk_dops = { - owner:THIS_MODULE, - open:lvm_blk_open, - release:lvm_blk_close, - ioctl:lvm_blk_ioctl, +struct block_device_operations lvm_blk_dops = +{ + owner: THIS_MODULE, + open: lvm_blk_open, + release: lvm_blk_close, + ioctl: lvm_blk_ioctl, }; @@ -414,14 +419,15 @@ static int lvm_hardsectsizes[MAX_LV]; static int lvm_size[MAX_LV]; -static struct gendisk lvm_gendisk = { - major:MAJOR_NR, - major_name:LVM_NAME, - minor_shift:0, - max_p:1, - part:lvm_hd_struct, - sizes:lvm_size, - nr_real:MAX_LV, +static struct gendisk lvm_gendisk = +{ + major: MAJOR_NR, + major_name: LVM_NAME, + minor_shift: 0, + max_p: 1, + part: lvm_hd_struct, + sizes: lvm_size, + nr_real: MAX_LV, }; @@ -458,8 +464,7 @@ lvm_hd_name_ptr = lvm_hd_name; #endif - blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), - lvm_make_request_fn); + blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), lvm_make_request_fn); /* initialise the pe lock */ @@ -477,7 +482,7 @@ #endif return 0; -} /* lvm_init() */ +} /* lvm_init() */ /* * cleanup... @@ -510,12 +515,11 @@ lvm_fin_fs(); #ifdef MODULE - printk(KERN_INFO "%s -- Module successfully deactivated\n", - lvm_name); + printk(KERN_INFO "%s -- Module successfully deactivated\n", lvm_name); #endif return; -} /* lvm_cleanup() */ +} /* lvm_cleanup() */ /* * support function to initialize lvm variables @@ -534,7 +538,7 @@ pe_lock_req.data.pv_offset = 0; /* Initialize VG pointers */ - for (v = 0; v < ABS_MAX_VG; v++) + for (v = 0; v < ABS_MAX_VG + 1; v++) vg[v] = NULL; /* Initialize LV -> VG association */ @@ -545,7 +549,7 @@ } return; -} /* lvm_init_vars() */ +} /* lvm_init_vars() */ /******************************************************************** @@ -568,15 +572,13 @@ minor, VG_CHR(minor), MODE_TO_STR(file->f_mode), lock); /* super user validation */ - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; + if (!capable(CAP_SYS_ADMIN)) return -EACCES; /* Group special file open */ - if (VG_CHR(minor) > MAX_VG) - return -ENXIO; + if (VG_CHR(minor) > MAX_VG) return -ENXIO; spin_lock(&lvm_lock); - if (lock == current->pid) + if(lock == current->pid) _lock_open_count++; spin_unlock(&lvm_lock); @@ -585,7 +587,7 @@ MOD_INC_USE_COUNT; return 0; -} /* lvm_chr_open() */ +} /* lvm_chr_open() */ /* @@ -602,19 +604,16 @@ uint extendable, l, v; void *arg = (void *) a; lv_t lv; - vg_t *vg_ptr = vg[VG_CHR(minor)]; + vg_t* vg_ptr = vg[VG_CHR(minor)]; /* otherwise cc will complain about unused variables */ (void) lvm_lock; - P_IOCTL - ("chr MINOR: %d command: 0x%X arg: %p VG#: %d mode: %s%s\n", - minor, command, arg, VG_CHR(minor), - MODE_TO_STR(file->f_mode)); + P_IOCTL("chr MINOR: %d command: 0x%X arg: %p VG#: %d mode: %s%s\n", + minor, command, arg, VG_CHR(minor), MODE_TO_STR(file->f_mode)); #ifdef LVM_TOTAL_RESET - if (lvm_reset_spindown > 0) - return -EACCES; + if (lvm_reset_spindown > 0) return -EACCES; #endif /* Main command switch */ @@ -626,8 +625,8 @@ case LVM_GET_IOP_VERSION: /* check lvm version to ensure driver/tools+lib interoperability */ - if (copy_to_user(arg, &lvm_iop_version, sizeof(ushort)) != - 0) return -EFAULT; + if (copy_to_user(arg, &lvm_iop_version, sizeof(ushort)) != 0) + return -EFAULT; return 0; #ifdef LVM_TOTAL_RESET @@ -635,8 +634,7 @@ /* lock reset function */ lvm_reset_spindown = 1; for (v = 0; v < ABS_MAX_VG; v++) { - if (vg[v] != NULL) - lvm_do_vg_remove(v); + if (vg[v] != NULL) lvm_do_vg_remove(v); } #ifdef MODULE @@ -644,28 +642,28 @@ MOD_INC_USE_COUNT; while (GET_USE_COUNT(&__this_module) > 1) MOD_DEC_USE_COUNT; -#endif /* MODULE */ +#endif /* MODULE */ lock = 0; /* release lock */ wake_up_interruptible(&lvm_wait); return 0; -#endif /* LVM_TOTAL_RESET */ +#endif /* LVM_TOTAL_RESET */ case LE_REMAP: /* remap a logical extent (after moving the physical extent) */ - return lvm_do_le_remap(vg_ptr, arg); + return lvm_do_le_remap(vg_ptr,arg); case PE_LOCK_UNLOCK: /* lock/unlock i/o to a physical extent to move it to another physical volume (move's done in user space's pvmove) */ - return lvm_do_pe_lock_unlock(vg_ptr, arg); + return lvm_do_pe_lock_unlock(vg_ptr,arg); case VG_CREATE_OLD: /* create a VGDA */ return lvm_do_vg_create(arg, minor); case VG_CREATE: - /* create a VGDA, assume VG number is filled in */ + /* create a VGDA, assume VG number is filled in */ return lvm_do_vg_create(arg, -1); case VG_EXTEND: @@ -687,10 +685,9 @@ case VG_SET_EXTENDABLE: /* set/clear extendability flag of volume group */ - if (vg_ptr == NULL) - return -ENXIO; - if (copy_from_user(&extendable, arg, sizeof(extendable)) != - 0) return -EFAULT; + if (vg_ptr == NULL) return -ENXIO; + if (copy_from_user(&extendable, arg, sizeof(extendable)) != 0) + return -EFAULT; if (extendable == VG_EXTENDABLE || extendable == ~VG_EXTENDABLE) { @@ -698,15 +695,13 @@ vg_ptr->vg_status |= VG_EXTENDABLE; else vg_ptr->vg_status &= ~VG_EXTENDABLE; - } else - return -EINVAL; + } else return -EINVAL; return 0; case VG_STATUS: /* get volume group data (only the vg_t struct) */ - if (vg_ptr == NULL) - return -ENXIO; + if (vg_ptr == NULL) return -ENXIO; if (copy_to_user(arg, vg_ptr, sizeof(vg_t)) != 0) return -EFAULT; return 0; @@ -739,25 +734,21 @@ case LV_REMOVE: case LV_RENAME: /* create, extend, reduce, remove or rename a logical volume */ - if (vg_ptr == NULL) - return -ENXIO; + if (vg_ptr == NULL) return -ENXIO; if (copy_from_user(&lv_req, arg, sizeof(lv_req)) != 0) return -EFAULT; if (command != LV_REMOVE) { - if (copy_from_user(&lv, lv_req.lv, sizeof(lv_t)) != - 0) return -EFAULT; + if (copy_from_user(&lv, lv_req.lv, sizeof(lv_t)) != 0) + return -EFAULT; } switch (command) { case LV_CREATE: - return lvm_do_lv_create(minor, lv_req.lv_name, - &lv); + return lvm_do_lv_create(minor, lv_req.lv_name, &lv); case LV_EXTEND: case LV_REDUCE: - return lvm_do_lv_extend_reduce(minor, - lv_req.lv_name, - &lv); + return lvm_do_lv_extend_reduce(minor, lv_req.lv_name, &lv); case LV_REMOVE: return lvm_do_lv_remove(minor, lv_req.lv_name, -1); @@ -785,12 +776,12 @@ case PV_CHANGE: /* change a physical volume */ - return lvm_do_pv_change(vg_ptr, arg); + return lvm_do_pv_change(vg_ptr,arg); case PV_STATUS: /* get physical volume data (pv_t structure only) */ - return lvm_do_pv_status(vg_ptr, arg); + return lvm_do_pv_status(vg_ptr,arg); case PV_FLUSH: @@ -802,11 +793,11 @@ printk(KERN_WARNING "%s -- lvm_chr_ioctl: unknown command 0x%x\n", lvm_name, command); - return -EINVAL; + return -ENOTTY; } return 0; -} /* lvm_chr_ioctl */ +} /* lvm_chr_ioctl */ /* @@ -824,14 +815,12 @@ } #endif - if (lvm_chr_open_count > 0) - lvm_chr_open_count--; + if (lvm_chr_open_count > 0) lvm_chr_open_count--; spin_lock(&lvm_lock); - if (lock == current->pid) { - if (!_lock_open_count) { - P_DEV("chr_close: unlocking LVM for pid %d\n", - lock); + if(lock == current->pid) { + if(!_lock_open_count) { + P_DEV("chr_close: unlocking LVM for pid %d\n", lock); lock = 0; wake_up_interruptible(&lvm_wait); } else @@ -842,7 +831,7 @@ MOD_DEC_USE_COUNT; return 0; -} /* lvm_chr_close() */ +} /* lvm_chr_close() */ @@ -862,8 +851,7 @@ vg_t *vg_ptr = vg[VG_BLK(minor)]; P_DEV("blk_open MINOR: %d VG#: %d LV#: %d mode: %s%s\n", - minor, VG_BLK(minor), LV_BLK(minor), - MODE_TO_STR(file->f_mode)); + minor, VG_BLK(minor), LV_BLK(minor), MODE_TO_STR(file->f_mode)); #ifdef LVM_TOTAL_RESET if (lvm_reset_spindown > 0) @@ -873,25 +861,26 @@ if (vg_ptr != NULL && (vg_ptr->vg_status & VG_ACTIVE) && (lv_ptr = vg_ptr->lv[LV_BLK(minor)]) != NULL && - LV_BLK(minor) >= 0 && LV_BLK(minor) < vg_ptr->lv_max) { + LV_BLK(minor) >= 0 && + LV_BLK(minor) < vg_ptr->lv_max) { /* Check parallel LV spindown (LV remove) */ - if (lv_ptr->lv_status & LV_SPINDOWN) - return -EPERM; + if (lv_ptr->lv_status & LV_SPINDOWN) return -EPERM; /* Check inactive LV and open for read/write */ /* We need to be able to "read" an inactive LV to re-activate it again */ if ((file->f_mode & FMODE_WRITE) && - (!(lv_ptr->lv_status & LV_ACTIVE))) return -EPERM; + (!(lv_ptr->lv_status & LV_ACTIVE))) + return -EPERM; if (!(lv_ptr->lv_access & LV_WRITE) && - (file->f_mode & FMODE_WRITE)) return -EACCES; + (file->f_mode & FMODE_WRITE)) + return -EACCES; - /* be sure to increment VG counter */ - if (lv_ptr->lv_open == 0) - vg_ptr->lv_open++; + /* be sure to increment VG counter */ + if (lv_ptr->lv_open == 0) vg_ptr->lv_open++; lv_ptr->lv_open++; MOD_INC_USE_COUNT; @@ -901,157 +890,161 @@ return 0; } return -ENXIO; -} /* lvm_blk_open() */ - +} /* lvm_blk_open() */ -/* - * block device i/o-control routine - */ -static int lvm_blk_ioctl(struct inode *inode, struct file *file, - uint command, ulong a) +/* Deliver "hard disk geometry" */ +static int _hdio_getgeo(ulong a, lv_t *lv_ptr, int what) { - int minor = MINOR(inode->i_rdev); - vg_t *vg_ptr = vg[VG_BLK(minor)]; - lv_t *lv_ptr = vg_ptr->lv[LV_BLK(minor)]; - void *arg = (void *) a; - struct hd_geometry *hd = (struct hd_geometry *) a; - - P_IOCTL("blk MINOR: %d command: 0x%X arg: %p VG#: %d LV#: %d " - "mode: %s%s\n", minor, command, arg, VG_BLK(minor), - LV_BLK(minor), MODE_TO_STR(file->f_mode)); - - switch (command) { - case BLKSSZGET: - /* get block device sector size as needed e.g. by fdisk */ - return put_user(lvm_sectsize(inode->i_rdev), (int *) arg); - - case BLKGETSIZE: - /* return device size */ - P_IOCTL("BLKGETSIZE: %u\n", lv_ptr->lv_size); - if (put_user(lv_ptr->lv_size, (unsigned long *) arg)) - return -EFAULT; - break; - -#ifdef BLKGETSIZE64 - case BLKGETSIZE64: - if (put_user((u64) lv_ptr->lv_size << 9, (u64 *) arg)) - return -EFAULT; - break; -#endif - - case BLKFLSBUF: - /* flush buffer cache */ - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - P_IOCTL("BLKFLSBUF\n"); - - fsync_dev(inode->i_rdev); - invalidate_buffers(inode->i_rdev); - break; - - - case BLKRASET: - /* set read ahead for block device */ - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - P_IOCTL("BLKRASET: %ld sectors for %s\n", - (long) arg, kdevname(inode->i_rdev)); - - if ((long) arg < LVM_MIN_READ_AHEAD || - (long) arg > LVM_MAX_READ_AHEAD) return -EINVAL; - lv_ptr->lv_read_ahead = (long) arg; - LVM_CORRECT_READ_AHEAD(lv_ptr->lv_read_ahead); - read_ahead[MAJOR_NR] = lv_ptr->lv_read_ahead; - break; - + int ret = 0; + uchar heads = 128; + uchar sectors = 128; + ulong start = 0; + uint cylinders; + + while ( heads * sectors > lv_ptr->lv_size) { + heads >>= 1; + sectors >>= 1; + } + cylinders = lv_ptr->lv_size / heads / sectors; - case BLKRAGET: - /* get current read ahead setting */ - P_IOCTL("BLKRAGET %d\n", lv_ptr->lv_read_ahead); - if (put_user(lv_ptr->lv_read_ahead, (long *) arg)) - return -EFAULT; - break; + switch (what) { + case 0: + { + struct hd_geometry *hd = (struct hd_geometry *) a; + if (put_user(heads, &hd->heads) || + put_user(sectors, &hd->sectors) || + put_user((ushort) cylinders, &hd->cylinders) || + put_user(start, &hd->start)) + return -EFAULT; + break; + } - case HDIO_GETGEO: - /* get disk geometry */ - P_IOCTL("%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", lvm_name); - if (hd == NULL) - return -EINVAL; +#ifdef HDIO_GETGEO_BIG + case 1: { - unsigned char heads = 64; - unsigned char sectors = 32; - long start = 0; - short cylinders = - lv_ptr->lv_size / heads / sectors; - - if (copy_to_user((char *) &hd->heads, &heads, - sizeof(heads)) != 0 || - copy_to_user((char *) &hd->sectors, §ors, - sizeof(sectors)) != 0 || - copy_to_user((short *) &hd->cylinders, - &cylinders, - sizeof(cylinders)) != 0 - || copy_to_user((long *) &hd->start, &start, - sizeof(start)) != 0) - return -EFAULT; + struct hd_big_geometry *hd = + (struct hd_big_geometry *) a; - P_IOCTL("%s -- lvm_blk_ioctl -- cylinders: %d\n", - lvm_name, cylinders); + if (put_user(heads, &hd->heads) || + put_user(sectors, &hd->sectors) || + put_user(cylinders, &hd->cylinders) || + put_user(start, &hd->start)) + return -EFAULT; + break; } - break; - +#endif - case LV_SET_ACCESS: - /* set access flags of a logical volume */ - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - lv_ptr->lv_access = (ulong) arg; - if (lv_ptr->lv_access & LV_WRITE) - set_device_ro(lv_ptr->lv_dev, 0); - else - set_device_ro(lv_ptr->lv_dev, 1); - break; + } + P_IOCTL("%s -- lvm_blk_ioctl -- cylinders: %d\n", + lvm_name, cylinders); + return ret; +} - case LV_SET_STATUS: - /* set status flags of a logical volume */ - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (!((ulong) arg & LV_ACTIVE) && lv_ptr->lv_open > 1) - return -EPERM; - lv_ptr->lv_status = (ulong) arg; - break; - case LV_BMAP: - /* turn logical block into (dev_t, block). non privileged. */ - /* don't bmap a snapshot, since the mapping can change */ - if (lv_ptr->lv_access & LV_SNAPSHOT) - return -EPERM; - - return lvm_user_bmap(inode, (struct lv_bmap *) arg); - - case LV_SET_ALLOCATION: - /* set allocation flags of a logical volume */ - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - lv_ptr->lv_allocation = (ulong) arg; - break; +/* + * block device i/o-control routine + */ +static int lvm_blk_ioctl(struct inode *inode, struct file *file, + uint cmd, ulong a) +{ + kdev_t dev = inode->i_rdev; + int minor = MINOR(dev), ret; + vg_t *vg_ptr = vg[VG_BLK(minor)]; + lv_t *lv_ptr = vg_ptr->lv[LV_BLK(minor)]; + void *arg = (void *) a; - case LV_SNAPSHOT_USE_RATE: - return lvm_get_snapshot_use_rate(lv_ptr, arg); + P_IOCTL("blk MINOR: %d cmd: 0x%X arg: %p VG#: %d LV#: %d " + "mode: %s%s\n", minor, cmd, arg, VG_BLK(minor), + LV_BLK(minor), MODE_TO_STR(file->f_mode)); - default: - printk(KERN_WARNING - "%s -- lvm_blk_ioctl: unknown command 0x%x\n", - lvm_name, command); - return -EINVAL; + switch (cmd) { + case BLKRASET: + /* set read ahead for block device */ + ret = blk_ioctl(dev, cmd, a); + if (ret) + return ret; + lv_ptr->lv_read_ahead = (long) a; + LVM_CORRECT_READ_AHEAD(lv_ptr->lv_read_ahead); + break; + + case HDIO_GETGEO: +#ifdef HDIO_GETGEO_BIG + case HDIO_GETGEO_BIG: +#endif + /* get disk geometry */ + P_IOCTL("%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", + lvm_name); + if (!a) + return -EINVAL; + + switch (cmd) { + case HDIO_GETGEO: + return _hdio_getgeo(a, lv_ptr, 0); +#ifdef HDIO_GETGEO_BIG + case HDIO_GETGEO_BIG: + return _hdio_getgeo(a, lv_ptr, 1); +#endif + } + + case LV_BMAP: + /* turn logical block into (dev_t, block). non privileged. */ + /* don't bmap a snapshot, since the mapping can change */ + if (lv_ptr->lv_access & LV_SNAPSHOT) + return -EPERM; + + return lvm_user_bmap(inode, (struct lv_bmap *) arg); + + case LV_SET_ACCESS: + /* set access flags of a logical volume */ + if (!capable(CAP_SYS_ADMIN)) return -EACCES; + + down_write(&lv_ptr->lv_lock); + lv_ptr->lv_access = (ulong) arg; + up_write(&lv_ptr->lv_lock); + + if ( lv_ptr->lv_access & LV_WRITE) + set_device_ro(lv_ptr->lv_dev, 0); + else + set_device_ro(lv_ptr->lv_dev, 1); + break; + + + case LV_SET_ALLOCATION: + /* set allocation flags of a logical volume */ + if (!capable(CAP_SYS_ADMIN)) return -EACCES; + down_write(&lv_ptr->lv_lock); + lv_ptr->lv_allocation = (ulong) arg; + up_write(&lv_ptr->lv_lock); + break; + + case LV_SET_STATUS: + /* set status flags of a logical volume */ + if (!capable(CAP_SYS_ADMIN)) return -EACCES; + if (!((ulong) arg & LV_ACTIVE) && lv_ptr->lv_open > 1) + return -EPERM; + down_write(&lv_ptr->lv_lock); + lv_ptr->lv_status = (ulong) arg; + up_write(&lv_ptr->lv_lock); + break; + + case LV_SNAPSHOT_USE_RATE: + return lvm_get_snapshot_use_rate(lv_ptr, arg); + + default: + /* Handle rest here */ + ret = blk_ioctl(dev, cmd, a); + if (ret) + printk(KERN_WARNING + "%s -- lvm_blk_ioctl: unknown " + "cmd 0x%x\n", + lvm_name, cmd); + return ret; } return 0; -} /* lvm_blk_ioctl() */ +} /* lvm_blk_ioctl() */ /* @@ -1066,21 +1059,24 @@ P_DEV("blk_close MINOR: %d VG#: %d LV#: %d\n", minor, VG_BLK(minor), LV_BLK(minor)); - if (lv_ptr->lv_open == 1) - vg_ptr->lv_open--; + if (lv_ptr->lv_open == 1) vg_ptr->lv_open--; lv_ptr->lv_open--; MOD_DEC_USE_COUNT; return 0; -} /* lvm_blk_close() */ +} /* lvm_blk_close() */ -static int lvm_get_snapshot_use_rate(lv_t * lv, void *arg) +static int lvm_get_snapshot_use_rate(lv_t *lv, void *arg) { lv_snapshot_use_rate_req_t lv_rate_req; - if (!(lv->lv_access & LV_SNAPSHOT)) + down_read(&lv->lv_lock); + if (!(lv->lv_access & LV_SNAPSHOT)) { + up_read(&lv->lv_lock); return -EPERM; + } + up_read(&lv->lv_lock); if (copy_from_user(&lv_rate_req, arg, sizeof(lv_rate_req))) return -EFAULT; @@ -1090,10 +1086,17 @@ switch (lv_rate_req.block) { case 0: + down_write(&lv->lv_lock); lv->lv_snapshot_use_rate = lv_rate_req.rate; + up_write(&lv->lv_lock); + down_read(&lv->lv_lock); if (lv->lv_remap_ptr * 100 / lv->lv_remap_end < - lv->lv_snapshot_use_rate) - interruptible_sleep_on(&lv->lv_snapshot_wait); + lv->lv_snapshot_use_rate) { + up_read(&lv->lv_lock); + interruptible_sleep_on(&lv->lv_snapshot_wait); + down_read(&lv->lv_lock); + } + up_read(&lv->lv_lock); break; case O_NONBLOCK: @@ -1102,7 +1105,9 @@ default: return -EINVAL; } + down_read(&lv->lv_lock); lv_rate_req.rate = lv->lv_remap_ptr * 100 / lv->lv_remap_end; + up_read(&lv->lv_lock); return copy_to_user(arg, &lv_rate_req, sizeof(lv_rate_req)) ? -EFAULT : 0; @@ -1117,20 +1122,20 @@ if (get_user(block, &user_result->lv_block)) return -EFAULT; - memset(&bh, 0, sizeof bh); + memset(&bh,0,sizeof bh); bh.b_blocknr = block; bh.b_dev = bh.b_rdev = inode->i_rdev; bh.b_size = lvm_get_blksize(bh.b_dev); bh.b_rsector = block * (bh.b_size >> 9); bh.b_end_io = NULL; - if ((err = lvm_map(&bh, READ)) < 0) { + if ((err = lvm_map(&bh, READ)) < 0) { printk("lvm map failed: %d\n", err); return -EINVAL; } return put_user(kdev_t_to_nr(bh.b_rdev), &user_result->lv_dev) || - put_user(bh.b_rsector / (bh.b_size >> 9), - &user_result->lv_block) ? -EFAULT : 0; + put_user(bh.b_rsector/(bh.b_size>>9), &user_result->lv_block) ? + -EFAULT : 0; } @@ -1139,8 +1144,7 @@ * (see init_module/lvm_init) */ static void __remap_snapshot(kdev_t rdev, ulong rsector, - ulong pe_start, lv_t * lv, vg_t * vg) -{ + ulong pe_start, lv_t *lv, vg_t *vg) { /* copy a chunk from the origin to a snapshot device */ down_write(&lv->lv_lock); @@ -1155,8 +1159,7 @@ } static inline void _remap_snapshot(kdev_t rdev, ulong rsector, - ulong pe_start, lv_t * lv, vg_t * vg) -{ + ulong pe_start, lv_t *lv, vg_t *vg) { int r; /* check to see if this chunk is already in the snapshot */ @@ -1173,8 +1176,7 @@ /* * extents destined for a pe that is on the move should be deferred */ -static inline int _should_defer(kdev_t pv, ulong sector, uint32_t pe_size) -{ +static inline int _should_defer(kdev_t pv, ulong sector, uint32_t pe_size) { return ((pe_lock_req.lock == LOCK_PE) && (pv == pe_lock_req.data.pv_dev) && (sector >= pe_lock_req.data.pv_offset) && @@ -1221,32 +1223,34 @@ goto bad; } - if ((rw == WRITE || rw == WRITEA) && !(lv->lv_access & LV_WRITE)) { + if ((rw == WRITE || rw == WRITEA) && + !(lv->lv_access & LV_WRITE)) { printk(KERN_CRIT "%s - lvm_map: ll_rw_blk write for readonly LV %s\n", lvm_name, lv->lv_name); goto bad; } - P_MAP - ("%s - lvm_map minor: %d *rdev: %s *rsector: %lu size:%lu\n", - lvm_name, minor, kdevname(bh->b_rdev), rsector_org, size); + P_MAP("%s - lvm_map minor: %d *rdev: %s *rsector: %lu size:%lu\n", + lvm_name, minor, + kdevname(bh->b_rdev), + rsector_org, size); if (rsector_org + size > lv->lv_size) { printk(KERN_ALERT "%s - lvm_map access beyond end of device; *rsector: " - "%lu or size: %lu wrong for minor: %2d\n", - lvm_name, rsector_org, size, minor); + "%lu or size: %lu wrong for minor: %2d\n", + lvm_name, rsector_org, size, minor); goto bad; } - if (lv->lv_stripes < 2) { /* linear mapping */ + if (lv->lv_stripes < 2) { /* linear mapping */ /* get the index */ index = rsector_org / vg_this->pe_size; pe_start = lv->lv_current_pe[index].pe; rsector_map = lv->lv_current_pe[index].pe + - (rsector_org % vg_this->pe_size); + (rsector_org % vg_this->pe_size); rdev_map = lv->lv_current_pe[index].dev; P_MAP("lv_current_pe[%ld].pe: %d rdev: %s rsector:%ld\n", @@ -1259,23 +1263,22 @@ stripe_length = vg_this->pe_size * lv->lv_stripes; stripe_index = (rsector_org % stripe_length) / - lv->lv_stripesize; + lv->lv_stripesize; index = rsector_org / stripe_length + - (stripe_index % lv->lv_stripes) * - (lv->lv_allocated_le / lv->lv_stripes); + (stripe_index % lv->lv_stripes) * + (lv->lv_allocated_le / lv->lv_stripes); pe_start = lv->lv_current_pe[index].pe; rsector_map = lv->lv_current_pe[index].pe + - (rsector_org % stripe_length) - - (stripe_index % lv->lv_stripes) * lv->lv_stripesize - - stripe_index / lv->lv_stripes * - (lv->lv_stripes - 1) * lv->lv_stripesize; + (rsector_org % stripe_length) - + (stripe_index % lv->lv_stripes) * lv->lv_stripesize - + stripe_index / lv->lv_stripes * + (lv->lv_stripes - 1) * lv->lv_stripesize; rdev_map = lv->lv_current_pe[index].dev; P_MAP("lv_current_pe[%ld].pe: %d rdev: %s rsector:%ld\n" "stripe_length: %ld stripe_index: %ld\n", - index, lv->lv_current_pe[index].pe, - kdevname(rdev_map), rsector_map, stripe_length, - stripe_index); + index, lv->lv_current_pe[index].pe, kdevname(rdev_map), + rsector_map, stripe_length, stripe_index); } /* @@ -1284,8 +1287,8 @@ * we need to queue this request, because this is in the fast path. */ if (rw == WRITE || rw == WRITEA) { - if (_defer_extent(bh, rw, rdev_map, - rsector_map, vg_this->pe_size)) { + if(_defer_extent(bh, rw, rdev_map, + rsector_map, vg_this->pe_size)) { up_read(&lv->lv_lock); return 0; @@ -1296,14 +1299,15 @@ lv->lv_current_pe[index].reads++; /* statistic */ /* snapshot volume exception handling on physical device address base */ - if (!(lv->lv_access & (LV_SNAPSHOT | LV_SNAPSHOT_ORG))) + if (!(lv->lv_access & (LV_SNAPSHOT|LV_SNAPSHOT_ORG))) goto out; - if (lv->lv_access & LV_SNAPSHOT) { /* remap snapshot */ - if (lvm_snapshot_remap_block - (&rdev_map, &rsector_map, pe_start, lv) < 0) - goto bad; - } else if (rw == WRITE || rw == WRITEA) { /* snapshot origin */ + if (lv->lv_access & LV_SNAPSHOT) { /* remap snapshot */ + if (lvm_snapshot_remap_block(&rdev_map, &rsector_map, + pe_start, lv) < 0) + goto bad; + + } else if (rw == WRITE || rw == WRITEA) { /* snapshot origin */ lv_t *snap; /* start with first snapshot and loop through all of @@ -1317,21 +1321,22 @@ /* Serializes the COW with the accesses to the snapshot device */ _remap_snapshot(rdev_map, rsector_map, - pe_start, snap, vg_this); + pe_start, snap, vg_this); } } - out: + out: bh->b_rdev = rdev_map; bh->b_rsector = rsector_map; up_read(&lv->lv_lock); return 1; - bad: - if (bh->b_end_io) buffer_IO_error(bh); + bad: + if (bh->b_end_io) + buffer_IO_error(bh); up_read(&lv->lv_lock); return -1; -} /* lvm_map() */ +} /* lvm_map() */ /* @@ -1363,8 +1368,9 @@ /* * make request function */ -static int lvm_make_request_fn(request_queue_t * q, - int rw, struct buffer_head *bh) +static int lvm_make_request_fn(request_queue_t *q, + int rw, + struct buffer_head *bh) { return (lvm_map(bh, rw) <= 0) ? 0 : 1; } @@ -1380,7 +1386,7 @@ */ static int lvm_do_lock_lvm(void) { - lock_try_again: +lock_try_again: spin_lock(&lvm_lock); if (lock != 0 && lock != current->pid) { P_DEV("lvm_do_lock_lvm: locked by pid %d ...\n", lock); @@ -1398,20 +1404,19 @@ P_DEV("lvm_do_lock_lvm: locking LVM for pid %d\n", lock); spin_unlock(&lvm_lock); return 0; -} /* lvm_do_lock_lvm */ +} /* lvm_do_lock_lvm */ /* * character device support function lock/unlock physical extend */ -static int lvm_do_pe_lock_unlock(vg_t * vg_ptr, void *arg) +static int lvm_do_pe_lock_unlock(vg_t *vg_ptr, void *arg) { pe_lock_req_t new_lock; struct buffer_head *bh; uint p; - if (vg_ptr == NULL) - return -ENXIO; + if (vg_ptr == NULL) return -ENXIO; if (copy_from_user(&new_lock, arg, sizeof(new_lock)) != 0) return -EFAULT; @@ -1422,8 +1427,7 @@ new_lock.data.pv_dev == vg_ptr->pv[p]->pv_dev) break; } - if (p == vg_ptr->pv_max) - return -ENXIO; + if (p == vg_ptr->pv_max) return -ENXIO; /* * this sync releaves memory pressure to lessen the @@ -1474,20 +1478,24 @@ /* * character device support function logical extend remap */ -static int lvm_do_le_remap(vg_t * vg_ptr, void *arg) +static int lvm_do_le_remap(vg_t *vg_ptr, void *arg) { uint l, le; lv_t *lv_ptr; - if (vg_ptr == NULL) - return -ENXIO; + if (vg_ptr == NULL) return -ENXIO; if (copy_from_user(&le_remap_req, arg, - sizeof(le_remap_req_t)) != 0) return -EFAULT; + sizeof(le_remap_req_t)) != 0) + return -EFAULT; for (l = 0; l < vg_ptr->lv_max; l++) { lv_ptr = vg_ptr->lv[l]; - if (lv_ptr != NULL && - strcmp(lv_ptr->lv_name, le_remap_req.lv_name) == 0) { + + if (!lv_ptr) + continue; + + if (strcmp(lv_ptr->lv_name, le_remap_req.lv_name) == 0) { + down_write(&lv_ptr->lv_lock); for (le = 0; le < lv_ptr->lv_allocated_le; le++) { if (lv_ptr->lv_current_pe[le].dev == le_remap_req.old_dev && @@ -1497,16 +1505,17 @@ le_remap_req.new_dev; lv_ptr->lv_current_pe[le].pe = le_remap_req.new_pe; - __update_hardsectsize(lv_ptr); + up_write(&lv_ptr->lv_lock); return 0; } } + up_write(&lv_ptr->lv_lock); return -EINVAL; } } return -ENXIO; -} /* lvm_do_le_remap() */ +} /* lvm_do_le_remap() */ /* @@ -1520,7 +1529,7 @@ vg_t *vg_ptr; lv_t **snap_lv_ptr; - if ((vg_ptr = kmalloc(sizeof(vg_t), GFP_KERNEL)) == NULL) { + if ((vg_ptr = kmalloc(sizeof(vg_t),GFP_KERNEL)) == NULL) { printk(KERN_CRIT "%s -- VG_CREATE: kmalloc error VG at line %d\n", lvm_name, __LINE__); @@ -1528,9 +1537,8 @@ } /* get the volume group structure */ if (copy_from_user(vg_ptr, arg, sizeof(vg_t)) != 0) { - P_IOCTL - ("lvm_do_vg_create ERROR: copy VG ptr %p (%d bytes)\n", - arg, sizeof(vg_t)); + P_IOCTL("lvm_do_vg_create ERROR: copy VG ptr %p (%d bytes)\n", + arg, sizeof(vg_t)); kfree(vg_ptr); return -EFAULT; } @@ -1539,6 +1547,10 @@ if (minor == -1) minor = vg_ptr->vg_number; + /* check limits */ + if (minor >= ABS_MAX_VG) + return -EFAULT; + /* Validate it */ if (vg[VG_CHR(minor)] != NULL) { P_IOCTL("lvm_do_vg_create ERROR: VG %d in use\n", minor); @@ -1560,7 +1572,7 @@ if (vg_ptr->lv_max > ABS_MAX_LV) { printk(KERN_WARNING - "%s -- Can't activate VG: ABS_MAX_LV too small for %u\n", + "%s -- Can't activate VG: ABS_MAX_LV too small for %u\n", lvm_name, vg_ptr->lv_max); kfree(vg_ptr); return -EPERM; @@ -1578,7 +1590,7 @@ /* user space address */ if ((pvp = vg_ptr->pv[p]) != NULL) { ret = lvm_do_pv_create(pvp, vg_ptr, p); - if (ret != 0) { + if ( ret != 0) { lvm_do_vg_remove(minor); return ret; } @@ -1586,7 +1598,7 @@ } size = vg_ptr->lv_max * sizeof(lv_t *); - if ((snap_lv_ptr = vmalloc(size)) == NULL) { + if ((snap_lv_ptr = vmalloc ( size)) == NULL) { printk(KERN_CRIT "%s -- VG_CREATE: vmalloc error snapshot LVs at line %d\n", lvm_name, __LINE__); @@ -1602,13 +1614,12 @@ /* user space address */ if ((lvp = vg_ptr->lv[l]) != NULL) { if (copy_from_user(&lv, lvp, sizeof(lv_t)) != 0) { - P_IOCTL - ("ERROR: copying LV ptr %p (%d bytes)\n", - lvp, sizeof(lv_t)); + P_IOCTL("ERROR: copying LV ptr %p (%d bytes)\n", + lvp, sizeof(lv_t)); lvm_do_vg_remove(minor); return -EFAULT; } - if (lv.lv_access & LV_SNAPSHOT) { + if ( lv.lv_access & LV_SNAPSHOT) { snap_lv_ptr[ls] = lvp; vg_ptr->lv[l] = NULL; ls++; @@ -1648,26 +1659,24 @@ vg_ptr->vg_status |= VG_ACTIVE; return 0; -} /* lvm_do_vg_create() */ +} /* lvm_do_vg_create() */ /* * character device support function VGDA extend */ -static int lvm_do_vg_extend(vg_t * vg_ptr, void *arg) +static int lvm_do_vg_extend(vg_t *vg_ptr, void *arg) { int ret = 0; uint p; pv_t *pv_ptr; - if (vg_ptr == NULL) - return -ENXIO; + if (vg_ptr == NULL) return -ENXIO; if (vg_ptr->pv_cur < vg_ptr->pv_max) { for (p = 0; p < vg_ptr->pv_max; p++) { - if ((pv_ptr = vg_ptr->pv[p]) == NULL) { + if ( ( pv_ptr = vg_ptr->pv[p]) == NULL) { ret = lvm_do_pv_create(arg, vg_ptr, p); - if (ret != 0) - return ret; + if ( ret != 0) return ret; pv_ptr = vg_ptr->pv[p]; vg_ptr->pe_total += pv_ptr->pe_total; return 0; @@ -1675,28 +1684,26 @@ } } return -EPERM; -} /* lvm_do_vg_extend() */ +} /* lvm_do_vg_extend() */ /* * character device support function VGDA reduce */ -static int lvm_do_vg_reduce(vg_t * vg_ptr, void *arg) -{ +static int lvm_do_vg_reduce(vg_t *vg_ptr, void *arg) { uint p; pv_t *pv_ptr; - if (vg_ptr == NULL) - return -ENXIO; + if (vg_ptr == NULL) return -ENXIO; if (copy_from_user(pv_name, arg, sizeof(pv_name)) != 0) return -EFAULT; for (p = 0; p < vg_ptr->pv_max; p++) { pv_ptr = vg_ptr->pv[p]; if (pv_ptr != NULL && - strcmp(pv_ptr->pv_name, pv_name) == 0) { - if (pv_ptr->lv_cur > 0) - return -EPERM; + strcmp(pv_ptr->pv_name, + pv_name) == 0) { + if (pv_ptr->lv_cur > 0) return -EPERM; lvm_do_pv_remove(vg_ptr, p); /* Make PV pointer array contiguous */ for (; p < vg_ptr->pv_max - 1; p++) @@ -1706,55 +1713,74 @@ } } return -ENXIO; -} /* lvm_do_vg_reduce */ +} /* lvm_do_vg_reduce */ /* * character device support function VG rename */ -static int lvm_do_vg_rename(vg_t * vg_ptr, void *arg) +static int lvm_do_vg_rename(vg_t *vg_ptr, void *arg) { int l = 0, p = 0, len = 0; - char vg_name[NAME_LEN] = { 0, }; - char lv_name[NAME_LEN] = { 0, }; + char vg_name[NAME_LEN] = { 0,}; + char lv_name[NAME_LEN] = { 0,}; char *ptr = NULL; lv_t *lv_ptr = NULL; pv_t *pv_ptr = NULL; /* If the VG doesn't exist in the kernel then just exit */ - if (!vg_ptr) - return 0; + if (!vg_ptr) return 0; if (copy_from_user(vg_name, arg, sizeof(vg_name)) != 0) return -EFAULT; lvm_fs_remove_vg(vg_ptr); - strncpy(vg_ptr->vg_name, vg_name, sizeof(vg_name) - 1); - for (l = 0; l < vg_ptr->lv_max; l++) { - if ((lv_ptr = vg_ptr->lv[l]) == NULL) - continue; - strncpy(lv_ptr->vg_name, vg_name, sizeof(vg_name)); + strncpy ( vg_ptr->vg_name, vg_name, sizeof ( vg_name)-1); + for ( l = 0; l < vg_ptr->lv_max; l++) + { + if ((lv_ptr = vg_ptr->lv[l]) == NULL) continue; + memset (lv_ptr->vg_name, 0, sizeof (*vg_name)); + strncpy(lv_ptr->vg_name, vg_name, sizeof ( vg_name)); ptr = strrchr(lv_ptr->lv_name, '/'); - if (ptr == NULL) - ptr = lv_ptr->lv_name; - strncpy(lv_name, ptr, sizeof(lv_name)); + ptr = ptr ? ptr + 1 : lv_ptr->lv_name; + strncpy(lv_name, ptr, sizeof ( lv_name)); len = sizeof(LVM_DIR_PREFIX); strcpy(lv_ptr->lv_name, LVM_DIR_PREFIX); strncat(lv_ptr->lv_name, vg_name, NAME_LEN - len); - len += strlen(vg_name); + strcat (lv_ptr->lv_name, "/"); + len += strlen(vg_name) + 1; strncat(lv_ptr->lv_name, lv_name, NAME_LEN - len); } - for (p = 0; p < vg_ptr->pv_max; p++) { - if ((pv_ptr = vg_ptr->pv[p]) == NULL) - continue; + for ( p = 0; p < vg_ptr->pv_max; p++) + { + if ( (pv_ptr = vg_ptr->pv[p]) == NULL) continue; strncpy(pv_ptr->vg_name, vg_name, NAME_LEN); } lvm_fs_create_vg(vg_ptr); + /* Need to add PV entries */ + for ( p = 0; p < vg_ptr->pv_act; p++) { + pv_t *pv_ptr = vg_ptr->pv[p]; + + if (pv_ptr) + lvm_fs_create_pv(vg_ptr, pv_ptr); + } + + /* Need to add LV entries */ + for ( l = 0; l < vg_ptr->lv_max; l++) { + lv_t *lv_ptr = vg_ptr->lv[l]; + + if (!lv_ptr) + continue; + + lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].de = + lvm_fs_create_lv(vg_ptr, lv_ptr); + } + return 0; -} /* lvm_do_vg_rename */ +} /* lvm_do_vg_rename */ /* @@ -1766,8 +1792,7 @@ vg_t *vg_ptr = vg[VG_CHR(minor)]; pv_t *pv_ptr; - if (vg_ptr == NULL) - return -ENXIO; + if (vg_ptr == NULL) return -ENXIO; #ifdef LVM_TOTAL_RESET if (vg_ptr->lv_open > 0 && lvm_reset_spindown == 0) @@ -1818,18 +1843,20 @@ MOD_DEC_USE_COUNT; return 0; -} /* lvm_do_vg_remove() */ +} /* lvm_do_vg_remove() */ /* * character device support function physical volume create */ -static int lvm_do_pv_create(pv_t * pvp, vg_t * vg_ptr, ulong p) -{ +static int lvm_do_pv_create(pv_t *pvp, vg_t *vg_ptr, ulong p) { pv_t *pv; int err; - pv = kmalloc(sizeof(pv_t), GFP_KERNEL); + if (!vg_ptr) + return -ENXIO; + + pv = kmalloc(sizeof(pv_t),GFP_KERNEL); if (pv == NULL) { printk(KERN_CRIT "%s -- PV_CREATE: kmalloc error PV at line %d\n", @@ -1840,9 +1867,8 @@ memset(pv, 0, sizeof(*pv)); if (copy_from_user(pv, pvp, sizeof(pv_t)) != 0) { - P_IOCTL - ("lvm_do_pv_create ERROR: copy PV ptr %p (%d bytes)\n", - pvp, sizeof(pv_t)); + P_IOCTL("lvm_do_pv_create ERROR: copy PV ptr %p (%d bytes)\n", + pvp, sizeof(pv_t)); kfree(pv); return -EFAULT; } @@ -1863,14 +1889,13 @@ vg_ptr->pv[p] = pv; return 0; -} /* lvm_do_pv_create() */ +} /* lvm_do_pv_create() */ /* * character device support function physical volume remove */ -static int lvm_do_pv_remove(vg_t * vg_ptr, ulong p) -{ +static int lvm_do_pv_remove(vg_t *vg_ptr, ulong p) { pv_t *pv = vg_ptr->pv[p]; lvm_fs_remove_pv(vg_ptr, pv); @@ -1888,7 +1913,7 @@ } -static void __update_hardsectsize(lv_t * lv) +static void __update_hardsectsize(lv_t *lv) { int max_hardsectsize = 0, hardsectsize = 0; int p; @@ -1900,10 +1925,9 @@ if (max_hardsectsize == 0) max_hardsectsize = hardsectsize; else if (hardsectsize != max_hardsectsize) { - P_DEV - ("%s PV[%d] (%s) sector size %d, not %d\n", - lv->lv_name, p, kdevname(pv->pv_dev), - hardsectsize, max_hardsectsize); + P_DEV("%s PV[%d] (%s) sector size %d, not %d\n", + lv->lv_name, p, kdevname(pv->pv_dev), + hardsectsize, max_hardsectsize); break; } } @@ -1913,14 +1937,12 @@ if (hardsectsize != max_hardsectsize) { int le; for (le = 0; le < lv->lv_allocated_le; le++) { - hardsectsize = - lvm_sectsize(lv->lv_current_pe[le].dev); + hardsectsize = lvm_sectsize(lv->lv_current_pe[le].dev); if (hardsectsize > max_hardsectsize) { - P_DEV - ("%s LE[%d] (%s) blocksize %d not %d\n", - lv->lv_name, le, - kdevname(lv->lv_current_pe[le].dev), - hardsectsize, max_hardsectsize); + P_DEV("%s LE[%d] (%s) blocksize %d not %d\n", + lv->lv_name, le, + kdevname(lv->lv_current_pe[le].dev), + hardsectsize, max_hardsectsize); max_hardsectsize = hardsectsize; } } @@ -1930,9 +1952,7 @@ (lv->lv_status & LV_ACTIVE)) { int e; for (e = 0; e < lv->lv_remap_end; e++) { - hardsectsize = - lvm_sectsize(lv->lv_block_exception[e]. - rdev_new); + hardsectsize = lvm_sectsize(lv->lv_block_exception[e].rdev_new); if (hardsectsize > max_hardsectsize) max_hardsectsize = hardsectsize; } @@ -1949,7 +1969,7 @@ /* * character device support function logical volume create */ -static int lvm_do_lv_create(int minor, char *lv_name, lv_t * lv) +static int lvm_do_lv_create(int minor, char *lv_name, lv_t *lv) { int e, ret, l, le, l_new, p, size, activate = 1; ulong lv_status_save; @@ -1977,18 +1997,14 @@ else { for (l = 0; l < vg_ptr->lv_max; l++) { if (vg_ptr->lv[l] == NULL) - if (l_new == -1) - l_new = l; + if (l_new == -1) l_new = l; } } - if (l_new == -1) - return -EPERM; - else - l = l_new; + if (l_new == -1) return -EPERM; + else l = l_new; - if ((lv_ptr = kmalloc(sizeof(lv_t), GFP_KERNEL)) == NULL) {; - printk(KERN_CRIT - "%s -- LV_CREATE: kmalloc error LV at line %d\n", + if ((lv_ptr = kmalloc(sizeof(lv_t),GFP_KERNEL)) == NULL) {; + printk(KERN_CRIT "%s -- LV_CREATE: kmalloc error LV at line %d\n", lvm_name, __LINE__); return -ENOMEM; } @@ -2020,7 +2036,8 @@ if ((lv_ptr->lv_current_pe = vmalloc(size)) == NULL) { printk(KERN_CRIT "%s -- LV_CREATE: vmalloc error LV_CURRENT_PE of %d Byte " - "at line %d\n", lvm_name, size, __LINE__); + "at line %d\n", + lvm_name, size, __LINE__); P_KFREE("%s -- kfree %d\n", lvm_name, __LINE__); kfree(lv_ptr); vg_ptr->lv[l] = NULL; @@ -2049,9 +2066,7 @@ lv_ptr->lv_snapshot_org = vg_ptr->lv[LV_BLK(lv_ptr->lv_snapshot_minor)]; if (lv_ptr->lv_snapshot_org != NULL) { - size = - lv_ptr->lv_remap_end * - sizeof(lv_block_exception_t); + size = lv_ptr->lv_remap_end * sizeof(lv_block_exception_t); if (!size) { printk(KERN_WARNING @@ -2061,33 +2076,29 @@ return -EINVAL; } - if ( - (lv_ptr->lv_block_exception = - vmalloc(size)) == NULL) { + if ((lv_ptr->lv_block_exception = vmalloc(size)) == NULL) { printk(KERN_CRIT "%s -- lvm_do_lv_create: vmalloc error LV_BLOCK_EXCEPTION " "of %d byte at line %d\n", lvm_name, size, __LINE__); - P_KFREE("%s -- kfree %d\n", - lvm_name, __LINE__); + P_KFREE("%s -- kfree %d\n", lvm_name, + __LINE__); kfree(lv_ptr); vg_ptr->lv[l] = NULL; return -ENOMEM; } - if (copy_from_user - (lv_ptr->lv_block_exception, lvbe, - size)) { + if (copy_from_user(lv_ptr->lv_block_exception, lvbe, size)) { vfree(lv_ptr->lv_block_exception); kfree(lv_ptr); vg_ptr->lv[l] = NULL; return -EFAULT; } - if (lv_ptr->lv_block_exception[0]. - rsector_org == - LVM_SNAPSHOT_DROPPED_SECTOR) { + if(lv_ptr->lv_block_exception[0].rsector_org == + LVM_SNAPSHOT_DROPPED_SECTOR) + { printk(KERN_WARNING - "%s -- lvm_do_lv_create: snapshot has been dropped and will not be activated\n", + "%s -- lvm_do_lv_create: snapshot has been dropped and will not be activated\n", lvm_name); activate = 0; } @@ -2101,54 +2112,36 @@ which can be the original logical volume */ lv_ptr = vg_ptr->lv[l]; /* now lv_ptr points to our new last snapshot logical volume */ - lv_ptr->lv_current_pe = - lv_ptr->lv_snapshot_org->lv_current_pe; - lv_ptr->lv_allocated_snapshot_le = - lv_ptr->lv_allocated_le; - lv_ptr->lv_allocated_le = - lv_ptr->lv_snapshot_org-> - lv_allocated_le; - lv_ptr->lv_current_le = - lv_ptr->lv_snapshot_org->lv_current_le; - lv_ptr->lv_size = - lv_ptr->lv_snapshot_org->lv_size; - lv_ptr->lv_stripes = - lv_ptr->lv_snapshot_org->lv_stripes; - lv_ptr->lv_stripesize = - lv_ptr->lv_snapshot_org->lv_stripesize; + lv_ptr->lv_current_pe = lv_ptr->lv_snapshot_org->lv_current_pe; + lv_ptr->lv_allocated_snapshot_le = lv_ptr->lv_allocated_le; + lv_ptr->lv_allocated_le = lv_ptr->lv_snapshot_org->lv_allocated_le; + lv_ptr->lv_current_le = lv_ptr->lv_snapshot_org->lv_current_le; + lv_ptr->lv_size = lv_ptr->lv_snapshot_org->lv_size; + lv_ptr->lv_stripes = lv_ptr->lv_snapshot_org->lv_stripes; + lv_ptr->lv_stripesize = lv_ptr->lv_snapshot_org->lv_stripesize; /* Update the VG PE(s) used by snapshot reserve space. */ - vg_ptr->pe_allocated += - lv_ptr->lv_allocated_snapshot_le; + vg_ptr->pe_allocated += lv_ptr->lv_allocated_snapshot_le; - if ((ret = lvm_snapshot_alloc(lv_ptr)) != - 0) { + if ((ret = lvm_snapshot_alloc(lv_ptr)) != 0) + { vfree(lv_ptr->lv_block_exception); kfree(lv_ptr); vg_ptr->lv[l] = NULL; return ret; } - for (e = 0; e < lv_ptr->lv_remap_ptr; e++) - lvm_hash_link(lv_ptr-> - lv_block_exception + - e, - lv_ptr-> - lv_block_exception - [e].rdev_org, - lv_ptr-> - lv_block_exception - [e].rsector_org, - lv_ptr); + for ( e = 0; e < lv_ptr->lv_remap_ptr; e++) + lvm_hash_link (lv_ptr->lv_block_exception + e, + lv_ptr->lv_block_exception[e].rdev_org, + lv_ptr->lv_block_exception[e].rsector_org, lv_ptr); /* need to fill the COW exception table data into the page for disk i/o */ - if (lvm_snapshot_fill_COW_page - (vg_ptr, lv_ptr)) { + if(lvm_snapshot_fill_COW_page(vg_ptr, lv_ptr)) { kfree(lv_ptr); vg_ptr->lv[l] = NULL; return -EINVAL; } - init_waitqueue_head(&lv_ptr-> - lv_snapshot_wait); + init_waitqueue_head(&lv_ptr->lv_snapshot_wait); } else { kfree(lv_ptr); vg_ptr->lv[l] = NULL; @@ -2159,7 +2152,7 @@ vg_ptr->lv[l] = NULL; return -EINVAL; } - } /* if ( vg[VG_CHR(minor)]->lv[l]->lv_access & LV_SNAPSHOT) */ + } /* if ( vg[VG_CHR(minor)]->lv[l]->lv_access & LV_SNAPSHOT) */ lv_ptr = vg_ptr->lv[l]; lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].start_sect = 0; @@ -2187,24 +2180,23 @@ down_write(&org->lv_lock); org->lv_access |= LV_SNAPSHOT_ORG; - lv_ptr->lv_access &= ~LV_SNAPSHOT_ORG; /* this can only hide an userspace bug */ + lv_ptr->lv_access &= ~LV_SNAPSHOT_ORG; /* this can only hide an userspace bug */ /* Link in the list of snapshot volumes */ - for (last = org; last->lv_snapshot_next; - last = last->lv_snapshot_next); + for (last = org; last->lv_snapshot_next; last = last->lv_snapshot_next); lv_ptr->lv_snapshot_prev = last; last->lv_snapshot_next = lv_ptr; up_write(&org->lv_lock); } /* activate the logical volume */ - if (activate) + if(activate) lv_ptr->lv_status |= LV_ACTIVE; else lv_ptr->lv_status &= ~LV_ACTIVE; - if (lv_ptr->lv_access & LV_WRITE) + if ( lv_ptr->lv_access & LV_WRITE) set_device_ro(lv_ptr->lv_dev, 0); else set_device_ro(lv_ptr->lv_dev, 1); @@ -2218,7 +2210,7 @@ lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].de = lvm_fs_create_lv(vg_ptr, lv_ptr); return 0; -} /* lvm_do_lv_create() */ +} /* lvm_do_lv_create() */ /* @@ -2230,6 +2222,9 @@ vg_t *vg_ptr = vg[VG_CHR(minor)]; lv_t *lv_ptr; + if (!vg_ptr) + return -ENXIO; + if (l == -1) { for (l = 0; l < vg_ptr->lv_max; l++) { if (vg_ptr->lv[l] != NULL && @@ -2238,8 +2233,7 @@ } } } - if (l == vg_ptr->lv_max) - return -ENXIO; + if (l == vg_ptr->lv_max) return -ENXIO; lv_ptr = vg_ptr->lv[l]; #ifdef LVM_TOTAL_RESET @@ -2262,12 +2256,11 @@ * Atomically make the the snapshot invisible * to the original lv before playing with it. */ - lv_t *org = lv_ptr->lv_snapshot_org; + lv_t * org = lv_ptr->lv_snapshot_org; down_write(&org->lv_lock); /* remove this snapshot logical volume from the chain */ - lv_ptr->lv_snapshot_prev->lv_snapshot_next = - lv_ptr->lv_snapshot_next; + lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr->lv_snapshot_next; if (lv_ptr->lv_snapshot_next != NULL) { lv_ptr->lv_snapshot_next->lv_snapshot_prev = lv_ptr->lv_snapshot_prev; @@ -2306,7 +2299,7 @@ vg_lv_map[MINOR(lv_ptr->lv_dev)].lv_number = -1; /* correct the PE count in PVs if this is not a snapshot - logical volume */ + logical volume */ if (!(lv_ptr->lv_access & LV_SNAPSHOT)) { /* only if this is no snapshot logical volume because we share the lv_current_pe[] structs with the @@ -2327,15 +2320,13 @@ vg_ptr->lv[l] = NULL; vg_ptr->lv_cur--; return 0; -} /* lvm_do_lv_remove() */ +} /* lvm_do_lv_remove() */ /* * logical volume extend / reduce */ -static int __extend_reduce_snapshot(vg_t * vg_ptr, lv_t * old_lv, - lv_t * new_lv) -{ +static int __extend_reduce_snapshot(vg_t *vg_ptr, lv_t *old_lv, lv_t *new_lv) { ulong size; lv_block_exception_t *lvbe; @@ -2366,8 +2357,7 @@ return 0; } -static int __extend_reduce(vg_t * vg_ptr, lv_t * old_lv, lv_t * new_lv) -{ +static int __extend_reduce(vg_t *vg_ptr, lv_t *old_lv, lv_t *new_lv) { ulong size, l, p, end; pe_t *pe; @@ -2383,7 +2373,7 @@ /* get the PE structures from user space */ if (copy_from_user(pe, new_lv->lv_current_pe, size)) { - if (old_lv->lv_access & LV_SNAPSHOT) + if(old_lv->lv_access & LV_SNAPSHOT) vfree(new_lv->lv_snapshot_hash_table); vfree(pe); return -EFAULT; @@ -2408,7 +2398,7 @@ vg_ptr->pe_allocated++; for (p = 0; p < vg_ptr->pv_cur; p++) { if (vg_ptr->pv[p]->pv_dev == - new_lv->lv_current_pe[l].dev) { + new_lv->lv_current_pe[l].dev) { vg_ptr->pv[p]->pe_allocated++; break; } @@ -2420,30 +2410,25 @@ end = min(old_lv->lv_current_le, new_lv->lv_current_le); for (l = 0; l < end; l++) { new_lv->lv_current_pe[l].reads += - old_lv->lv_current_pe[l].reads; + old_lv->lv_current_pe[l].reads; new_lv->lv_current_pe[l].writes += - old_lv->lv_current_pe[l].writes; + old_lv->lv_current_pe[l].writes; } } else { /* striped logical volume */ - uint i, j, source, dest, end, old_stripe_size, - new_stripe_size; + uint i, j, source, dest, end, old_stripe_size, new_stripe_size; - old_stripe_size = - old_lv->lv_allocated_le / old_lv->lv_stripes; - new_stripe_size = - new_lv->lv_allocated_le / new_lv->lv_stripes; + old_stripe_size = old_lv->lv_allocated_le / old_lv->lv_stripes; + new_stripe_size = new_lv->lv_allocated_le / new_lv->lv_stripes; end = min(old_stripe_size, new_stripe_size); for (i = source = dest = 0; i < new_lv->lv_stripes; i++) { for (j = 0; j < end; j++) { new_lv->lv_current_pe[dest + j].reads += - old_lv->lv_current_pe[source + - j].reads; + old_lv->lv_current_pe[source + j].reads; new_lv->lv_current_pe[dest + j].writes += - old_lv->lv_current_pe[source + - j].writes; + old_lv->lv_current_pe[source + j].writes; } source += old_stripe_size; dest += new_stripe_size; @@ -2453,7 +2438,7 @@ return 0; } -static int lvm_do_lv_extend_reduce(int minor, char *lv_name, lv_t * new_lv) +static int lvm_do_lv_extend_reduce(int minor, char *lv_name, lv_t *new_lv) { int r; ulong l, e, size; @@ -2461,12 +2446,15 @@ lv_t *old_lv; pe_t *pe; + if (!vg_ptr) + return -ENXIO; + if ((pe = new_lv->lv_current_pe) == NULL) return -EINVAL; for (l = 0; l < vg_ptr->lv_max; l++) - if (vg_ptr->lv[l] - && !strcmp(vg_ptr->lv[l]->lv_name, lv_name)) break; + if (vg_ptr->lv[l] && !strcmp(vg_ptr->lv[l]->lv_name, lv_name)) + break; if (l == vg_ptr->lv_max) return -ENXIO; @@ -2476,24 +2464,22 @@ if (old_lv->lv_access & LV_SNAPSHOT) { /* only perform this operation on active snapshots */ if (old_lv->lv_status & LV_ACTIVE) - r = - __extend_reduce_snapshot(vg_ptr, old_lv, - new_lv); + r = __extend_reduce_snapshot(vg_ptr, old_lv, new_lv); else r = -EPERM; } else r = __extend_reduce(vg_ptr, old_lv, new_lv); - if (r) + if(r) return r; /* copy relevent fields */ down_write(&old_lv->lv_lock); - if (new_lv->lv_access & LV_SNAPSHOT) { + if(new_lv->lv_access & LV_SNAPSHOT) { size = (new_lv->lv_remap_end > old_lv->lv_remap_end) ? - old_lv->lv_remap_ptr : new_lv->lv_remap_end; + old_lv->lv_remap_ptr : new_lv->lv_remap_end; size *= sizeof(lv_block_exception_t); memcpy(new_lv->lv_block_exception, old_lv->lv_block_exception, size); @@ -2501,18 +2487,17 @@ old_lv->lv_remap_end = new_lv->lv_remap_end; old_lv->lv_block_exception = new_lv->lv_block_exception; old_lv->lv_snapshot_hash_table = - new_lv->lv_snapshot_hash_table; + new_lv->lv_snapshot_hash_table; old_lv->lv_snapshot_hash_table_size = - new_lv->lv_snapshot_hash_table_size; + new_lv->lv_snapshot_hash_table_size; old_lv->lv_snapshot_hash_mask = - new_lv->lv_snapshot_hash_mask; + new_lv->lv_snapshot_hash_mask; for (e = 0; e < new_lv->lv_remap_ptr; e++) lvm_hash_link(new_lv->lv_block_exception + e, - new_lv->lv_block_exception[e]. - rdev_org, - new_lv->lv_block_exception[e]. - rsector_org, new_lv); + new_lv->lv_block_exception[e].rdev_org, + new_lv->lv_block_exception[e].rsector_org, + new_lv); } else { @@ -2524,26 +2509,24 @@ old_lv->lv_current_le = new_lv->lv_current_le; old_lv->lv_current_pe = new_lv->lv_current_pe; lvm_gendisk.part[MINOR(old_lv->lv_dev)].nr_sects = - old_lv->lv_size; + old_lv->lv_size; lvm_size[MINOR(old_lv->lv_dev)] = old_lv->lv_size >> 1; if (old_lv->lv_access & LV_SNAPSHOT_ORG) { lv_t *snap; - for (snap = old_lv->lv_snapshot_next; snap; - snap = snap->lv_snapshot_next) { + for(snap = old_lv->lv_snapshot_next; snap; + snap = snap->lv_snapshot_next) { down_write(&snap->lv_lock); - snap->lv_current_pe = - old_lv->lv_current_pe; + snap->lv_current_pe = old_lv->lv_current_pe; snap->lv_allocated_le = - old_lv->lv_allocated_le; - snap->lv_current_le = - old_lv->lv_current_le; + old_lv->lv_allocated_le; + snap->lv_current_le = old_lv->lv_current_le; snap->lv_size = old_lv->lv_size; - lvm_gendisk.part[MINOR(snap->lv_dev)]. - nr_sects = old_lv->lv_size; + lvm_gendisk.part[MINOR(snap->lv_dev)].nr_sects + = old_lv->lv_size; lvm_size[MINOR(snap->lv_dev)] = - old_lv->lv_size >> 1; + old_lv->lv_size >> 1; __update_hardsectsize(snap); up_write(&snap->lv_lock); } @@ -2554,13 +2537,13 @@ up_write(&old_lv->lv_lock); return 0; -} /* lvm_do_lv_extend_reduce() */ +} /* lvm_do_lv_extend_reduce() */ /* * character device support function logical volume status by name */ -static int lvm_do_lv_status_byname(vg_t * vg_ptr, void *arg) +static int lvm_do_lv_status_byname(vg_t *vg_ptr, void *arg) { uint l; lv_status_byname_req_t lv_status_byname_req; @@ -2568,206 +2551,181 @@ void *saved_ptr2; lv_t *lv_ptr; - if (vg_ptr == NULL) - return -ENXIO; + if (vg_ptr == NULL) return -ENXIO; if (copy_from_user(&lv_status_byname_req, arg, sizeof(lv_status_byname_req_t)) != 0) return -EFAULT; - if (lv_status_byname_req.lv == NULL) - return -EINVAL; + if (lv_status_byname_req.lv == NULL) return -EINVAL; for (l = 0; l < vg_ptr->lv_max; l++) { if ((lv_ptr = vg_ptr->lv[l]) != NULL && strcmp(lv_ptr->lv_name, lv_status_byname_req.lv_name) == 0) { - /* Save usermode pointers */ - if (copy_from_user - (&saved_ptr1, - &lv_status_byname_req.lv->lv_current_pe, - sizeof(void *)) != 0) - return -EFAULT; - if (copy_from_user - (&saved_ptr2, - &lv_status_byname_req.lv->lv_block_exception, - sizeof(void *)) != 0) + /* Save usermode pointers */ + if (copy_from_user(&saved_ptr1, &lv_status_byname_req.lv->lv_current_pe, sizeof(void*)) != 0) return -EFAULT; - if (copy_to_user(lv_status_byname_req.lv, - lv_ptr, sizeof(lv_t)) != 0) + if (copy_from_user(&saved_ptr2, &lv_status_byname_req.lv->lv_block_exception, sizeof(void*)) != 0) + return -EFAULT; + if (copy_to_user(lv_status_byname_req.lv, + lv_ptr, + sizeof(lv_t)) != 0) return -EFAULT; if (saved_ptr1 != NULL) { if (copy_to_user(saved_ptr1, lv_ptr->lv_current_pe, lv_ptr->lv_allocated_le * - sizeof(pe_t)) != 0) + sizeof(pe_t)) != 0) return -EFAULT; } /* Restore usermode pointers */ - if (copy_to_user - (&lv_status_byname_req.lv->lv_current_pe, - &saved_ptr1, sizeof(void *)) != 0) - return -EFAULT; + if (copy_to_user(&lv_status_byname_req.lv->lv_current_pe, &saved_ptr1, sizeof(void*)) != 0) + return -EFAULT; return 0; } } return -ENXIO; -} /* lvm_do_lv_status_byname() */ +} /* lvm_do_lv_status_byname() */ /* * character device support function logical volume status by index */ -static int lvm_do_lv_status_byindex(vg_t * vg_ptr, void *arg) +static int lvm_do_lv_status_byindex(vg_t *vg_ptr,void *arg) { lv_status_byindex_req_t lv_status_byindex_req; void *saved_ptr1; void *saved_ptr2; lv_t *lv_ptr; - if (vg_ptr == NULL) - return -ENXIO; + if (vg_ptr == NULL) return -ENXIO; if (copy_from_user(&lv_status_byindex_req, arg, sizeof(lv_status_byindex_req)) != 0) return -EFAULT; if (lv_status_byindex_req.lv == NULL) return -EINVAL; - if (lv_status_byindex_req.lv_index < 0 || - lv_status_byindex_req.lv_index >= MAX_LV) - return -EINVAL; - if ((lv_ptr = vg_ptr->lv[lv_status_byindex_req.lv_index]) == NULL) + if ( ( lv_ptr = vg_ptr->lv[lv_status_byindex_req.lv_index]) == NULL) return -ENXIO; /* Save usermode pointers */ - if (copy_from_user - (&saved_ptr1, &lv_status_byindex_req.lv->lv_current_pe, - sizeof(void *)) != 0) - return -EFAULT; - if (copy_from_user - (&saved_ptr2, &lv_status_byindex_req.lv->lv_block_exception, - sizeof(void *)) != 0) - return -EFAULT; + if (copy_from_user(&saved_ptr1, &lv_status_byindex_req.lv->lv_current_pe, sizeof(void*)) != 0) + return -EFAULT; + if (copy_from_user(&saved_ptr2, &lv_status_byindex_req.lv->lv_block_exception, sizeof(void*)) != 0) + return -EFAULT; - if (copy_to_user(lv_status_byindex_req.lv, lv_ptr, sizeof(lv_t)) != - 0) return -EFAULT; + if (copy_to_user(lv_status_byindex_req.lv, lv_ptr, sizeof(lv_t)) != 0) + return -EFAULT; if (saved_ptr1 != NULL) { if (copy_to_user(saved_ptr1, lv_ptr->lv_current_pe, lv_ptr->lv_allocated_le * - sizeof(pe_t)) != 0) return -EFAULT; + sizeof(pe_t)) != 0) + return -EFAULT; } /* Restore usermode pointers */ - if (copy_to_user - (&lv_status_byindex_req.lv->lv_current_pe, &saved_ptr1, - sizeof(void *)) != 0) - return -EFAULT; + if (copy_to_user(&lv_status_byindex_req.lv->lv_current_pe, &saved_ptr1, sizeof(void *)) != 0) + return -EFAULT; return 0; -} /* lvm_do_lv_status_byindex() */ +} /* lvm_do_lv_status_byindex() */ /* * character device support function logical volume status by device number */ -static int lvm_do_lv_status_bydev(vg_t * vg_ptr, void *arg) -{ +static int lvm_do_lv_status_bydev(vg_t * vg_ptr, void * arg) { int l; lv_status_bydev_req_t lv_status_bydev_req; void *saved_ptr1; void *saved_ptr2; lv_t *lv_ptr; - if (vg_ptr == NULL) - return -ENXIO; + if (vg_ptr == NULL) return -ENXIO; if (copy_from_user(&lv_status_bydev_req, arg, sizeof(lv_status_bydev_req)) != 0) return -EFAULT; - for (l = 0; l < vg_ptr->lv_max; l++) { - if (vg_ptr->lv[l] == NULL) - continue; - if (vg_ptr->lv[l]->lv_dev == lv_status_bydev_req.dev) - break; + for ( l = 0; l < vg_ptr->lv_max; l++) { + if ( vg_ptr->lv[l] == NULL) continue; + if ( vg_ptr->lv[l]->lv_dev == lv_status_bydev_req.dev) break; } - if (l == vg_ptr->lv_max) - return -ENXIO; + if ( l == vg_ptr->lv_max) return -ENXIO; lv_ptr = vg_ptr->lv[l]; /* Save usermode pointers */ - if (copy_from_user - (&saved_ptr1, &lv_status_bydev_req.lv->lv_current_pe, - sizeof(void *)) != 0) - return -EFAULT; - if (copy_from_user - (&saved_ptr2, &lv_status_bydev_req.lv->lv_block_exception, - sizeof(void *)) != 0) - return -EFAULT; + if (copy_from_user(&saved_ptr1, &lv_status_bydev_req.lv->lv_current_pe, sizeof(void*)) != 0) + return -EFAULT; + if (copy_from_user(&saved_ptr2, &lv_status_bydev_req.lv->lv_block_exception, sizeof(void*)) != 0) + return -EFAULT; - if (copy_to_user(lv_status_bydev_req.lv, lv_ptr, sizeof(lv_t)) != - 0) return -EFAULT; + if (copy_to_user(lv_status_bydev_req.lv, lv_ptr, sizeof(lv_t)) != 0) + return -EFAULT; if (saved_ptr1 != NULL) { if (copy_to_user(saved_ptr1, lv_ptr->lv_current_pe, lv_ptr->lv_allocated_le * - sizeof(pe_t)) != 0) return -EFAULT; + sizeof(pe_t)) != 0) + return -EFAULT; } /* Restore usermode pointers */ - if (copy_to_user - (&lv_status_bydev_req.lv->lv_current_pe, &saved_ptr1, - sizeof(void *)) != 0) - return -EFAULT; + if (copy_to_user(&lv_status_bydev_req.lv->lv_current_pe, &saved_ptr1, sizeof(void *)) != 0) + return -EFAULT; return 0; -} /* lvm_do_lv_status_bydev() */ +} /* lvm_do_lv_status_bydev() */ /* * character device support function rename a logical volume */ -static int lvm_do_lv_rename(vg_t * vg_ptr, lv_req_t * lv_req, lv_t * lv) +static int lvm_do_lv_rename(vg_t *vg_ptr, lv_req_t *lv_req, lv_t *lv) { int l = 0; int ret = 0; lv_t *lv_ptr = NULL; - for (l = 0; l < vg_ptr->lv_max; l++) { - if ((lv_ptr = vg_ptr->lv[l]) == NULL) - continue; - if (lv_ptr->lv_dev == lv->lv_dev) { + if (!vg_ptr) + return -ENXIO; + + for (l = 0; l < vg_ptr->lv_max; l++) + { + if ( (lv_ptr = vg_ptr->lv[l]) == NULL) continue; + if (lv_ptr->lv_dev == lv->lv_dev) + { lvm_fs_remove_lv(vg_ptr, lv_ptr); - strncpy(lv_ptr->lv_name, lv_req->lv_name, - NAME_LEN); + strncpy(lv_ptr->lv_name, lv_req->lv_name, NAME_LEN); lvm_fs_create_lv(vg_ptr, lv_ptr); break; } } - if (l == vg_ptr->lv_max) - ret = -ENODEV; + if (l == vg_ptr->lv_max) ret = -ENODEV; return ret; -} /* lvm_do_lv_rename */ +} /* lvm_do_lv_rename */ /* * character device support function physical volume change */ -static int lvm_do_pv_change(vg_t * vg_ptr, void *arg) +static int lvm_do_pv_change(vg_t *vg_ptr, void *arg) { uint p; pv_t *pv_ptr; struct block_device *bd; - if (vg_ptr == NULL) - return -ENXIO; + if (vg_ptr == NULL) return -ENXIO; if (copy_from_user(&pv_change_req, arg, - sizeof(pv_change_req)) != 0) return -EFAULT; + sizeof(pv_change_req)) != 0) + return -EFAULT; for (p = 0; p < vg_ptr->pv_max; p++) { pv_ptr = vg_ptr->pv[p]; if (pv_ptr != NULL && - strcmp(pv_ptr->pv_name, pv_change_req.pv_name) == 0) { + strcmp(pv_ptr->pv_name, + pv_change_req.pv_name) == 0) { bd = pv_ptr->bd; if (copy_from_user(pv_ptr, @@ -2783,33 +2741,35 @@ } } return -ENXIO; -} /* lvm_do_pv_change() */ +} /* lvm_do_pv_change() */ /* * character device support function get physical volume status */ -static int lvm_do_pv_status(vg_t * vg_ptr, void *arg) +static int lvm_do_pv_status(vg_t *vg_ptr, void *arg) { uint p; pv_t *pv_ptr; - if (vg_ptr == NULL) - return -ENXIO; + if (vg_ptr == NULL) return -ENXIO; if (copy_from_user(&pv_status_req, arg, - sizeof(pv_status_req)) != 0) return -EFAULT; + sizeof(pv_status_req)) != 0) + return -EFAULT; for (p = 0; p < vg_ptr->pv_max; p++) { pv_ptr = vg_ptr->pv[p]; if (pv_ptr != NULL && - strcmp(pv_ptr->pv_name, pv_status_req.pv_name) == 0) { + strcmp(pv_ptr->pv_name, + pv_status_req.pv_name) == 0) { if (copy_to_user(pv_status_req.pv, - pv_ptr, sizeof(pv_t)) != 0) + pv_ptr, + sizeof(pv_t)) != 0) return -EFAULT; return 0; } } return -ENXIO; -} /* lvm_do_pv_status() */ +} /* lvm_do_pv_status() */ /* @@ -2851,15 +2811,13 @@ hardsect_size[MAJOR_NR] = lvm_hardsectsizes; return; -} /* lvm_gen_init() */ +} /* lvm_gen_init() */ /* Must have down_write(_pe_lock) when we enqueue buffers */ -static void _queue_io(struct buffer_head *bh, int rw) -{ - if (bh->b_reqnext) - BUG(); +static void _queue_io(struct buffer_head *bh, int rw) { + if (bh->b_reqnext) BUG(); bh->b_reqnext = _pe_requests; _pe_requests = bh; } @@ -2897,15 +2855,14 @@ /* * we must open the pv's before we use them */ -static int _open_pv(pv_t * pv) -{ +static int _open_pv(pv_t *pv) { int err; struct block_device *bd; if (!(bd = bdget(kdev_t_to_nr(pv->pv_dev)))) return -ENOMEM; - err = blkdev_get(bd, FMODE_READ | FMODE_WRITE, 0, BDEV_FILE); + err = blkdev_get(bd, FMODE_READ|FMODE_WRITE, 0, BDEV_FILE); if (err) return err; @@ -2913,8 +2870,7 @@ return 0; } -static void _close_pv(pv_t * pv) -{ +static void _close_pv(pv_t *pv) { if (pv) { struct block_device *bdev = pv->bd; pv->bd = NULL; @@ -2926,7 +2882,7 @@ static unsigned long _sectors_to_k(unsigned long sect) { - if (SECTOR_SIZE > 1024) { + if(SECTOR_SIZE > 1024) { return sect * (SECTOR_SIZE / 1024); } diff -u -r linux-2.4.19-rc3.orig/include/linux/lvm.h linux-2.4.19-rc3/include/linux/lvm.h --- linux-2.4.19-rc3.orig/include/linux/lvm.h Thu Jul 25 13:05:18 2002 +++ linux-2.4.19-rc3/include/linux/lvm.h Thu Jul 25 13:46:01 2002 @@ -3,13 +3,14 @@ * kernel/lvm.h * tools/lib/lvm.h * - * Copyright (C) 1997 - 2001 Heinz Mauelshagen, Sistina Software + * Copyright (C) 1997 - 2002 Heinz Mauelshagen, Sistina Software * * February-November 1997 * May-July 1998 * January-March,July,September,October,Dezember 1999 * January,February,July,November 2000 * January-March,June,July 2001 + * May 2002 * * lvm is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -79,8 +80,8 @@ #ifndef _LVM_H_INCLUDE #define _LVM_H_INCLUDE -#define LVM_RELEASE_NAME "1.0.3" -#define LVM_RELEASE_DATE "19/02/2002" +#define LVM_RELEASE_NAME "1.0.5+" +#define LVM_RELEASE_DATE "22/07/2002" #define _LVM_KERNEL_H_VERSION "LVM "LVM_RELEASE_NAME" ("LVM_RELEASE_DATE")" @@ -208,40 +209,35 @@ /* * VGDA: default disk spaces and offsets * - * There's space after the structures for later extensions. - * The physical volume structure holds offset and size definitions - * for itself (well, kind of redundant ;-) and all other structure{s| arrays}; - * - * In recent versions since LVM 0.9.1 we align to 4k offsets in order to ease - * future kernel reads of the metadata. - * - * offset what size - * --------------- -------------------------------- ------------ - * 0 physical volume structure pv->pv_on_disk.size - * (~500 byte) - * pv->vg_on_disk.base volume group structure pv->vg_on_disk.size - * - * pv->uuidlist_on_disk.base 128 byte each - * uuidlist of physical volumes - * holding one uuid per physical volume + * there's space after the structures for later extensions. * - * pv->lv_on_disk.base logical volume structures; pv->lv_on_disk.size - * one structure per logical volume (~300 byte each) + * offset what size + * --------------- ---------------------------------- ------------ + * 0 physical volume structure ~500 byte * - * pv->pe_on_disk.base physical extent alloc. structs pv->pe_on_disk.size - * one strcuture per physical extent (4 byte each) + * 1K volume group structure ~200 byte * - * End of disk - first physical extent default 4 megabyte + * 6K namelist of physical volumes 128 byte each + * + * 6k + n * ~300byte n logical volume structures ~300 byte each + * + * + m * 4byte m physical extent alloc. structs 4 byte each + * + * End of disk - first physical extent typically 4 megabyte * PE total * * PE size - * (rounded to 64k offset today) * - * pv->pe_on_disk.base + pv->pe_on_disk.size == start of first physical extent * */ /* DONT TOUCH THESE !!! */ + + + + + + /* * LVM_PE_T_MAX corresponds to: * @@ -253,7 +249,7 @@ * * Maximum PE size of 16GB gives a maximum logical volume size of 1024 TB. * - * AFAIK, the actual kernels limit this to 2 TB. + * AFAIK, the actual kernels limit this to 1 TB. * * Should be a sufficient spectrum ;*) */ @@ -273,7 +269,7 @@ #define LVM_MAX_MIRRORS 2 /* future use */ #define LVM_MIN_READ_AHEAD 0 /* minimum read ahead sectors */ #define LVM_DEFAULT_READ_AHEAD 1024 /* sectors for 512k scsi segments */ -#define LVM_MAX_READ_AHEAD 10000 /* maximum read ahead sectors */ +#define LVM_MAX_READ_AHEAD 1024 /* maximum read ahead sectors */ #define LVM_MAX_LV_IO_TIMEOUT 60 /* seconds I/O timeout (future use) */ #define LVM_PARTITION 0xfe /* LVM partition id */ #define LVM_NEW_PARTITION 0x8e /* new LVM partition id (10/09/1999) */