diff options
author | marks <none@none> | 2006-04-17 08:08:54 -0700 |
---|---|---|
committer | marks <none@none> | 2006-04-17 08:08:54 -0700 |
commit | 72fc53bc90bd3b199d29d03ee68adb4a5a17d35b (patch) | |
tree | dafd5e6da6d67a2da1c39d2d25ab74be001f1d4f /usr/src | |
parent | 7cb42c7ebab29418f23e6bc16bd40cea6f303d10 (diff) | |
download | illumos-gate-72fc53bc90bd3b199d29d03ee68adb4a5a17d35b.tar.gz |
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/fs/zfs/sys/zfs_znode.h | 1 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_replay.c | 9 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_vnops.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_znode.c | 62 |
4 files changed, 66 insertions, 8 deletions
diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_znode.h b/usr/src/uts/common/fs/zfs/sys/zfs_znode.h index 4d069b5209..019eefb1a5 100644 --- a/usr/src/uts/common/fs/zfs/sys/zfs_znode.h +++ b/usr/src/uts/common/fs/zfs/sys/zfs_znode.h @@ -255,6 +255,7 @@ extern void zfs_delete_wait_empty(zfsvfs_t *zfsvfs); extern void zfs_remove_op_tables(); extern int zfs_create_op_tables(); extern int zfs_sync(vfs_t *vfsp, short flag, cred_t *cr); +extern dev_t zfs_cmpldev(uint64_t); extern uint64_t zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, int txtype, znode_t *dzp, znode_t *zp, char *name); diff --git a/usr/src/uts/common/fs/zfs/zfs_replay.c b/usr/src/uts/common/fs/zfs/zfs_replay.c index cd5a3848cb..85a681c3dc 100644 --- a/usr/src/uts/common/fs/zfs/zfs_replay.c +++ b/usr/src/uts/common/fs/zfs/zfs_replay.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -65,7 +64,7 @@ zfs_init_vattr(vattr_t *vap, uint64_t mask, uint64_t mode, vap->va_mode = mode & MODEMASK; vap->va_uid = (uid_t)uid; vap->va_gid = (gid_t)gid; - vap->va_rdev = (dev_t)rdev; + vap->va_rdev = zfs_cmpldev(rdev); vap->va_nodeid = nodeid; } diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c index 67e886cac2..b4ec0fd662 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vnops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c @@ -1875,7 +1875,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr) vap->va_nodeid = zp->z_id; vap->va_nlink = MIN(pzp->zp_links, UINT32_MAX); /* nlink_t limit! */ vap->va_size = pzp->zp_size; - vap->va_rdev = pzp->zp_rdev; + vap->va_rdev = vp->v_rdev; vap->va_seq = zp->z_seq; ZFS_TIME_DECODE(&vap->va_atime, pzp->zp_atime); diff --git a/usr/src/uts/common/fs/zfs/zfs_znode.c b/usr/src/uts/common/fs/zfs/zfs_znode.c index 74e5c97cc5..15b23b5854 100644 --- a/usr/src/uts/common/fs/zfs/zfs_znode.c +++ b/usr/src/uts/common/fs/zfs/zfs_znode.c @@ -32,6 +32,7 @@ #include <sys/sysmacros.h> #include <sys/resource.h> #include <sys/mntent.h> +#include <sys/mkdev.h> #include <sys/vfs.h> #include <sys/vnode.h> #include <sys/file.h> @@ -327,6 +328,63 @@ zfs_init_fs(zfsvfs_t *zfsvfs, znode_t **zpp, cred_t *cr) } /* + * define a couple of values we need available + * for both 64 and 32 bit environments. + */ +#ifndef NBITSMINOR64 +#define NBITSMINOR64 32 +#endif +#ifndef MAXMAJ64 +#define MAXMAJ64 0xffffffffUL +#endif +#ifndef MAXMIN64 +#define MAXMIN64 0xffffffffUL +#endif + +/* + * Create special expldev for ZFS private use. + * Can't use standard expldev since it doesn't do + * what we want. The standard expldev() takes a + * dev32_t in LP64 and expands it to a long dev_t. + * We need an interface that takes a dev32_t in ILP32 + * and expands it to a long dev_t. + */ +static uint64_t +zfs_expldev(dev_t dev) +{ +#ifndef _LP64 + major_t major = (major_t)dev >> NBITSMINOR32 & MAXMAJ32; + return (((uint64_t)major << NBITSMINOR64) | + ((minor_t)dev & MAXMIN32)); +#else + return (dev); +#endif +} + +/* + * Special cmpldev for ZFS private use. + * Can't use standard cmpldev since it takes + * a long dev_t and compresses it to dev32_t in + * LP64. We need to do a compaction of a long dev_t + * to a dev32_t in ILP32. + */ +dev_t +zfs_cmpldev(uint64_t dev) +{ +#ifndef _LP64 + minor_t minor = (minor_t)dev & MAXMIN64; + major_t major = (major_t)(dev >> NBITSMINOR64) & MAXMAJ64; + + if (major > MAXMAJ32 || minor > MAXMIN32) + return (NODEV32); + + return (((dev32_t)major << NBITSMINOR32) | minor); +#else + return (dev); +#endif +} + +/* * Construct a new znode/vnode and intialize. * * This does not do a call to dmu_set_user() that is @@ -377,7 +435,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, uint64_t obj_num, int blksz) break; case VBLK: case VCHR: - vp->v_rdev = (dev_t)zp->z_phys->zp_rdev; + vp->v_rdev = zfs_cmpldev(zp->z_phys->zp_rdev); /*FALLTHROUGH*/ case VFIFO: case VSOCK: @@ -528,7 +586,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, uint64_t *oid, dmu_tx_t *tx, cred_t *cr, flag |= IS_XATTR; if (vap->va_type == VBLK || vap->va_type == VCHR) { - pzp->zp_rdev = vap->va_rdev; + pzp->zp_rdev = zfs_expldev(vap->va_rdev); } if (vap->va_type == VDIR) { |