From 5ce3b77ef8855f266d885a683af0b6ae0737680b Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 9 Aug 2010 11:06:00 -0700 Subject: [PATCH 1/2] Remove /zvol/ path component for zvol devices As part of commit f162433deb029769f76db8cc216cad9b4f7356fb the /zvol/ path component was added for zvol devices. This ensured all zvol devices would be created by udev in /dev/zvol//, as opposed to the previous /dev// path. Logically, it was nice to organize them in a directory much like Solaris does. However, while initial testing showed this to work fine with modern kernels it does not appear to be supported under RHEL5. The extra path component triggers a NULL deref in create_dir(). Anyway, to avoid having different zvol path names based on your kernel version its more consistent simply to revert to the original naming convention. If you really want the zvol component you can always add custom udev rules to do exactly this. We can revisiting this change again once we are willing to drop support for RHEL5 and similar older distros. --- module/zcommon/include/sys/fs/zfs.h | 2 +- module/zfs/vdev.c | 10 ++++++++++ module/zfs/zvol.c | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/module/zcommon/include/sys/fs/zfs.h b/module/zcommon/include/sys/fs/zfs.h index 2f3c48b6e8..b5f0dd2fa9 100644 --- a/module/zcommon/include/sys/fs/zfs.h +++ b/module/zcommon/include/sys/fs/zfs.h @@ -691,7 +691,7 @@ typedef struct ddt_histogram { #define ZFS_DEV "/dev/zfs" /* general zvol path */ -#define ZVOL_DIR "/dev/zvol" +#define ZVOL_DIR "/dev" #define ZVOL_MAJOR 230 #define ZVOL_MINOR_BITS 4 diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c index e1018ccc6a..0e57148323 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -1072,6 +1072,15 @@ vdev_open_child(void *arg) boolean_t vdev_uses_zvols(vdev_t *vd) { +/* + * Stacking zpools on top of zvols is unsupported until we implement a method + * for determining if an arbitrary block device is a zvol without using the + * path. Solaris would check the 'zvol' path component but this does not + * exist in the Linux port, so we really should do something like stat the + * file and check the major number. This is complicated by the fact that + * we need to do this portably in user or kernel space. + */ +#if 0 int c; if (vd->vdev_path && strncmp(vd->vdev_path, ZVOL_DIR, @@ -1080,6 +1089,7 @@ vdev_uses_zvols(vdev_t *vd) for (c = 0; c < vd->vdev_children; c++) if (vdev_uses_zvols(vd->vdev_child[c])) return (B_TRUE); +#endif return (B_FALSE); } diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index 15716aba3c..4e31733f04 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -1066,7 +1066,7 @@ zvol_alloc(dev_t dev, const char *name) zv->zv_disk->fops = &zvol_ops; zv->zv_disk->private_data = zv; zv->zv_disk->queue = zv->zv_queue; - snprintf(zv->zv_disk->disk_name, DISK_NAME_LEN, "zvol/%s", name); + snprintf(zv->zv_disk->disk_name, DISK_NAME_LEN, "%s", name); return zv; From dd11e3f7f02ad1cd88aec6fc42ceab4ed9442e80 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 9 Aug 2010 14:48:12 -0700 Subject: [PATCH 2/2] Limit sysfs name to KOBJ_NAME_LEN See commit dfc166d174c1550dab8b4528232449e3e0d8f9e1 for details. --- module/zcommon/zfs_namecheck.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/module/zcommon/zfs_namecheck.c b/module/zcommon/zfs_namecheck.c index 5cfafea471..2398c2755c 100644 --- a/module/zcommon/zfs_namecheck.c +++ b/module/zcommon/zfs_namecheck.c @@ -142,9 +142,22 @@ dataset_namecheck(const char *path, namecheck_err_t *why, char *what) * which is the same as MAXNAMELEN used in the kernel. * If ZFS_MAXNAMELEN value is changed, make sure to cleanup all * places using MAXNAMELEN. + * + * When HAVE_KOBJ_NAME_LEN is defined the maximum safe kobject name + * length is 20 bytes. This 20 bytes is broken down as follows to + * provide a maximum safe /[@snapshot] length of only + * 18 bytes. To ensure bytes are left for [@snapshot] the + * portition is futher limited to 9 bytes. For 2.6.27 and + * newer kernels this limit is set to MAXNAMELEN. + * + * / + + + * (18) + (1) + (1) */ - +#ifdef HAVE_KOBJ_NAME_LEN + if (strlen(path) > 18) { +#else if (strlen(path) >= MAXNAMELEN) { +#endif /* HAVE_KOBJ_NAME_LEN */ if (why) *why = NAME_ERR_TOOLONG; return (-1); @@ -303,8 +316,22 @@ pool_namecheck(const char *pool, namecheck_err_t *why, char *what) * which is the same as MAXNAMELEN used in the kernel. * If ZPOOL_MAXNAMELEN value is changed, make sure to cleanup all * places using MAXNAMELEN. + * + * When HAVE_KOBJ_NAME_LEN is defined the maximum safe kobject name + * length is 20 bytes. This 20 bytes is broken down as follows to + * provide a maximum safe /[@snapshot] length of only + * 18 bytes. To ensure bytes are left for [@snapshot] the + * portition is futher limited to 8 bytes. For 2.6.27 and + * newer kernels this limit is set to MAXNAMELEN. + * + * / + + + * (18) + (1) + (1) */ +#ifdef HAVE_KOBJ_NAME_LEN + if (strlen(pool) > 8) { +#else if (strlen(pool) >= MAXNAMELEN) { +#endif /* HAVE_KOBJ_NAME_LEN */ if (why) *why = NAME_ERR_TOOLONG; return (-1);