diff options
author | Pedro Martelletto <pedro@cvs.openbsd.org> | 2005-10-06 17:43:15 +0000 |
---|---|---|
committer | Pedro Martelletto <pedro@cvs.openbsd.org> | 2005-10-06 17:43:15 +0000 |
commit | 6b5c4875730c0625ade9a9e0956158ef63d060cc (patch) | |
tree | 86c108ac00103fca450cd730e5365a20cf6c328d /sys | |
parent | 6b9104e190b8c030c1d44562a060f447f659554a (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.c | 8 | ||||
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_dinode.h | 12 | ||||
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_inode.c | 13 | ||||
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_vfsops.c | 14 | ||||
-rw-r--r-- | sys/ufs/ufs/inode.h | 22 |
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. */ |