[parisc-linux-cvs] Re: 2.4.18-pa52 DIFF lvm10
Grant Grundler
grundler@dsl2.external.hp.com
Mon, 08 Jul 2002 14:56:57 -0600
Grant Grundler wrote:
> arch/parisc/kernel: ioctl32.c
>
> Log message:
> 2.4.18-pa52 lvm10 from Joel Soete <joel.soete@freebel.net>
> Adds 32-bit ioctl wrapper for lvm10 ioctls. tested on a500.
Joel has posted this patch to p-l.org mailing list before.
Including it here for...well...because. ;^)
Tested this on a500 with one disk and seems to work fine.
grant
Index: Makefile
===================================================================
RCS file: /var/cvs/linux/Makefile,v
retrieving revision 1.322
diff -u -p -r1.322 Makefile
--- Makefile 2002/07/07 13:44:28 1.322
+++ Makefile 2002/07/08 20:50:08
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 18
-EXTRAVERSION = -pa51
+EXTRAVERSION = -pa52
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
Index: arch/parisc/kernel/ioctl32.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/ioctl32.c,v
retrieving revision 1.11
diff -u -p -r1.11 ioctl32.c
--- arch/parisc/kernel/ioctl32.c 2002/05/01 05:05:52 1.11
+++ arch/parisc/kernel/ioctl32.c 2002/07/08 20:50:08
@@ -51,8 +51,8 @@
#include <linux/serial.h>
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
/* Ugh. This header really is not clean */
-#define min min
-#define max max
+/* #define min min
+#define max max */
#include <linux/lvm.h>
#endif /* LVM */
@@ -1805,6 +1805,8 @@ typedef struct {
u32 proc;
u32 pv[ABS_MAX_PV + 1];
u32 lv[ABS_MAX_LV + 1];
+ uint8_t vg_uuid[UUID_LEN+1]; /* volume group UUID */
+ uint8_t dummy1[200];
} vg32_t;
typedef struct {
@@ -1830,6 +1832,7 @@ typedef struct {
uint32_t pe_stale;
u32 pe;
u32 inode;
+ uint8_t pv_uuid[UUID_LEN+1];
} pv32_t;
typedef struct {
@@ -1840,9 +1843,16 @@ typedef struct {
typedef struct {
u32 lv_index;
u32 lv;
+ /* Transfer size because user space and kernel space differ */
+ uint16_t size;
} lv_status_byindex_req32_t;
typedef struct {
+ __kernel_dev_t32 dev;
+ u32 lv;
+} lv_status_bydev_req32_t;
+
+typedef struct {
uint8_t lv_name[NAME_LEN];
kdev_t old_dev;
kdev_t new_dev;
@@ -1911,7 +1921,8 @@ static lv_t *get_lv_t(u32 p, int *errp)
lv_block_exception32_t *lbe32;
lv_block_exception_t *lbe;
lv32_t *ul = (lv32_t *)A(p);
- lv_t *l = (lv_t *)kmalloc(sizeof(lv_t), GFP_KERNEL);
+ lv_t *l = (lv_t *) kmalloc(sizeof(lv_t), GFP_KERNEL);
+
if (!l) {
*errp = -ENOMEM;
return NULL;
@@ -1976,18 +1987,20 @@ static int copy_lv_t(u32 ptr, lv_t *l)
err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr,
((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
size = l->lv_allocated_le * sizeof(pe_t);
- err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size);
- return -EFAULT;
+ if (ptr1)
+ err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size);
+ return err ? -EFAULT : 0;
}
static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
- vg_t *v;
+ vg_t *v = NULL;
union {
lv_req_t lv_req;
le_remap_req_t le_remap;
lv_status_byindex_req_t lv_byindex;
- pv_status_req32_t pv_status;
+ lv_status_bydev_req_t lv_bydev;
+ pv_status_req_t pv_status;
} u;
pv_t p;
int err;
@@ -1999,97 +2012,144 @@ static int do_lvm_ioctl(unsigned int fd,
switch (cmd) {
case VG_STATUS:
v = kmalloc(sizeof(vg_t), GFP_KERNEL);
- if (!v) return -ENOMEM;
+ if (!v)
+ return -ENOMEM;
karg = v;
break;
+
+ case VG_CREATE_OLD:
case VG_CREATE:
v = kmalloc(sizeof(vg_t), GFP_KERNEL);
- if (!v) return -ENOMEM;
- if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc) ||
- __get_user(v->proc, &((vg32_t *)arg)->proc)) {
+ if (!v)
+ return -ENOMEM;
+ if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc)) {
+ kfree(v);
+ return -EFAULT;
+ }
+ /* 'proc' field is unused, just NULL it out. */
+ v->proc = NULL;
+ if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) {
kfree(v);
return -EFAULT;
}
+
karg = v;
memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv));
- if (v->pv_max > ABS_MAX_PV || v->lv_max == ABS_MAX_LV) return -EPERM;
+ if (v->pv_max > ABS_MAX_PV || v->lv_max > ABS_MAX_LV)
+ return -EPERM;
for (i = 0; i < v->pv_max; i++) {
err = __get_user(ptr, &((vg32_t *)arg)->pv[i]);
- if (err) break;
+ if (err)
+ break;
if (ptr) {
v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL);
if (!v->pv[i]) {
err = -ENOMEM;
break;
}
- err = copy_from_user(v->pv[i], (void *)A(ptr), sizeof(pv32_t) - 8);
+ err = copy_from_user(v->pv[i], (void *)A(ptr),
+ sizeof(pv32_t) - 8 - UUID_LEN+1);
if (err) {
err = -EFAULT;
break;
+ }
+ err = copy_from_user(v->pv[i]->pv_uuid,
+ ((pv32_t *)A(ptr))->pv_uuid,
+ UUID_LEN+1);
+ if (err) {
+ err = -EFAULT;
+ break;
}
- v->pv[i]->pe = NULL; v->pv[i]->inode = NULL;
+
+ v->pv[i]->pe = NULL;
+ v->pv[i]->bd = NULL;
}
}
if (!err) {
for (i = 0; i < v->lv_max; i++) {
err = __get_user(ptr, &((vg32_t *)arg)->lv[i]);
- if (err) break;
+ if (err)
+ break;
if (ptr) {
v->lv[i] = get_lv_t(ptr, &err);
- if (err) break;
+ if (err)
+ break;
}
}
}
break;
+
case LV_CREATE:
case LV_EXTEND:
case LV_REDUCE:
case LV_REMOVE:
+ case LV_RENAME:
case LV_STATUS_BYNAME:
- err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));
- if (err) return -EFAULT;
+ err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));
+ if (err)
+ return -EFAULT;
if (cmd != LV_REMOVE) {
err = __get_user(ptr, &((lv_req32_t *)arg)->lv);
- if (err) return err;
+ if (err)
+ return err;
u.lv_req.lv = get_lv_t(ptr, &err);
} else
u.lv_req.lv = NULL;
break;
+
case LV_STATUS_BYINDEX:
- err = get_user(u.lv_byindex.lv_index, &((lv_status_byindex_req32_t *)arg)->lv_index);
+ err = get_user(u.lv_byindex.lv_index,
+ &((lv_status_byindex_req32_t *)arg)->lv_index);
err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv);
- if (err) return err;
+ if (err)
+ return err;
u.lv_byindex.lv = get_lv_t(ptr, &err);
break;
+
+ case LV_STATUS_BYDEV:
+ err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev);
+ err |= __get_user(ptr, &((lv_status_bydev_req32_t *)arg)->lv);
+ if (err)
+ return err;
+ u.lv_bydev.lv = get_lv_t(ptr, &err);
+ break;
+
case VG_EXTEND:
- err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8);
- if (err) return -EFAULT;
- p.pe = NULL; p.inode = NULL;
+ err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1);
+ if (err)
+ return -EFAULT;
+ err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1);
+ if (err)
+ return -EFAULT;
+ p.pe = NULL;
+ p.bd = NULL;
karg = &p;
break;
- case LE_REMAP:
- err = copy_from_user(&u.le_remap, (void *)arg, sizeof(le_remap_req32_t));
- if (err) return -EFAULT;
- u.le_remap.new_pe = ((le_remap_req32_t *)&u.le_remap)->new_pe;
- u.le_remap.old_pe = ((le_remap_req32_t *)&u.le_remap)->old_pe;
- break;
+
case PV_CHANGE:
case PV_STATUS:
err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name));
- if (err) return -EFAULT;
+ if (err)
+ return -EFAULT;
err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv);
- if (err) return err;
+ if (err)
+ return err;
u.pv_status.pv = &p;
if (cmd == PV_CHANGE) {
- err = copy_from_user(&p, (void *)A(ptr), sizeof(pv32_t) - 8);
- if (err) return -EFAULT;
- p.pe = NULL; p.inode = NULL;
+ err = copy_from_user(&p, (void *)A(ptr),
+ sizeof(pv32_t) - 8 - UUID_LEN+1);
+ if (err)
+ return -EFAULT;
+ p.pe = NULL;
+ p.bd = NULL;
}
break;
- }
+ };
+
old_fs = get_fs(); set_fs (KERNEL_DS);
err = sys_ioctl (fd, cmd, (unsigned long)karg);
set_fs (old_fs);
+
switch (cmd) {
case VG_STATUS:
if (!err) {
@@ -2097,35 +2157,65 @@ static int do_lvm_ioctl(unsigned int fd,
clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc))
err = -EFAULT;
}
+ if (copy_to_user(((vg32_t *)arg)->vg_uuid, v->vg_uuid, UUID_LEN+1)) {
+ err = -EFAULT;
+ }
kfree(v);
break;
+
+ case VG_CREATE_OLD:
case VG_CREATE:
- for (i = 0; i < v->pv_max; i++)
- if (v->pv[i]) kfree(v->pv[i]);
- for (i = 0; i < v->lv_max; i++)
- if (v->lv[i]) put_lv_t(v->lv[i]);
+ for (i = 0; i < v->pv_max; i++) {
+ if (v->pv[i])
+ kfree(v->pv[i]);
+ }
+ for (i = 0; i < v->lv_max; i++) {
+ if (v->lv[i])
+ put_lv_t(v->lv[i]);
+ }
kfree(v);
break;
+
case LV_STATUS_BYNAME:
- if (!err && u.lv_req.lv) err = copy_lv_t(ptr, u.lv_req.lv);
+ if (!err && u.lv_req.lv)
+ err = copy_lv_t(ptr, u.lv_req.lv);
/* Fall through */
+
case LV_CREATE:
case LV_EXTEND:
case LV_REDUCE:
- if (u.lv_req.lv) put_lv_t(u.lv_req.lv);
+ if (u.lv_req.lv)
+ put_lv_t(u.lv_req.lv);
break;
+
case LV_STATUS_BYINDEX:
if (u.lv_byindex.lv) {
- if (!err) err = copy_lv_t(ptr, u.lv_byindex.lv);
+ if (!err)
+ err = copy_lv_t(ptr, u.lv_byindex.lv);
put_lv_t(u.lv_byindex.lv);
}
+ break;
+
+ case LV_STATUS_BYDEV:
+ if (u.lv_bydev.lv) {
+ if (!err)
+ err = copy_lv_t(ptr, u.lv_bydev.lv);
+ put_lv_t(u.lv_byindex.lv);
+ }
+ break;
+
case PV_STATUS:
if (!err) {
- err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8);
- if (err) return -EFAULT;
+ err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);
+ if (err)
+ return -EFAULT;
+ err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);
+ if (err)
+ return -EFAULT;
}
break;
- }
+ };
+
return err;
}
#endif
@@ -3309,6 +3399,7 @@ COMPATIBLE_IOCTL(VG_SET_EXTENDABLE)
COMPATIBLE_IOCTL(VG_STATUS_GET_COUNT)
COMPATIBLE_IOCTL(VG_STATUS_GET_NAMELIST)
COMPATIBLE_IOCTL(VG_REMOVE)
+COMPATIBLE_IOCTL(VG_RENAME)
COMPATIBLE_IOCTL(VG_REDUCE)
COMPATIBLE_IOCTL(PE_LOCK_UNLOCK)
COMPATIBLE_IOCTL(PV_FLUSH)
@@ -3320,6 +3411,9 @@ COMPATIBLE_IOCTL(LVM_RESET)
COMPATIBLE_IOCTL(LV_SET_ACCESS)
COMPATIBLE_IOCTL(LV_SET_STATUS)
COMPATIBLE_IOCTL(LV_SET_ALLOCATION)
+COMPATIBLE_IOCTL(LE_REMAP)
+COMPATIBLE_IOCTL(LV_BMAP)
+COMPATIBLE_IOCTL(LV_SNAPSHOT_USE_RATE)
#endif /* LVM */
#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
@@ -3472,15 +3566,17 @@ HANDLE_IOCTL(SONET_GETFRAMING, do_atm_io
HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl)
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
HANDLE_IOCTL(VG_STATUS, do_lvm_ioctl)
+HANDLE_IOCTL(VG_CREATE_OLD, do_lvm_ioctl)
HANDLE_IOCTL(VG_CREATE, do_lvm_ioctl)
HANDLE_IOCTL(VG_EXTEND, do_lvm_ioctl)
HANDLE_IOCTL(LV_CREATE, do_lvm_ioctl)
HANDLE_IOCTL(LV_REMOVE, do_lvm_ioctl)
HANDLE_IOCTL(LV_EXTEND, do_lvm_ioctl)
HANDLE_IOCTL(LV_REDUCE, do_lvm_ioctl)
+HANDLE_IOCTL(LV_RENAME, do_lvm_ioctl)
HANDLE_IOCTL(LV_STATUS_BYNAME, do_lvm_ioctl)
HANDLE_IOCTL(LV_STATUS_BYINDEX, do_lvm_ioctl)
-HANDLE_IOCTL(LE_REMAP, do_lvm_ioctl)
+HANDLE_IOCTL(LV_STATUS_BYDEV, do_lvm_ioctl)
HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl)
HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl)
#endif /* LVM */