finally i have found the time to forwardport this patch that fixes the
sizeof(lv_t) differeneces between user and kernelspace which caused
memorycorruption in the userspace-tools. The interface is kept unchanged.
By having another (smaller) lv_t exported to userspace (userlv_t) it also
removes a allocation of a >4k lv_t-object on the stack in the ioctls, which
i overlooked in the last patch. Running kernel with this patch right now,
and ioctls tested under uml.
The patch is fairly large, but most changes are just adding the
u.-substructure, the changes are just in lvm-files and it fixes crashes in
the userspacetools.
--//anders/g
--- linux-2.5.2-pre9-uml/drivers/md/lvm-fs.c Sun Jan 6 18:10:19 2002 +++ linux-2.5.2-pre9-uml-lvm/drivers/md/lvm-fs.c Sun Jan 6 21:58:39 2002 @@ -170,11 +170,11 @@ 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 = _basename(lv->u.lv_name); - lv_devfs_handle[minor(lv->lv_dev)] = devfs_register( + lv_devfs_handle[minor(lv->u.lv_dev)] = devfs_register( vg_devfs_handle[vg_ptr->vg_number], name, - DEVFS_FL_DEFAULT, LVM_BLK_MAJOR, minor(lv->lv_dev), + DEVFS_FL_DEFAULT, LVM_BLK_MAJOR, minor(lv->u.lv_dev), S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, &lvm_blk_dops, NULL); @@ -183,15 +183,15 @@ pde->read_proc = _proc_read_lv; pde->data = lv; } - return lv_devfs_handle[minor(lv->lv_dev)]; + return lv_devfs_handle[minor(lv->u.lv_dev)]; } void lvm_fs_remove_lv(vg_t *vg_ptr, lv_t *lv) { - devfs_unregister(lv_devfs_handle[minor(lv->lv_dev)]); - lv_devfs_handle[minor(lv->lv_dev)] = NULL; + devfs_unregister(lv_devfs_handle[minor(lv->u.lv_dev)]); + lv_devfs_handle[minor(lv->u.lv_dev)] = NULL; if(vg_ptr->lv_subdir_pde) { - const char *name = _basename(lv->lv_name); + const char *name = _basename(lv->u.lv_name); remove_proc_entry(name, vg_ptr->lv_subdir_pde); } } @@ -269,21 +269,21 @@ int sz = 0; lv_t *lv = data; - sz += sprintf(page + sz, "name: %s\n", lv->lv_name); - sz += sprintf(page + sz, "size: %u\n", lv->lv_size); - sz += sprintf(page + sz, "access: %u\n", lv->lv_access); - sz += sprintf(page + sz, "status: %u\n", lv->lv_status); - sz += sprintf(page + sz, "number: %u\n", lv->lv_number); - sz += sprintf(page + sz, "open: %u\n", lv->lv_open); - sz += sprintf(page + sz, "allocation: %u\n", lv->lv_allocation); - if(lv->lv_stripes > 1) { + sz += sprintf(page + sz, "name: %s\n", lv->u.lv_name); + sz += sprintf(page + sz, "size: %u\n", lv->u.lv_size); + sz += sprintf(page + sz, "access: %u\n", lv->u.lv_access); + sz += sprintf(page + sz, "status: %u\n", lv->u.lv_status); + sz += sprintf(page + sz, "number: %u\n", lv->u.lv_number); + sz += sprintf(page + sz, "open: %u\n", lv->u.lv_open); + sz += sprintf(page + sz, "allocation: %u\n", lv->u.lv_allocation); + if(lv->u.lv_stripes > 1) { sz += sprintf(page + sz, "stripes: %u\n", - lv->lv_stripes); + lv->u.lv_stripes); sz += sprintf(page + sz, "stripesize: %u\n", - lv->lv_stripesize); + lv->u.lv_stripesize); } sz += sprintf(page + sz, "device: %02u:%02u\n", - major(lv->lv_dev), minor(lv->lv_dev)); + major(lv->u.lv_dev), minor(lv->u.lv_dev)); return sz; } @@ -350,13 +350,13 @@ if (vg_ptr->lv_cur > 0) { for (l = 0; l < vg[v]->lv_max; l++) { if ((lv_ptr = vg_ptr->lv[l]) != NULL) { - pe_t_bytes += lv_ptr->lv_allocated_le; + pe_t_bytes += lv_ptr->u.lv_allocated_le; hash_table_bytes += lv_ptr->lv_snapshot_hash_table_size; - if (lv_ptr->lv_block_exception != NULL) - lv_block_exception_t_bytes += lv_ptr->lv_remap_end; - if (lv_ptr->lv_open > 0) { + if (lv_ptr->u.lv_block_exception != NULL) + lv_block_exception_t_bytes += lv_ptr->u.lv_remap_end; + if (lv_ptr->u.lv_open > 0) { lv_open_counter++; - lv_open_total += lv_ptr->lv_open; + lv_open_total += lv_ptr->u.lv_open; } } } @@ -532,16 +532,16 @@ char inactive_flag = 'A', allocation_flag = ' ', stripes_flag = ' ', rw_flag = ' ', *basename; - if (!(lv_ptr->lv_status & LV_ACTIVE)) + if (!(lv_ptr->u.lv_status & LV_ACTIVE)) inactive_flag = 'I'; rw_flag = 'R'; - if (lv_ptr->lv_access & LV_WRITE) + if (lv_ptr->u.lv_access & LV_WRITE) rw_flag = 'W'; allocation_flag = 'D'; - if (lv_ptr->lv_allocation & LV_CONTIGUOUS) + if (lv_ptr->u.lv_allocation & LV_CONTIGUOUS) allocation_flag = 'C'; stripes_flag = 'L'; - if (lv_ptr->lv_stripes > 1) + if (lv_ptr->u.lv_stripes > 1) stripes_flag = 'S'; sz += sprintf(buf+sz, "[%c%c%c%c", @@ -549,29 +549,29 @@ rw_flag, allocation_flag, stripes_flag); - if (lv_ptr->lv_stripes > 1) + if (lv_ptr->u.lv_stripes > 1) sz += sprintf(buf+sz, "%-2d", - lv_ptr->lv_stripes); + lv_ptr->u.lv_stripes); else sz += sprintf(buf+sz, " "); /* FIXME: use _basename */ - basename = strrchr(lv_ptr->lv_name, '/'); - if ( basename == 0) basename = lv_ptr->lv_name; + basename = strrchr(lv_ptr->u.lv_name, '/'); + if ( basename == 0) basename = lv_ptr->u.lv_name; else basename++; sz += sprintf(buf+sz, "] %-25s", basename); if (strlen(basename) > 25) sz += sprintf(buf+sz, "\n "); sz += sprintf(buf+sz, "%9d /%-6d ", - lv_ptr->lv_size >> 1, - lv_ptr->lv_size / vg_ptr->pe_size); + lv_ptr->u.lv_size >> 1, + lv_ptr->u.lv_size / vg_ptr->pe_size); - if (lv_ptr->lv_open == 0) + if (lv_ptr->u.lv_open == 0) sz += sprintf(buf+sz, "close"); else sz += sprintf(buf+sz, "%dx open", - lv_ptr->lv_open); + lv_ptr->u.lv_open); return sz; } --- linux-2.5.2-pre9-uml/drivers/md/lvm-snap.c Sun Jan 6 18:10:19 2002 +++ linux-2.5.2-pre9-uml-lvm/drivers/md/lvm-snap.c Sun Jan 6 21:48:08 2002 @@ -93,7 +93,7 @@ { struct list_head * hash_table = lv->lv_snapshot_hash_table, * next; unsigned long mask = lv->lv_snapshot_hash_mask; - int chunk_size = lv->lv_chunk_size; + int chunk_size = lv->u.lv_chunk_size; lv_block_exception_t * ret; int i = 0; @@ -127,7 +127,7 @@ { struct list_head * hash_table = lv->lv_snapshot_hash_table; unsigned long mask = lv->lv_snapshot_hash_mask; - int chunk_size = lv->lv_chunk_size; + int chunk_size = lv->u.lv_chunk_size; hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)]; list_add(&exception->hash, hash_table); @@ -139,7 +139,7 @@ int ret; unsigned long pe_off, pe_adjustment, __org_start; kdev_t __org_dev; - int chunk_size = lv->lv_chunk_size; + int chunk_size = lv->u.lv_chunk_size; lv_block_exception_t * exception; pe_off = pe_start % chunk_size; @@ -164,26 +164,26 @@ /* no exception storage space available for this snapshot or error on this snapshot --> release it */ - invalidate_buffers(lv_snap->lv_dev); + invalidate_buffers(lv_snap->u.lv_dev); /* wipe the snapshot since it's inconsistent now */ _disable_snapshot(vg, lv_snap); last_dev = NODEV; - for (i = 0; i < lv_snap->lv_remap_ptr; i++) { - if ( !kdev_same(lv_snap->lv_block_exception[i].rdev_new, + for (i = 0; i < lv_snap->u.lv_remap_ptr; i++) { + if ( !kdev_same(lv_snap->u.lv_block_exception[i].rdev_new, last_dev)) { - last_dev = lv_snap->lv_block_exception[i].rdev_new; + last_dev = lv_snap->u.lv_block_exception[i].rdev_new; invalidate_buffers(last_dev); } } lvm_snapshot_release(lv_snap); - lv_snap->lv_status &= ~LV_ACTIVE; + lv_snap->u.lv_status &= ~LV_ACTIVE; printk(KERN_INFO "%s -- giving up to snapshot %s on %s: %s\n", - lvm_name, lv_snap->lv_snapshot_org->lv_name, lv_snap->lv_name, + lvm_name, lv_snap->u.lv_snapshot_org->u.lv_name, lv_snap->u.lv_name, reason); } @@ -234,7 +234,7 @@ int lvm_snapshot_fill_COW_page(vg_t * vg, lv_t * lv_snap) { uint pvn; - int id = 0, is = lv_snap->lv_remap_ptr; + int id = 0, is = lv_snap->u.lv_remap_ptr; ulong blksize_snap; lv_COW_table_disk_t * lv_COW_table = (lv_COW_table_disk_t *) page_address(lv_snap->lv_COW_table_iobuf->maplist[0]); @@ -244,13 +244,13 @@ is--; blksize_snap = - block_size(lv_snap->lv_block_exception[is].rdev_new); + block_size(lv_snap->u.lv_block_exception[is].rdev_new); is -= is % (blksize_snap / sizeof(lv_COW_table_disk_t)); memset(lv_COW_table, 0, blksize_snap); - for ( ; is < lv_snap->lv_remap_ptr; is++, id++) { + for ( ; is < lv_snap->u.lv_remap_ptr; is++, id++) { /* store new COW_table entry */ - lv_block_exception_t *be = lv_snap->lv_block_exception + is; + lv_block_exception_t *be = lv_snap->u.lv_block_exception + is; if(_pv_get_number(vg, be->rdev_org, &pvn)) goto bad; @@ -281,7 +281,7 @@ int r; const char *err; if((r = _write_COW_table_block(vg, lv_snap, - lv_snap->lv_remap_ptr - 1, &err))) + lv_snap->u.lv_remap_ptr - 1, &err))) lvm_drop_snapshot(vg, lv_snap, err); return r; } @@ -303,13 +303,13 @@ const char * reason; kdev_t snap_phys_dev; unsigned long org_start, snap_start, virt_start, pe_off; - int idx = lv_snap->lv_remap_ptr, chunk_size = lv_snap->lv_chunk_size; + int idx = lv_snap->u.lv_remap_ptr, chunk_size = lv_snap->u.lv_chunk_size; struct kiobuf * iobuf; int blksize_snap, blksize_org, min_blksize, max_blksize; int max_sectors, nr_sectors; /* check if we are out of snapshot space */ - if (idx >= lv_snap->lv_remap_end) + if (idx >= lv_snap->u.lv_remap_end) goto fail_out_of_space; /* calculate physical boundaries of source chunk */ @@ -318,8 +318,8 @@ virt_start = org_virt_sector - (org_phys_sector - org_start); /* calculate physical boundaries of destination chunk */ - snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new; - snap_start = lv_snap->lv_block_exception[idx].rsector_new; + snap_phys_dev = lv_snap->u.lv_block_exception[idx].rdev_new; + snap_start = lv_snap->u.lv_block_exception[idx].rsector_new; #ifdef DEBUG_SNAPSHOT printk(KERN_INFO @@ -371,20 +371,20 @@ #ifdef DEBUG_SNAPSHOT /* invalidate the logical snapshot buffer cache */ - invalidate_snap_cache(virt_start, lv_snap->lv_chunk_size, - lv_snap->lv_dev); + invalidate_snap_cache(virt_start, lv_snap->u.lv_chunk_size, + lv_snap->u.lv_dev); #endif /* the original chunk is now stored on the snapshot volume so update the execption table */ - lv_snap->lv_block_exception[idx].rdev_org = org_phys_dev; - lv_snap->lv_block_exception[idx].rsector_org = org_start; + lv_snap->u.lv_block_exception[idx].rdev_org = org_phys_dev; + lv_snap->u.lv_block_exception[idx].rsector_org = org_start; - lvm_hash_link(lv_snap->lv_block_exception + idx, + lvm_hash_link(lv_snap->u.lv_block_exception + idx, org_phys_dev, org_start, lv_snap); - lv_snap->lv_remap_ptr = idx + 1; + lv_snap->u.lv_remap_ptr = idx + 1; if (lv_snap->lv_snapshot_use_rate > 0) { - if (lv_snap->lv_remap_ptr * 100 / lv_snap->lv_remap_end >= lv_snap->lv_snapshot_use_rate) + if (lv_snap->u.lv_remap_ptr * 100 / lv_snap->u.lv_remap_end >= lv_snap->lv_snapshot_use_rate) wake_up_interruptible(&lv_snap->lv_snapshot_wait); } return 0; @@ -462,7 +462,7 @@ unsigned long buckets, max_buckets, size; struct list_head * hash; - buckets = lv->lv_remap_end; + buckets = lv->u.lv_remap_end; max_buckets = calc_max_buckets(); buckets = min(buckets, max_buckets); while (buckets & (buckets-1)) @@ -531,10 +531,10 @@ void lvm_snapshot_release(lv_t * lv) { - if (lv->lv_block_exception) + if (lv->u.lv_block_exception) { - vfree(lv->lv_block_exception); - lv->lv_block_exception = NULL; + vfree(lv->u.lv_block_exception); + lv->u.lv_block_exception = NULL; } if (lv->lv_snapshot_hash_table) { @@ -578,8 +578,8 @@ COW_entries_per_pe = LVM_GET_COW_TABLE_ENTRIES_PER_PE(vg, lv_snap); /* get physical addresse of destination chunk */ - snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new; - snap_pe_start = lv_snap->lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->lv_chunk_size; + snap_phys_dev = lv_snap->u.lv_block_exception[idx].rdev_new; + snap_pe_start = lv_snap->u.lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->u.lv_chunk_size; blksize_snap = block_size(snap_phys_dev); @@ -595,7 +595,7 @@ blocks[0] = (snap_pe_start + COW_table_sector_offset) >> (blksize_snap >> 10); /* store new COW_table entry */ - be = lv_snap->lv_block_exception + idx; + be = lv_snap->u.lv_block_exception + idx; if(_pv_get_number(vg, be->rdev_org, &pvn)) goto fail_pv_get_number; @@ -620,15 +620,15 @@ if (idx_COW_table % COW_entries_per_block == COW_entries_per_block - 1 || end_of_table) { /* don't go beyond the end */ - if (idx + 1 >= lv_snap->lv_remap_end) goto out; + if (idx + 1 >= lv_snap->u.lv_remap_end) goto out; memset(lv_COW_table, 0, blksize_snap); if (end_of_table) { idx++; - snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new; - snap_pe_start = lv_snap->lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->lv_chunk_size; + snap_phys_dev = lv_snap->u.lv_block_exception[idx].rdev_new; + snap_pe_start = lv_snap->u.lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->u.lv_chunk_size; blksize_snap = block_size(snap_phys_dev); blocks[0] = snap_pe_start >> (blksize_snap >> 10); } else blocks[0]++; @@ -664,7 +664,7 @@ static void _disable_snapshot(vg_t *vg, lv_t *lv) { const char *err; - lv->lv_block_exception[0].rsector_org = LVM_SNAPSHOT_DROPPED_SECTOR; + lv->u.lv_block_exception[0].rsector_org = LVM_SNAPSHOT_DROPPED_SECTOR; if(_write_COW_table_block(vg, lv, 0, &err) < 0) { printk(KERN_ERR "%s -- couldn't disable snapshot: %s\n", lvm_name, err); --- linux-2.5.2-pre9-uml/drivers/md/lvm.c Sun Jan 6 18:10:19 2002 +++ linux-2.5.2-pre9-uml-lvm/drivers/md/lvm.c Mon Jan 7 22:00:45 2002 @@ -182,6 +182,9 @@ * 28/12/2001 - buffer_head -> bio * removed huge allocation of a lv_t on stack * (Anders Gustafsson) + * 07/01/2002 - fixed sizeof(lv_t) differences in user/kernel-space + * removed another huge allocation of a lv_t on stack + * (Anders Gustafsson) * */ @@ -270,10 +273,10 @@ static int lvm_do_pv_create(pv_t *, vg_t *, ulong); static int lvm_do_pv_remove(vg_t *, ulong); -static int lvm_do_lv_create(int, char *, lv_t *); -static int lvm_do_lv_extend_reduce(int, char *, lv_t *); +static int lvm_do_lv_create(int, char *, userlv_t *); +static int lvm_do_lv_extend_reduce(int, char *, userlv_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_rename(vg_t *, lv_req_t *, userlv_t *); 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 *); @@ -549,7 +552,7 @@ int minor = minor(inode->i_rdev); uint extendable, l, v; void *arg = (void *) a; - lv_t lv; + userlv_t ulv; vg_t* vg_ptr = vg[VG_CHR(minor)]; /* otherwise cc will complain about unused variables */ @@ -685,21 +688,21 @@ return -EFAULT; if (command != LV_REMOVE) { - if (copy_from_user(&lv, lv_req.lv, sizeof(lv_t)) != 0) + if (copy_from_user(&ulv, lv_req.lv, sizeof(userlv_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, &ulv); 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, &ulv); case LV_REMOVE: return lvm_do_lv_remove(minor, lv_req.lv_name, -1); case LV_RENAME: - return lvm_do_lv_rename(vg_ptr, &lv_req, &lv); + return lvm_do_lv_rename(vg_ptr, &lv_req, &ulv); } @@ -811,27 +814,27 @@ 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->u.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))) + (!(lv_ptr->u.lv_status & LV_ACTIVE))) return -EPERM; - if (!(lv_ptr->lv_access & LV_WRITE) && + if (!(lv_ptr->u.lv_access & LV_WRITE) && (file->f_mode & FMODE_WRITE)) return -EACCES; /* be sure to increment VG counter */ - if (lv_ptr->lv_open == 0) vg_ptr->lv_open++; - lv_ptr->lv_open++; + if (lv_ptr->u.lv_open == 0) vg_ptr->lv_open++; + lv_ptr->u.lv_open++; MOD_INC_USE_COUNT; - P_DEV("blk_open OK, LV size %d\n", lv_ptr->lv_size); + P_DEV("blk_open OK, LV size %d\n", lv_ptr->u.lv_size); return 0; } @@ -862,13 +865,13 @@ case BLKGETSIZE: /* return device size */ - P_IOCTL("BLKGETSIZE: %u\n", lv_ptr->lv_size); - if (put_user(lv_ptr->lv_size, (unsigned long *)arg)) + P_IOCTL("BLKGETSIZE: %u\n", lv_ptr->u.lv_size); + if (put_user(lv_ptr->u.lv_size, (unsigned long *)arg)) return -EFAULT; break; case BLKGETSIZE64: - if (put_user((u64)lv_ptr->lv_size << 9, (u64 *)arg)) + if (put_user((u64)lv_ptr->u.lv_size << 9, (u64 *)arg)) return -EFAULT; break; @@ -894,14 +897,14 @@ if ((long) arg < LVM_MIN_READ_AHEAD || (long) arg > LVM_MAX_READ_AHEAD) return -EINVAL; - lv_ptr->lv_read_ahead = (long) arg; + lv_ptr->u.lv_read_ahead = (long) arg; break; 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)) + P_IOCTL("BLKRAGET %d\n", lv_ptr->u.lv_read_ahead); + if (put_user(lv_ptr->u.lv_read_ahead, (long *)arg)) return -EFAULT; break; @@ -915,7 +918,7 @@ unsigned char heads = 64; unsigned char sectors = 32; long start = 0; - short cylinders = lv_ptr->lv_size / heads / sectors; + short cylinders = lv_ptr->u.lv_size / heads / sectors; if (copy_to_user((char *) &hd->heads, &heads, sizeof(heads)) != 0 || @@ -936,26 +939,26 @@ 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); + lv_ptr->u.lv_access = (ulong) arg; + if ( lv_ptr->u.lv_access & LV_WRITE) + set_device_ro(lv_ptr->u.lv_dev, 0); else - set_device_ro(lv_ptr->lv_dev, 1); + set_device_ro(lv_ptr->u.lv_dev, 1); 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) + if (!((ulong) arg & LV_ACTIVE) && lv_ptr->u.lv_open > 1) return -EPERM; - lv_ptr->lv_status = (ulong) arg; + lv_ptr->u.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) + if(lv_ptr->u.lv_access & LV_SNAPSHOT) return -EPERM; return lvm_user_bmap(inode, (struct lv_bmap *) arg); @@ -963,7 +966,7 @@ case LV_SET_ALLOCATION: /* set allocation flags of a logical volume */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; - lv_ptr->lv_allocation = (ulong) arg; + lv_ptr->u.lv_allocation = (ulong) arg; break; case LV_SNAPSHOT_USE_RATE: @@ -992,8 +995,8 @@ 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--; - lv_ptr->lv_open--; + if (lv_ptr->u.lv_open == 1) vg_ptr->lv_open--; + lv_ptr->u.lv_open--; MOD_DEC_USE_COUNT; @@ -1004,7 +1007,7 @@ { lv_snapshot_use_rate_req_t lv_rate_req; - if (!(lv->lv_access & LV_SNAPSHOT)) + if (!(lv->u.lv_access & LV_SNAPSHOT)) return -EPERM; if (copy_from_user(&lv_rate_req, arg, sizeof(lv_rate_req))) @@ -1016,7 +1019,7 @@ switch (lv_rate_req.block) { case 0: lv->lv_snapshot_use_rate = lv_rate_req.rate; - if (lv->lv_remap_ptr * 100 / lv->lv_remap_end < + if (lv->u.lv_remap_ptr * 100 / lv->u.lv_remap_end < lv->lv_snapshot_use_rate) interruptible_sleep_on(&lv->lv_snapshot_wait); break; @@ -1027,7 +1030,7 @@ default: return -EINVAL; } - lv_rate_req.rate = lv->lv_remap_ptr * 100 / lv->lv_remap_end; + lv_rate_req.rate = lv->u.lv_remap_ptr * 100 / lv->u.lv_remap_end; return copy_to_user(arg, &lv_rate_req, sizeof(lv_rate_req)) ? -EFAULT : 0; @@ -1044,7 +1047,7 @@ memset(&bio,0,sizeof(bio)); bio.bi_dev = inode->i_rdev; - bio.bi_size = lvm_get_blksize(bio.bi_dev); /* NEEDED by bio_sectors */ + bio.bi_size = block_size(bio.bi_dev); /* NEEDED by bio_sectors */ bio.bi_sector = block * bio_sectors(&bio); bio.bi_rw = READ; if ((err=lvm_map(&bio)) < 0) { @@ -1134,18 +1137,18 @@ int rw = bio_rw(bi); down_read(&lv->lv_lock); - if (!(lv->lv_status & LV_ACTIVE)) { + if (!(lv->u.lv_status & LV_ACTIVE)) { printk(KERN_ALERT "%s - lvm_map: ll_rw_blk for inactive LV %s\n", - lvm_name, lv->lv_name); + lvm_name, lv->u.lv_name); goto bad; } if ((rw == WRITE || rw == WRITEA) && - !(lv->lv_access & LV_WRITE)) { + !(lv->u.lv_access & LV_WRITE)) { printk(KERN_CRIT "%s - lvm_map: ll_rw_blk write for readonly LV %s\n", - lvm_name, lv->lv_name); + lvm_name, lv->u.lv_name); goto bad; } @@ -1154,7 +1157,7 @@ kdevname(bi->bi_dev), rsector_org, size); - if (rsector_org + size > lv->lv_size) { + if (rsector_org + size > lv->u.lv_size) { printk(KERN_ALERT "%s - lvm_map access beyond end of device; *rsector: " "%lu or size: %lu wrong for minor: %2d\n", @@ -1163,39 +1166,39 @@ } - if (lv->lv_stripes < 2) { /* linear mapping */ + if (lv->u.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 + + pe_start = lv->u.lv_current_pe[index].pe; + rsector_map = lv->u.lv_current_pe[index].pe + (rsector_org % vg_this->pe_size); - rdev_map = lv->lv_current_pe[index].dev; + rdev_map = lv->u.lv_current_pe[index].dev; - P_MAP("lv_current_pe[%ld].pe: %d rdev: %s rsector:%ld\n", - index, lv->lv_current_pe[index].pe, + P_MAP("u.lv_current_pe[%ld].pe: %d rdev: %s rsector:%ld\n", + index, lv->u.lv_current_pe[index].pe, kdevname(rdev_map), rsector_map); } else { /* striped mapping */ ulong stripe_index; ulong stripe_length; - stripe_length = vg_this->pe_size * lv->lv_stripes; + stripe_length = vg_this->pe_size * lv->u.lv_stripes; stripe_index = (rsector_org % stripe_length) / - lv->lv_stripesize; + lv->u.lv_stripesize; index = rsector_org / stripe_length + - (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 + + (stripe_index % lv->u.lv_stripes) * + (lv->u.lv_allocated_le / lv->u.lv_stripes); + pe_start = lv->u.lv_current_pe[index].pe; + rsector_map = lv->u.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; - rdev_map = lv->lv_current_pe[index].dev; + (stripe_index % lv->u.lv_stripes) * lv->u.lv_stripesize - + stripe_index / lv->u.lv_stripes * + (lv->u.lv_stripes - 1) * lv->u.lv_stripesize; + rdev_map = lv->u.lv_current_pe[index].dev; - P_MAP("lv_current_pe[%ld].pe: %d rdev: %s rsector:%ld\n" + P_MAP("u.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), + index, lv->u.lv_current_pe[index].pe, kdevname(rdev_map), rsector_map, stripe_length, stripe_index); } @@ -1212,16 +1215,16 @@ return 0; } - lv->lv_current_pe[index].writes++; /* statistic */ + lv->u.lv_current_pe[index].writes++; /* statistic */ } else - lv->lv_current_pe[index].reads++; /* statistic */ + lv->u.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->u.lv_access & (LV_SNAPSHOT|LV_SNAPSHOT_ORG))) goto out; - if (lv->lv_access & LV_SNAPSHOT) { /* remap snapshot */ - if (lv->lv_block_exception) + if (lv->u.lv_access & LV_SNAPSHOT) { /* remap snapshot */ + if (lv->u.lv_block_exception) lvm_snapshot_remap_block(&rdev_map, &rsector_map, pe_start, lv); else @@ -1232,10 +1235,10 @@ /* start with first snapshot and loop through all of them */ - for (snap = lv->lv_snapshot_next; snap; - snap = snap->lv_snapshot_next) { + for (snap = lv->u.lv_snapshot_next; snap; + snap = snap->u.lv_snapshot_next) { /* Check for inactive snapshot */ - if (!(snap->lv_status & LV_ACTIVE)) + if (!(snap->u.lv_status & LV_ACTIVE)) continue; /* Serializes the COW with the accesses to the @@ -1274,8 +1277,8 @@ if (vg[VG_BLK(minor)] == NULL || (lv_ptr = vg[VG_BLK(minor)]->lv[LV_BLK(minor)]) == NULL) return; - len = strlen(lv_ptr->lv_name) - 5; - memcpy(buf, &lv_ptr->lv_name[5], len); + len = strlen(lv_ptr->u.lv_name) - 5; + memcpy(buf, &lv_ptr->u.lv_name[5], len); buf[len] = 0; return; } @@ -1360,7 +1363,7 @@ return -EBUSY; } - /* Should we do to_kdev_t() on the pv_dev and lv_dev??? */ + /* Should we do to_kdev_t() on the pv_dev and u.lv_dev??? */ pe_lock_req.lock = LOCK_PE; pe_lock_req.data.lv_dev = new_lock.data.lv_dev; pe_lock_req.data.pv_dev = new_lock.data.pv_dev; @@ -1407,16 +1410,16 @@ for (l = 0; l < vg_ptr->lv_max; l++) { lv_ptr = vg_ptr->lv[l]; if (lv_ptr != NULL && - strcmp(lv_ptr->lv_name, + strcmp(lv_ptr->u.lv_name, le_remap_req.lv_name) == 0) { - for (le = 0; le < lv_ptr->lv_allocated_le; le++) { - if (kdev_same(lv_ptr->lv_current_pe[le].dev, + for (le = 0; le < lv_ptr->u.lv_allocated_le; le++) { + if (kdev_same(lv_ptr->u.lv_current_pe[le].dev, le_remap_req.old_dev) && - lv_ptr->lv_current_pe[le].pe == + lv_ptr->u.lv_current_pe[le].pe == le_remap_req.old_pe) { - lv_ptr->lv_current_pe[le].dev = + lv_ptr->u.lv_current_pe[le].dev = le_remap_req.new_dev; - lv_ptr->lv_current_pe[le].pe = + lv_ptr->u.lv_current_pe[le].pe = le_remap_req.new_pe; __update_hardsectsize(lv_ptr); @@ -1532,7 +1535,7 @@ /* user space address */ if ((lvp = vg_ptr->lv[l]) != NULL) { - if (copy_from_user(tmplv, lvp, sizeof(lv_t)) != 0) { + if (copy_from_user(tmplv, lvp, sizeof(userlv_t)) != 0) { P_IOCTL("ERROR: copying LV ptr %p (%d bytes)\n", lvp, sizeof(lv_t)); lvm_do_vg_remove(minor); @@ -1540,7 +1543,7 @@ kfree(tmplv); return -EFAULT; } - if ( tmplv->lv_access & LV_SNAPSHOT) { + if ( tmplv->u.lv_access & LV_SNAPSHOT) { snap_lv_ptr[ls] = lvp; vg_ptr->lv[l] = NULL; ls++; @@ -1548,7 +1551,7 @@ } vg_ptr->lv[l] = NULL; /* only create original logical volumes for now */ - if (lvm_do_lv_create(minor, tmplv->lv_name, tmplv) != 0) { + if (lvm_do_lv_create(minor, tmplv->u.lv_name, &tmplv->u) != 0) { lvm_do_vg_remove(minor); vfree(snap_lv_ptr); kfree(tmplv); @@ -1561,13 +1564,13 @@ in place during first path above */ for (l = 0; l < ls; l++) { lv_t *lvp = snap_lv_ptr[l]; - if (copy_from_user(tmplv, lvp, sizeof(lv_t)) != 0) { + if (copy_from_user(tmplv, lvp, sizeof(userlv_t)) != 0) { lvm_do_vg_remove(minor); vfree(snap_lv_ptr); kfree(tmplv); return -EFAULT; } - if (lvm_do_lv_create(minor, tmplv->lv_name, tmplv) != 0) { + if (lvm_do_lv_create(minor, tmplv->u.lv_name, &tmplv->u) != 0) { lvm_do_vg_remove(minor); vfree(snap_lv_ptr); kfree(tmplv); @@ -1666,15 +1669,15 @@ 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)); - ptr = strrchr(lv_ptr->lv_name, '/'); - if (ptr == NULL) ptr = lv_ptr->lv_name; + strncpy(lv_ptr->u.vg_name, vg_name, sizeof ( vg_name)); + ptr = strrchr(lv_ptr->u.lv_name, '/'); + if (ptr == NULL) ptr = lv_ptr->u.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); + strcpy(lv_ptr->u.lv_name, LVM_DIR_PREFIX); + strncat(lv_ptr->u.lv_name, vg_name, NAME_LEN - len); len += strlen ( vg_name); - strncat(lv_ptr->lv_name, lv_name, NAME_LEN - len); + strncat(lv_ptr->u.lv_name, lv_name, NAME_LEN - len); } for ( p = 0; p < vg_ptr->pv_max; p++) { @@ -1716,7 +1719,7 @@ /* first free snapshot logical volumes */ for (i = 0; i < vg_ptr->lv_max; i++) { if (vg_ptr->lv[i] != NULL && - vg_ptr->lv[i]->lv_access & LV_SNAPSHOT) { + vg_ptr->lv[i]->u.lv_access & LV_SNAPSHOT) { lvm_do_lv_remove(minor, NULL, i); current->state = TASK_UNINTERRUPTIBLE; schedule_timeout(1); @@ -1819,8 +1822,8 @@ int le, e; int max_hardsectsize = 0, hardsectsize; - for (le = 0; le < lv->lv_allocated_le; le++) { - hardsectsize = get_hardsect_size(lv->lv_current_pe[le].dev); + for (le = 0; le < lv->u.lv_allocated_le; le++) { + hardsectsize = get_hardsect_size(lv->u.lv_current_pe[le].dev); if (hardsectsize == 0) hardsectsize = 512; if (hardsectsize > max_hardsectsize) @@ -1828,10 +1831,10 @@ } /* only perform this operation on active snapshots */ - if ((lv->lv_access & LV_SNAPSHOT) && - (lv->lv_status & LV_ACTIVE)) { - for (e = 0; e < lv->lv_remap_end; e++) { - hardsectsize = get_hardsect_size( lv->lv_block_exception[e].rdev_new); + if ((lv->u.lv_access & LV_SNAPSHOT) && + (lv->u.lv_status & LV_ACTIVE)) { + for (e = 0; e < lv->u.lv_remap_end; e++) { + hardsectsize = get_hardsect_size( lv->u.lv_block_exception[e].rdev_new); if (hardsectsize == 0) hardsectsize = 512; if (hardsectsize > max_hardsectsize) @@ -1843,31 +1846,31 @@ /* * 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, userlv_t *ulv) { int e, ret, l, le, l_new, p, size, activate = 1; ulong lv_status_save; - lv_block_exception_t *lvbe = lv->lv_block_exception; + lv_block_exception_t *lvbe = ulv->lv_block_exception; vg_t *vg_ptr = vg[VG_CHR(minor)]; lv_t *lv_ptr = NULL; pe_t *pep; - if (!(pep = lv->lv_current_pe)) + if (!(pep = ulv->lv_current_pe)) return -EINVAL; - if (_sectors_to_k(lv->lv_chunk_size) > LVM_SNAPSHOT_MAX_CHUNK) + if (_sectors_to_k(ulv->lv_chunk_size) > LVM_SNAPSHOT_MAX_CHUNK) return -EINVAL; for (l = 0; l < vg_ptr->lv_cur; l++) { if (vg_ptr->lv[l] != NULL && - strcmp(vg_ptr->lv[l]->lv_name, lv_name) == 0) + strcmp(vg_ptr->lv[l]->u.lv_name, lv_name) == 0) return -EEXIST; } /* in case of lv_remove(), lv_create() pair */ l_new = -1; - if (vg_ptr->lv[lv->lv_number] == NULL) - l_new = lv->lv_number; + if (vg_ptr->lv[ulv->lv_number] == NULL) + l_new = ulv->lv_number; else { for (l = 0; l < vg_ptr->lv_max; l++) { if (vg_ptr->lv[l] == NULL) @@ -1883,16 +1886,16 @@ return -ENOMEM; } /* copy preloaded LV */ - memcpy((char *) lv_ptr, (char *) lv, sizeof(lv_t)); + memcpy((char *) lv_ptr, (char *) ulv, sizeof(userlv_t)); - lv_status_save = lv_ptr->lv_status; - lv_ptr->lv_status &= ~LV_ACTIVE; - lv_ptr->lv_snapshot_org = NULL; - lv_ptr->lv_snapshot_prev = NULL; - lv_ptr->lv_snapshot_next = NULL; - lv_ptr->lv_block_exception = NULL; + lv_status_save = lv_ptr->u.lv_status; + lv_ptr->u.lv_status &= ~LV_ACTIVE; + lv_ptr->u.lv_snapshot_org = NULL; + lv_ptr->u.lv_snapshot_prev = NULL; + lv_ptr->u.lv_snapshot_next = NULL; + lv_ptr->u.lv_block_exception = NULL; lv_ptr->lv_iobuf = NULL; - lv_ptr->lv_COW_table_iobuf = NULL; + lv_ptr->lv_COW_table_iobuf = NULL; lv_ptr->lv_snapshot_hash_table = NULL; lv_ptr->lv_snapshot_hash_table_size = 0; lv_ptr->lv_snapshot_hash_mask = 0; @@ -1904,10 +1907,10 @@ /* get the PE structures from user space if this is not a snapshot logical volume */ - if (!(lv_ptr->lv_access & LV_SNAPSHOT)) { - size = lv_ptr->lv_allocated_le * sizeof(pe_t); + if (!(lv_ptr->u.lv_access & LV_SNAPSHOT)) { + size = lv_ptr->u.lv_allocated_le * sizeof(pe_t); - if ((lv_ptr->lv_current_pe = vmalloc(size)) == NULL) { + if ((lv_ptr->u.lv_current_pe = vmalloc(size)) == NULL) { printk(KERN_CRIT "%s -- LV_CREATE: vmalloc error LV_CURRENT_PE of %d Byte " "at line %d\n", @@ -1917,30 +1920,30 @@ vg_ptr->lv[l] = NULL; return -ENOMEM; } - if (copy_from_user(lv_ptr->lv_current_pe, pep, size)) { + if (copy_from_user(lv_ptr->u.lv_current_pe, pep, size)) { P_IOCTL("ERROR: copying PE ptr %p (%d bytes)\n", pep, sizeof(size)); - vfree(lv_ptr->lv_current_pe); + vfree(lv_ptr->u.lv_current_pe); kfree(lv_ptr); vg_ptr->lv[l] = NULL; return -EFAULT; } /* correct the PE count in PVs */ - for (le = 0; le < lv_ptr->lv_allocated_le; le++) { + for (le = 0; le < lv_ptr->u.lv_allocated_le; le++) { vg_ptr->pe_allocated++; for (p = 0; p < vg_ptr->pv_cur; p++) { if (kdev_same(vg_ptr->pv[p]->pv_dev, - lv_ptr->lv_current_pe[le].dev)) + lv_ptr->u.lv_current_pe[le].dev)) vg_ptr->pv[p]->pe_allocated++; } } } else { /* Get snapshot exception data and block list */ if (lvbe != NULL) { - 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); + lv_ptr->u.lv_snapshot_org = + vg_ptr->lv[LV_BLK(lv_ptr->u.lv_snapshot_minor)]; + if (lv_ptr->u.lv_snapshot_org != NULL) { + size = lv_ptr->u.lv_remap_end * sizeof(lv_block_exception_t); if(!size) { printk(KERN_WARNING @@ -1950,7 +1953,7 @@ return -EINVAL; } - if ((lv_ptr->lv_block_exception = vmalloc(size)) == NULL) { + if ((lv_ptr->u.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", @@ -1961,14 +1964,14 @@ vg_ptr->lv[l] = NULL; return -ENOMEM; } - if (copy_from_user(lv_ptr->lv_block_exception, lvbe, size)) { - vfree(lv_ptr->lv_block_exception); + if (copy_from_user(lv_ptr->u.lv_block_exception, lvbe, size)) { + vfree(lv_ptr->u.lv_block_exception); kfree(lv_ptr); vg_ptr->lv[l] = NULL; return -EFAULT; } - if(lv_ptr->lv_block_exception[0].rsector_org == + if(lv_ptr->u.lv_block_exception[0].rsector_org == LVM_SNAPSHOT_DROPPED_SECTOR) { printk(KERN_WARNING @@ -1979,36 +1982,36 @@ /* point to the original logical volume */ - lv_ptr = lv_ptr->lv_snapshot_org; + lv_ptr = lv_ptr->u.lv_snapshot_org; - lv_ptr->lv_snapshot_minor = 0; - lv_ptr->lv_snapshot_org = lv_ptr; + lv_ptr->u.lv_snapshot_minor = 0; + lv_ptr->u.lv_snapshot_org = lv_ptr; /* our new one now back points to the previous last in the chain 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->u.lv_current_pe = lv_ptr->u.lv_snapshot_org->u.lv_current_pe; + lv_ptr->lv_allocated_snapshot_le = lv_ptr->u.lv_allocated_le; + lv_ptr->u.lv_allocated_le = lv_ptr->u.lv_snapshot_org->u.lv_allocated_le; + lv_ptr->u.lv_current_le = lv_ptr->u.lv_snapshot_org->u.lv_current_le; + lv_ptr->u.lv_size = lv_ptr->u.lv_snapshot_org->u.lv_size; + lv_ptr->u.lv_stripes = lv_ptr->u.lv_snapshot_org->u.lv_stripes; + lv_ptr->u.lv_stripesize = lv_ptr->u.lv_snapshot_org->u.lv_stripesize; /* Update the VG PE(s) used by snapshot reserve space. */ vg_ptr->pe_allocated += lv_ptr->lv_allocated_snapshot_le; if ((ret = lvm_snapshot_alloc(lv_ptr)) != 0) { - vfree(lv_ptr->lv_block_exception); + vfree(lv_ptr->u.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->u.lv_remap_ptr; e++) + lvm_hash_link (lv_ptr->u.lv_block_exception + e, + lv_ptr->u.lv_block_exception[e].rdev_org, + lv_ptr->u.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)) { @@ -2027,62 +2030,62 @@ 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]->u.lv_access & LV_SNAPSHOT) */ lv_ptr = vg_ptr->lv[l]; - lvm_gendisk.part[minor(lv_ptr->lv_dev)].start_sect = 0; - lvm_gendisk.part[minor(lv_ptr->lv_dev)].nr_sects = lv_ptr->lv_size; - lvm_size[minor(lv_ptr->lv_dev)] = lv_ptr->lv_size >> 1; - vg_lv_map[minor(lv_ptr->lv_dev)].vg_number = vg_ptr->vg_number; - vg_lv_map[minor(lv_ptr->lv_dev)].lv_number = lv_ptr->lv_number; - LVM_CORRECT_READ_AHEAD(lv_ptr->lv_read_ahead); + lvm_gendisk.part[minor(lv_ptr->u.lv_dev)].start_sect = 0; + lvm_gendisk.part[minor(lv_ptr->u.lv_dev)].nr_sects = lv_ptr->u.lv_size; + lvm_size[minor(lv_ptr->u.lv_dev)] = lv_ptr->u.lv_size >> 1; + vg_lv_map[minor(lv_ptr->u.lv_dev)].vg_number = vg_ptr->vg_number; + vg_lv_map[minor(lv_ptr->u.lv_dev)].lv_number = lv_ptr->u.lv_number; + LVM_CORRECT_READ_AHEAD(lv_ptr->u.lv_read_ahead); vg_ptr->lv_cur++; - lv_ptr->lv_status = lv_status_save; + lv_ptr->u.lv_status = lv_status_save; __update_hardsectsize(lv_ptr); /* optionally add our new snapshot LV */ - if (lv_ptr->lv_access & LV_SNAPSHOT) { - lv_t *org = lv_ptr->lv_snapshot_org, *last; + if (lv_ptr->u.lv_access & LV_SNAPSHOT) { + lv_t *org = lv_ptr->u.lv_snapshot_org, *last; /* sync the original logical volume */ - fsync_dev(org->lv_dev); + fsync_dev(org->u.lv_dev); #ifdef LVM_VFS_ENHANCEMENT /* VFS function call to sync and lock the filesystem */ - fsync_dev_lockfs(org->lv_dev); + fsync_dev_lockfs(org->u.lv_dev); #endif 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 */ + org->u.lv_access |= LV_SNAPSHOT_ORG; + lv_ptr->u.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); - lv_ptr->lv_snapshot_prev = last; - last->lv_snapshot_next = lv_ptr; + for (last = org; last->u.lv_snapshot_next; last = last->u.lv_snapshot_next); + lv_ptr->u.lv_snapshot_prev = last; + last->u.lv_snapshot_next = lv_ptr; up_write(&org->lv_lock); } /* activate the logical volume */ if(activate) - lv_ptr->lv_status |= LV_ACTIVE; + lv_ptr->u.lv_status |= LV_ACTIVE; else - lv_ptr->lv_status &= ~LV_ACTIVE; + lv_ptr->u.lv_status &= ~LV_ACTIVE; - if ( lv_ptr->lv_access & LV_WRITE) - set_device_ro(lv_ptr->lv_dev, 0); + if ( lv_ptr->u.lv_access & LV_WRITE) + set_device_ro(lv_ptr->u.lv_dev, 0); else - set_device_ro(lv_ptr->lv_dev, 1); + set_device_ro(lv_ptr->u.lv_dev, 1); #ifdef LVM_VFS_ENHANCEMENT /* VFS function call to unlock the filesystem */ - if (lv_ptr->lv_access & LV_SNAPSHOT) - unlockfs(lv_ptr->lv_snapshot_org->lv_dev); + if (lv_ptr->u.lv_access & LV_SNAPSHOT) + unlockfs(lv_ptr->u.lv_snapshot_org->u.lv_dev); #endif lv_ptr->vg = vg_ptr; - lvm_gendisk.part[minor(lv_ptr->lv_dev)].de = + lvm_gendisk.part[minor(lv_ptr->u.lv_dev)].de = lvm_fs_create_lv(vg_ptr, lv_ptr); return 0; @@ -2101,7 +2104,7 @@ if (l == -1) { for (l = 0; l < vg_ptr->lv_max; l++) { if (vg_ptr->lv[l] != NULL && - strcmp(vg_ptr->lv[l]->lv_name, lv_name) == 0) { + strcmp(vg_ptr->lv[l]->u.lv_name, lv_name) == 0) { break; } } @@ -2110,38 +2113,38 @@ lv_ptr = vg_ptr->lv[l]; #ifdef LVM_TOTAL_RESET - if (lv_ptr->lv_open > 0 && lvm_reset_spindown == 0) + if (lv_ptr->u.lv_open > 0 && lvm_reset_spindown == 0) #else - if (lv_ptr->lv_open > 0) + if (lv_ptr->u.lv_open > 0) #endif return -EBUSY; /* check for deletion of snapshot source while snapshot volume still exists */ - if ((lv_ptr->lv_access & LV_SNAPSHOT_ORG) && - lv_ptr->lv_snapshot_next != NULL) + if ((lv_ptr->u.lv_access & LV_SNAPSHOT_ORG) && + lv_ptr->u.lv_snapshot_next != NULL) return -EPERM; lvm_fs_remove_lv(vg_ptr, lv_ptr); - if (lv_ptr->lv_access & LV_SNAPSHOT) { + if (lv_ptr->u.lv_access & LV_SNAPSHOT) { /* * 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->u.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; - if (lv_ptr->lv_snapshot_next != NULL) { - lv_ptr->lv_snapshot_next->lv_snapshot_prev = - lv_ptr->lv_snapshot_prev; + lv_ptr->u.lv_snapshot_prev->u.lv_snapshot_next = lv_ptr->u.lv_snapshot_next; + if (lv_ptr->u.lv_snapshot_next != NULL) { + lv_ptr->u.lv_snapshot_next->u.lv_snapshot_prev = + lv_ptr->u.lv_snapshot_prev; } /* no more snapshots? */ - if (!org->lv_snapshot_next) { - org->lv_access &= ~LV_SNAPSHOT_ORG; + if (!org->u.lv_snapshot_next) { + org->u.lv_access &= ~LV_SNAPSHOT_ORG; } up_write(&org->lv_lock); @@ -2151,41 +2154,41 @@ vg_ptr->pe_allocated -= lv_ptr->lv_allocated_snapshot_le; } - lv_ptr->lv_status |= LV_SPINDOWN; + lv_ptr->u.lv_status |= LV_SPINDOWN; /* sync the buffers */ - fsync_dev(lv_ptr->lv_dev); + fsync_dev(lv_ptr->u.lv_dev); - lv_ptr->lv_status &= ~LV_ACTIVE; + lv_ptr->u.lv_status &= ~LV_ACTIVE; /* invalidate the buffers */ - invalidate_buffers(lv_ptr->lv_dev); + invalidate_buffers(lv_ptr->u.lv_dev); /* reset generic hd */ - lvm_gendisk.part[minor(lv_ptr->lv_dev)].start_sect = -1; - lvm_gendisk.part[minor(lv_ptr->lv_dev)].nr_sects = 0; - lvm_gendisk.part[minor(lv_ptr->lv_dev)].de = 0; - lvm_size[minor(lv_ptr->lv_dev)] = 0; + lvm_gendisk.part[minor(lv_ptr->u.lv_dev)].start_sect = -1; + lvm_gendisk.part[minor(lv_ptr->u.lv_dev)].nr_sects = 0; + lvm_gendisk.part[minor(lv_ptr->u.lv_dev)].de = 0; + lvm_size[minor(lv_ptr->u.lv_dev)] = 0; /* reset VG/LV mapping */ - vg_lv_map[minor(lv_ptr->lv_dev)].vg_number = ABS_MAX_VG; - vg_lv_map[minor(lv_ptr->lv_dev)].lv_number = -1; + vg_lv_map[minor(lv_ptr->u.lv_dev)].vg_number = ABS_MAX_VG; + vg_lv_map[minor(lv_ptr->u.lv_dev)].lv_number = -1; /* correct the PE count in PVs if this is not a snapshot logical volume */ - if (!(lv_ptr->lv_access & LV_SNAPSHOT)) { + if (!(lv_ptr->u.lv_access & LV_SNAPSHOT)) { /* only if this is no snapshot logical volume because - we share the lv_current_pe[] structs with the + we share the u.lv_current_pe[] structs with the original logical volume */ - for (le = 0; le < lv_ptr->lv_allocated_le; le++) { + for (le = 0; le < lv_ptr->u.lv_allocated_le; le++) { vg_ptr->pe_allocated--; for (p = 0; p < vg_ptr->pv_cur; p++) { if (kdev_same(vg_ptr->pv[p]->pv_dev, - lv_ptr->lv_current_pe[le].dev)) + lv_ptr->u.lv_current_pe[le].dev)) vg_ptr->pv[p]->pe_allocated--; } } - vfree(lv_ptr->lv_current_pe); + vfree(lv_ptr->u.lv_current_pe); } P_KFREE("%s -- kfree %d\n", lvm_name, __LINE__); @@ -2203,10 +2206,10 @@ ulong size; lv_block_exception_t *lvbe; - if (!new_lv->lv_block_exception) + if (!new_lv->u.lv_block_exception) return -ENXIO; - size = new_lv->lv_remap_end * sizeof(lv_block_exception_t); + size = new_lv->u.lv_remap_end * sizeof(lv_block_exception_t); if ((lvbe = vmalloc(size)) == NULL) { printk(KERN_CRIT "%s -- lvm_do_lv_extend_reduce: vmalloc " @@ -2215,15 +2218,15 @@ return -ENOMEM; } - if ((new_lv->lv_remap_end > old_lv->lv_remap_end) && - (copy_from_user(lvbe, new_lv->lv_block_exception, size))) { + if ((new_lv->u.lv_remap_end > old_lv->u.lv_remap_end) && + (copy_from_user(lvbe, new_lv->u.lv_block_exception, size))) { vfree(lvbe); return -EFAULT; } - new_lv->lv_block_exception = lvbe; + new_lv->u.lv_block_exception = lvbe; if (lvm_snapshot_alloc_hash_table(new_lv)) { - vfree(new_lv->lv_block_exception); + vfree(new_lv->u.lv_block_exception); return -ENOMEM; } @@ -2235,7 +2238,7 @@ pe_t *pe; /* allocate space for new pe structures */ - size = new_lv->lv_current_le * sizeof(pe_t); + size = new_lv->u.lv_current_le * sizeof(pe_t); if ((pe = vmalloc(size)) == NULL) { printk(KERN_CRIT "%s -- lvm_do_lv_extend_reduce: " @@ -2245,21 +2248,21 @@ } /* 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 (copy_from_user(pe, new_lv->u.lv_current_pe, size)) { + if(old_lv->u.lv_access & LV_SNAPSHOT) vfree(new_lv->lv_snapshot_hash_table); vfree(pe); return -EFAULT; } - new_lv->lv_current_pe = pe; + new_lv->u.lv_current_pe = pe; /* reduce allocation counters on PV(s) */ - for (l = 0; l < old_lv->lv_allocated_le; l++) { + for (l = 0; l < old_lv->u.lv_allocated_le; l++) { vg_ptr->pe_allocated--; for (p = 0; p < vg_ptr->pv_cur; p++) { if (kdev_same(vg_ptr->pv[p]->pv_dev, - old_lv->lv_current_pe[l].dev)) { + old_lv->u.lv_current_pe[l].dev)) { vg_ptr->pv[p]->pe_allocated--; break; } @@ -2267,11 +2270,11 @@ } /* extend the PE count in PVs */ - for (l = 0; l < new_lv->lv_allocated_le; l++) { + for (l = 0; l < new_lv->u.lv_allocated_le; l++) { vg_ptr->pe_allocated++; for (p = 0; p < vg_ptr->pv_cur; p++) { if (kdev_same(vg_ptr->pv[p]->pv_dev, - new_lv->lv_current_pe[l].dev)) { + new_lv->u.lv_current_pe[l].dev)) { vg_ptr->pv[p]->pe_allocated++; break; } @@ -2279,30 +2282,30 @@ } /* save availiable i/o statistic data */ - if (old_lv->lv_stripes < 2) { /* linear logical volume */ - end = min(old_lv->lv_current_le, new_lv->lv_current_le); + if (old_lv->u.lv_stripes < 2) { /* linear logical volume */ + end = min(old_lv->u.lv_current_le, new_lv->u.lv_current_le); for (l = 0; l < end; l++) { - new_lv->lv_current_pe[l].reads += - old_lv->lv_current_pe[l].reads; + new_lv->u.lv_current_pe[l].reads += + old_lv->u.lv_current_pe[l].reads; - new_lv->lv_current_pe[l].writes += - old_lv->lv_current_pe[l].writes; + new_lv->u.lv_current_pe[l].writes += + old_lv->u.lv_current_pe[l].writes; } } else { /* striped logical volume */ 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->u.lv_allocated_le / old_lv->u.lv_stripes; + new_stripe_size = new_lv->u.lv_allocated_le / new_lv->u.lv_stripes; end = min(old_stripe_size, new_stripe_size); for (i = source = dest = 0; - i < new_lv->lv_stripes; i++) { + i < new_lv->u.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; - new_lv->lv_current_pe[dest + j].writes += - old_lv->lv_current_pe[source + j].writes; + new_lv->u.lv_current_pe[dest + j].reads += + old_lv->u.lv_current_pe[source + j].reads; + new_lv->u.lv_current_pe[dest + j].writes += + old_lv->u.lv_current_pe[source + j].writes; } source += old_stripe_size; dest += new_stripe_size; @@ -2312,19 +2315,29 @@ 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, userlv_t *ulv) { int r; ulong l, e, size; vg_t *vg_ptr = vg[VG_CHR(minor)]; lv_t *old_lv; + lv_t *new_lv; pe_t *pe; - if ((pe = new_lv->lv_current_pe) == NULL) + if((new_lv = kmalloc(sizeof(lv_t),GFP_KERNEL)) == NULL){ + printk(KERN_CRIT + "%s -- LV_EXTEND/REDUCE: kmallor error LV at line %d\n", + lvm_name,__LINE__); + return -ENOMEM; + } + memset(new_lv,0,sizeof(lv_t)); + memcpy(&new_lv->u,ulv,sizeof(userlv_t)); + + if ((pe = new_lv->u.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)) + if (vg_ptr->lv[l] && !strcmp(vg_ptr->lv[l]->u.lv_name, lv_name)) break; if (l == vg_ptr->lv_max) @@ -2332,9 +2345,9 @@ old_lv = vg_ptr->lv[l]; - if (old_lv->lv_access & LV_SNAPSHOT) { + if (old_lv->u.lv_access & LV_SNAPSHOT) { /* only perform this operation on active snapshots */ - if (old_lv->lv_status & LV_ACTIVE) + if (old_lv->u.lv_status & LV_ACTIVE) r = __extend_reduce_snapshot(vg_ptr, old_lv, new_lv); else r = -EPERM; @@ -2348,15 +2361,15 @@ /* copy relevent fields */ down_write(&old_lv->lv_lock); - 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; + if(new_lv->u.lv_access & LV_SNAPSHOT) { + size = (new_lv->u.lv_remap_end > old_lv->u.lv_remap_end) ? + old_lv->u.lv_remap_ptr : new_lv->u.lv_remap_end; size *= sizeof(lv_block_exception_t); - memcpy(new_lv->lv_block_exception, - old_lv->lv_block_exception, size); + memcpy(new_lv->u.lv_block_exception, + old_lv->u.lv_block_exception, size); - old_lv->lv_remap_end = new_lv->lv_remap_end; - old_lv->lv_block_exception = new_lv->lv_block_exception; + old_lv->u.lv_remap_end = new_lv->u.lv_remap_end; + old_lv->u.lv_block_exception = new_lv->u.lv_block_exception; old_lv->lv_snapshot_hash_table = new_lv->lv_snapshot_hash_table; old_lv->lv_snapshot_hash_table_size = @@ -2364,40 +2377,40 @@ old_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, + for (e = 0; e < new_lv->u.lv_remap_ptr; e++) + lvm_hash_link(new_lv->u.lv_block_exception + e, + new_lv->u.lv_block_exception[e].rdev_org, + new_lv->u.lv_block_exception[e].rsector_org, new_lv); } else { - vfree(old_lv->lv_current_pe); + vfree(old_lv->u.lv_current_pe); vfree(old_lv->lv_snapshot_hash_table); - old_lv->lv_size = new_lv->lv_size; - old_lv->lv_allocated_le = new_lv->lv_allocated_le; - 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; - lvm_size[minor(old_lv->lv_dev)] = old_lv->lv_size >> 1; + old_lv->u.lv_size = new_lv->u.lv_size; + old_lv->u.lv_allocated_le = new_lv->u.lv_allocated_le; + old_lv->u.lv_current_le = new_lv->u.lv_current_le; + old_lv->u.lv_current_pe = new_lv->u.lv_current_pe; + lvm_gendisk.part[minor(old_lv->u.lv_dev)].nr_sects = + old_lv->u.lv_size; + lvm_size[minor(old_lv->u.lv_dev)] = old_lv->u.lv_size >> 1; - if (old_lv->lv_access & LV_SNAPSHOT_ORG) { + if (old_lv->u.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->u.lv_snapshot_next; snap; + snap = snap->u.lv_snapshot_next) { down_write(&snap->lv_lock); - 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; - snap->lv_size = 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; + snap->u.lv_current_pe = old_lv->u.lv_current_pe; + snap->u.lv_allocated_le = + old_lv->u.lv_allocated_le; + snap->u.lv_current_le = old_lv->u.lv_current_le; + snap->u.lv_size = old_lv->u.lv_size; + + lvm_gendisk.part[minor(snap->u.lv_dev)].nr_sects + = old_lv->u.lv_size; + lvm_size[minor(snap->u.lv_dev)] = + old_lv->u.lv_size >> 1; __update_hardsectsize(snap); up_write(&snap->lv_lock); } @@ -2431,27 +2444,27 @@ for (l = 0; l < vg_ptr->lv_max; l++) { if ((lv_ptr = vg_ptr->lv[l]) != NULL && - strcmp(lv_ptr->lv_name, + strcmp(lv_ptr->u.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) + if (copy_from_user(&saved_ptr1, &lv_status_byname_req.lv->u.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) + if (copy_from_user(&saved_ptr2, &lv_status_byname_req.lv->u.lv_block_exception, sizeof(void*)) != 0) return -EFAULT; if (copy_to_user(lv_status_byname_req.lv, lv_ptr, - sizeof(lv_t)) != 0) + sizeof(userlv_t)) != 0) return -EFAULT; if (saved_ptr1 != NULL) { if (copy_to_user(saved_ptr1, - lv_ptr->lv_current_pe, - lv_ptr->lv_allocated_le * + lv_ptr->u.lv_current_pe, + lv_ptr->u.lv_allocated_le * 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) + if (copy_to_user(&lv_status_byname_req.lv->u.lv_current_pe, &saved_ptr1, sizeof(void*)) != 0) return -EFAULT; return 0; } @@ -2484,23 +2497,23 @@ return -ENXIO; /* Save usermode pointers */ - if (copy_from_user(&saved_ptr1, &lv_status_byindex_req.lv->lv_current_pe, sizeof(void*)) != 0) + if (copy_from_user(&saved_ptr1, &lv_status_byindex_req.lv->u.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) + if (copy_from_user(&saved_ptr2, &lv_status_byindex_req.lv->u.lv_block_exception, sizeof(void*)) != 0) return -EFAULT; - if (copy_to_user(lv_status_byindex_req.lv, lv_ptr, sizeof(lv_t)) != 0) + if (copy_to_user(lv_status_byindex_req.lv, lv_ptr, sizeof(userlv_t)) != 0) return -EFAULT; if (saved_ptr1 != NULL) { if (copy_to_user(saved_ptr1, - lv_ptr->lv_current_pe, - lv_ptr->lv_allocated_le * + lv_ptr->u.lv_current_pe, + lv_ptr->u.lv_allocated_le * 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) + if (copy_to_user(&lv_status_byindex_req.lv->u.lv_current_pe, &saved_ptr1, sizeof(void *)) != 0) return -EFAULT; return 0; @@ -2524,7 +2537,7 @@ for ( l = 0; l < vg_ptr->lv_max; l++) { if ( vg_ptr->lv[l] == NULL) continue; - if ( kdev_same(vg_ptr->lv[l]->lv_dev, + if ( kdev_same(vg_ptr->lv[l]->u.lv_dev, to_kdev_t(lv_status_bydev_req.dev))) break; } @@ -2533,22 +2546,22 @@ 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) + if (copy_from_user(&saved_ptr1, &lv_status_bydev_req.lv->u.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) + if (copy_from_user(&saved_ptr2, &lv_status_bydev_req.lv->u.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 (saved_ptr1 != NULL) { if (copy_to_user(saved_ptr1, - lv_ptr->lv_current_pe, - lv_ptr->lv_allocated_le * + lv_ptr->u.lv_current_pe, + lv_ptr->u.lv_allocated_le * 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) + if (copy_to_user(&lv_status_bydev_req.lv->u.lv_current_pe, &saved_ptr1, sizeof(void *)) != 0) return -EFAULT; return 0; @@ -2558,7 +2571,7 @@ /* * 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, userlv_t *ulv) { int l = 0; int ret = 0; @@ -2567,10 +2580,10 @@ for (l = 0; l < vg_ptr->lv_max; l++) { if ( (lv_ptr = vg_ptr->lv[l]) == NULL) continue; - if (kdev_same(lv_ptr->lv_dev, lv->lv_dev)) + if (kdev_same(lv_ptr->u.lv_dev, ulv->lv_dev)) { lvm_fs_remove_lv(vg_ptr, lv_ptr); - strncpy(lv_ptr->lv_name, + strncpy(lv_ptr->u.lv_name, lv_req->lv_name, NAME_LEN); lvm_fs_create_lv(vg_ptr, lv_ptr); --- linux-2.5.2-pre9-uml/include/linux/lvm.h Mon Jan 7 21:57:11 2002 +++ linux-2.5.2-pre9-uml-lvm/include/linux/lvm.h Sun Jan 6 22:35:46 2002 @@ -477,8 +477,16 @@ * Structure Logical Volume (LV) Version 3 */ -/* core */ -typedef struct lv_v5 { +struct kern_lv_v5; +struct user_lv_v5; +typedef struct user_lv_v5 userlv_t; +#ifdef __KERNEL__ +typedef struct kern_lv_v5 lv_t; +#else +typedef struct user_lv_v5 lv_t; +#endif + +struct user_lv_v5 { char lv_name[NAME_LEN]; char vg_name[NAME_LEN]; uint lv_access; @@ -501,15 +509,18 @@ uint lv_read_ahead; /* delta to version 1 starts here */ - struct lv_v5 *lv_snapshot_org; - struct lv_v5 *lv_snapshot_prev; - struct lv_v5 *lv_snapshot_next; + lv_t *lv_snapshot_org; + lv_t *lv_snapshot_prev; + lv_t *lv_snapshot_next; lv_block_exception_t *lv_block_exception; uint lv_remap_ptr; uint lv_remap_end; uint lv_chunk_size; uint lv_snapshot_minor; -#ifdef __KERNEL__ +}; + +struct kern_lv_v5{ + struct user_lv_v5 u; struct kiobuf *lv_iobuf; sector_t blocks[LVM_MAX_SECTORS]; struct kiobuf *lv_COW_table_iobuf; @@ -520,12 +531,8 @@ wait_queue_head_t lv_snapshot_wait; int lv_snapshot_use_rate; struct vg_v3 *vg; - uint lv_allocated_snapshot_le; -#else - char dummy[200]; -#endif -} lv_t; +}; /* disk */ typedef struct lv_disk_v3 { @@ -679,13 +686,13 @@ } static int inline LVM_GET_COW_TABLE_CHUNKS_PER_PE(vg_t *vg, lv_t *lv) { - return vg->pe_size / lv->lv_chunk_size; + return vg->pe_size / lv->u.lv_chunk_size; } static int inline LVM_GET_COW_TABLE_ENTRIES_PER_PE(vg_t *vg, lv_t *lv) { - ulong chunks = vg->pe_size / lv->lv_chunk_size; + ulong chunks = vg->pe_size / lv->u.lv_chunk_size; ulong entry_size = sizeof(lv_COW_table_disk_t); - ulong chunk_size = lv->lv_chunk_size * SECTOR_SIZE; + ulong chunk_size = lv->u.lv_chunk_size * SECTOR_SIZE; ulong entries = (vg->pe_size * SECTOR_SIZE) / (entry_size + chunk_size); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/