summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorPedro Martelletto <pedro@cvs.openbsd.org>2005-10-06 17:43:15 +0000
committerPedro Martelletto <pedro@cvs.openbsd.org>2005-10-06 17:43:15 +0000
commit6b5c4875730c0625ade9a9e0956158ef63d060cc (patch)
tree86c108ac00103fca450cd730e5365a20cf6c328d /sys
parent6b9104e190b8c030c1d44562a060f447f659554a (diff)
Use part of the reserved space on the disk inode to scatter 16 more bits
for the UID and GID, making them 32-bit. Based on what Linux does, with a slightly different implementation. Endianess issue in fsck noted by miod@, okay deraadt@.
Diffstat (limited to 'sys')
-rw-r--r--sys/ufs/ext2fs/ext2fs_bswap.c8
-rw-r--r--sys/ufs/ext2fs/ext2fs_dinode.h12
-rw-r--r--sys/ufs/ext2fs/ext2fs_inode.c13
-rw-r--r--sys/ufs/ext2fs/ext2fs_vfsops.c14
-rw-r--r--sys/ufs/ufs/inode.h22
5 files changed, 50 insertions, 19 deletions
diff --git a/sys/ufs/ext2fs/ext2fs_bswap.c b/sys/ufs/ext2fs/ext2fs_bswap.c
index 7f14b8ef1d7..94e77e37edd 100644
--- a/sys/ufs/ext2fs/ext2fs_bswap.c
+++ b/sys/ufs/ext2fs/ext2fs_bswap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs_bswap.c,v 1.2 2001/09/18 09:12:36 art Exp $ */
+/* $OpenBSD: ext2fs_bswap.c,v 1.3 2005/10/06 17:43:14 pedro Exp $ */
/* $NetBSD: ext2fs_bswap.c,v 1.6 2000/07/24 00:23:10 mycroft Exp $ */
/*
@@ -107,8 +107,10 @@ e2fs_i_bswap(old, new)
struct ext2fs_dinode *old, *new;
{
new->e2di_mode = swap16(old->e2di_mode);
- new->e2di_uid = swap16(old->e2di_uid);
- new->e2di_gid = swap16(old->e2di_gid);
+ new->e2di_uid_low = swap16(old->e2di_uid_low);
+ new->e2di_gid_low = swap16(old->e2di_gid_low);
+ new->e2di_uid_high = swap16(old->e2di_uid_high);
+ new->e2di_gid_high = swap16(old->e2di_gid_high);
new->e2di_nlink = swap16(old->e2di_nlink);
new->e2di_size = swap32(old->e2di_size);
new->e2di_atime = swap32(old->e2di_atime);
diff --git a/sys/ufs/ext2fs/ext2fs_dinode.h b/sys/ufs/ext2fs/ext2fs_dinode.h
index 6d4d54cc986..f7e560131ee 100644
--- a/sys/ufs/ext2fs/ext2fs_dinode.h
+++ b/sys/ufs/ext2fs/ext2fs_dinode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs_dinode.h,v 1.8 2003/06/02 23:28:22 millert Exp $ */
+/* $OpenBSD: ext2fs_dinode.h,v 1.9 2005/10/06 17:43:14 pedro Exp $ */
/* $NetBSD: ext2fs_dinode.h,v 1.6 2000/01/26 16:21:33 bouyer Exp $ */
/*
@@ -64,13 +64,13 @@
struct ext2fs_dinode {
u_int16_t e2di_mode; /* 0: IFMT, permissions; see below. */
- u_int16_t e2di_uid; /* 2: Owner UID */
+ u_int16_t e2di_uid_low; /* 2: Owner UID, lowest bits */
u_int32_t e2di_size; /* 4: Size (in bytes) */
u_int32_t e2di_atime; /* 8: Acces time */
u_int32_t e2di_ctime; /* 12: Create time */
u_int32_t e2di_mtime; /* 16: Modification time */
u_int32_t e2di_dtime; /* 20: Deletion time */
- u_int16_t e2di_gid; /* 24: Owner GID */
+ u_int16_t e2di_gid_low; /* 24: Owner GID, lowest bits */
u_int16_t e2di_nlink; /* 26: File link count */
u_int32_t e2di_nblock; /* 28: Blocks count */
u_int32_t e2di_flags; /* 32: Status flags (chflags) */
@@ -83,11 +83,11 @@ struct ext2fs_dinode {
u_int8_t e2di_nfrag; /* 116: fragment number */
u_int8_t e2di_fsize; /* 117: fragment size */
u_int16_t e2di_linux_reserved2; /* 118 */
- u_int32_t e2di_linux_reserved3[2]; /* 120 */
+ u_int16_t e2di_uid_high; /* 120: 16 highest bits of uid */
+ u_int16_t e2di_gid_high; /* 122: 16 highest bits of gid */
+ u_int32_t e2di_linux_reserved3; /* 124 */
};
-
-
#define E2MAXSYMLINKLEN ((NDADDR + NIADDR) * sizeof(u_int32_t))
/* File permissions. */
diff --git a/sys/ufs/ext2fs/ext2fs_inode.c b/sys/ufs/ext2fs/ext2fs_inode.c
index 7ddf4c0bf59..c969759606b 100644
--- a/sys/ufs/ext2fs/ext2fs_inode.c
+++ b/sys/ufs/ext2fs/ext2fs_inode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs_inode.c,v 1.28 2005/08/14 12:45:24 pedro Exp $ */
+/* $OpenBSD: ext2fs_inode.c,v 1.29 2005/10/06 17:43:14 pedro Exp $ */
/* $NetBSD: ext2fs_inode.c,v 1.24 2001/06/19 12:59:18 wiz Exp $ */
/*
@@ -189,6 +189,17 @@ ext2fs_update(struct inode *ip, struct timespec *atime, struct timespec *mtime,
ip->i_flag &= ~(IN_MODIFIED);
cp = (caddr_t)bp->b_data +
(ino_to_fsbo(fs, ip->i_number) * EXT2_DINODE_SIZE);
+
+ /*
+ * See note about 16-bit UID/GID limitation in ext2fs_vget(). Now
+ * that we are about to write the inode, construct the split UID and
+ * GID fields out of the two 32-bit fields we kept in memory.
+ */
+ ip->i_e2fs_uid_low = (u_int16_t)ip->i_e2fs_uid;
+ ip->i_e2fs_gid_low = (u_int16_t)ip->i_e2fs_gid;
+ ip->i_e2fs_uid_high = ip->i_e2fs_uid >> 16;
+ ip->i_e2fs_gid_high = ip->i_e2fs_gid >> 16;
+
e2fs_isave(&ip->i_e2din, (struct ext2fs_dinode *)cp);
if (waitfor)
return (bwrite(bp));
diff --git a/sys/ufs/ext2fs/ext2fs_vfsops.c b/sys/ufs/ext2fs/ext2fs_vfsops.c
index cbd728ee8e4..9493378d3cf 100644
--- a/sys/ufs/ext2fs/ext2fs_vfsops.c
+++ b/sys/ufs/ext2fs/ext2fs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs_vfsops.c,v 1.38 2005/07/28 23:11:25 pedro Exp $ */
+/* $OpenBSD: ext2fs_vfsops.c,v 1.39 2005/10/06 17:43:14 pedro Exp $ */
/* $NetBSD: ext2fs_vfsops.c,v 1.1 1997/06/11 09:34:07 bouyer Exp $ */
/*
@@ -896,6 +896,18 @@ ext2fs_vget(mp, ino, vpp)
bcopy(((struct ext2fs_dinode*)bp->b_data + ino_to_fsbo(fs, ino)),
&ip->i_e2din, sizeof(struct ext2fs_dinode));
ip->i_effnlink = ip->i_e2fs_nlink;
+
+ /*
+ * The fields for storing the UID and GID of an ext2fs inode are
+ * limited to 16 bits. To overcome this limitation, Linux decided to
+ * scatter the highest bits of these values into a previously reserved
+ * area on the disk inode. We deal with this situation by having two
+ * 32-bit fields *out* of the disk inode to hold the complete values.
+ * Now that we are reading in the inode, compute these fields.
+ */
+ ip->i_e2fs_uid = ip->i_e2fs_uid_low | (ip->i_e2fs_uid_high << 16);
+ ip->i_e2fs_gid = ip->i_e2fs_gid_low | (ip->i_e2fs_gid_high << 16);
+
brelse(bp);
/* If the inode was deleted, reset all fields */
diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
index 12c6f5ce9f6..70e09eea1d4 100644
--- a/sys/ufs/ufs/inode.h
+++ b/sys/ufs/ufs/inode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: inode.h,v 1.27 2004/07/13 21:04:29 millert Exp $ */
+/* $OpenBSD: inode.h,v 1.28 2005/10/06 17:43:14 pedro Exp $ */
/* $NetBSD: inode.h,v 1.8 1995/06/15 23:22:50 cgd Exp $ */
/*
@@ -46,8 +46,10 @@
* Per-filesystem inode extensions.
*/
struct ext2fs_inode_ext {
- ufs1_daddr_t ext2fs_last_lblk; /* last logical block allocated */
- ufs1_daddr_t ext2fs_last_blk; /* last block allocated on disk */
+ ufs1_daddr_t ext2fs_last_lblk; /* last logical block allocated */
+ ufs1_daddr_t ext2fs_last_blk; /* last block allocated on disk */
+ u_int32_t ext2fs_effective_uid; /* effective inode uid */
+ u_int32_t ext2fs_effective_gid; /* effective inode gid */
};
/*
@@ -100,9 +102,11 @@ struct inode {
struct ext2fs_inode_ext e2fs;
struct dirhash *dirhash;
} inode_ext;
-#define i_e2fs_last_lblk inode_ext.e2fs.ext2fs_last_lblk
-#define i_e2fs_last_blk inode_ext.e2fs.ext2fs_last_blk
-#define i_dirhash inode_ext.dirhash
+#define i_e2fs_last_lblk inode_ext.e2fs.ext2fs_last_lblk
+#define i_e2fs_last_blk inode_ext.e2fs.ext2fs_last_blk
+#define i_e2fs_uid inode_ext.e2fs.ext2fs_effective_uid
+#define i_e2fs_gid inode_ext.e2fs.ext2fs_effective_gid
+#define i_dirhash inode_ext.dirhash
/*
* The on-disk dinode itself.
@@ -201,13 +205,11 @@ struct inode_vtbl {
#endif /* _KERNEL */
#define i_e2fs_mode i_e2din.e2di_mode
-#define i_e2fs_uid i_e2din.e2di_uid
#define i_e2fs_size i_e2din.e2di_size
#define i_e2fs_atime i_e2din.e2di_atime
#define i_e2fs_ctime i_e2din.e2di_ctime
#define i_e2fs_mtime i_e2din.e2di_mtime
#define i_e2fs_dtime i_e2din.e2di_dtime
-#define i_e2fs_gid i_e2din.e2di_gid
#define i_e2fs_nlink i_e2din.e2di_nlink
#define i_e2fs_nblock i_e2din.e2di_nblock
#define i_e2fs_flags i_e2din.e2di_flags
@@ -218,6 +220,10 @@ struct inode_vtbl {
#define i_e2fs_faddr i_e2din.e2di_faddr
#define i_e2fs_nfrag i_e2din.e2di_nfrag
#define i_e2fs_fsize i_e2din.e2di_fsize
+#define i_e2fs_uid_low i_e2din.e2di_uid_low
+#define i_e2fs_gid_low i_e2din.e2di_gid_low
+#define i_e2fs_uid_high i_e2din.e2di_uid_high
+#define i_e2fs_gid_high i_e2din.e2di_gid_high
/* These flags are kept in i_flag. */
#define IN_ACCESS 0x0001 /* Access time update request. */