summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext2fs/ext2_fs.h15
-rw-r--r--ext2fs/inode.c13
2 files changed, 22 insertions, 6 deletions
diff --git a/ext2fs/ext2_fs.h b/ext2fs/ext2_fs.h
index feeecea9..a5a19317 100644
--- a/ext2fs/ext2_fs.h
+++ b/ext2fs/ext2_fs.h
@@ -216,13 +216,13 @@ struct ext2_group_desc
*/
struct ext2_inode {
__u16 i_mode; /* File mode */
- __u16 i_uid; /* Owner Uid */
+ __u16 i_uid; /* Low 16 bits of Owner Uid */
__u32 i_size; /* Size in bytes */
__u32 i_atime; /* Access time */
__u32 i_ctime; /* Creation time */
__u32 i_mtime; /* Modification time */
__u32 i_dtime; /* Deletion Time */
- __u16 i_gid; /* Group Id */
+ __u16 i_gid; /* Low 16 bits of Group Id */
__u16 i_links_count; /* Links count */
__u32 i_blocks; /* Blocks count */
__u32 i_flags; /* File flags */
@@ -247,7 +247,9 @@ struct ext2_inode {
__u8 l_i_frag; /* Fragment number */
__u8 l_i_fsize; /* Fragment size */
__u16 i_pad1;
- __u32 l_i_reserved2[2];
+ __u16 l_i_uid_high; /* these 2 fields */
+ __u16 l_i_gid_high; /* were reserved2[0] */
+ __u32 l_i_reserved2;
} linux2;
struct {
__u8 h_i_frag; /* Fragment number */
@@ -272,6 +274,10 @@ struct ext2_inode {
#define i_reserved1 osd1.linux1.l_i_reserved1
#define i_frag osd2.linux2.l_i_frag
#define i_fsize osd2.linux2.l_i_fsize
+#define i_uid_low i_uid
+#define i_gid_low i_gid
+#define i_uid_high osd2.linux2.l_i_uid_high
+#define i_gid_high osd2.linux2.l_i_gid_high
#define i_reserved2 osd2.linux2.l_i_reserved2
#endif
@@ -310,6 +316,7 @@ struct ext2_inode {
#define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */
#define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */
#define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */
+#define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */
#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
#define set_opt(o, opt) o |= EXT2_MOUNT_##opt
@@ -597,7 +604,6 @@ extern void ext2_put_super (struct super_block *);
extern void ext2_write_super (struct super_block *);
extern int ext2_remount (struct super_block *, int *, char *);
extern struct super_block * ext2_read_super (struct super_block *,void *,int);
-extern int init_ext2_fs(void);
extern int ext2_statfs (struct super_block *, struct statfs *, int);
/* truncate.c */
@@ -615,6 +621,7 @@ extern struct inode_operations ext2_file_inode_operations;
/* symlink.c */
extern struct inode_operations ext2_symlink_inode_operations;
+extern struct inode_operations ext2_fast_symlink_inode_operations;
#endif /* __KERNEL__ */
diff --git a/ext2fs/inode.c b/ext2fs/inode.c
index 6be299fd..b3f07df4 100644
--- a/ext2fs/inode.c
+++ b/ext2fs/inode.c
@@ -335,8 +335,17 @@ check_high_bits (struct node *np, long l)
{
if (sblock->s_creator_os == EXT2_OS_HURD)
return 0;
- else
- return ((l & ~0xFFFF) == 0) ? 0 : EINVAL;
+
+ /* Linux 2.3.42 has a mount-time option (not a bit stored on disk)
+ NO_UID32 to ignore the high 16 bits of uid and gid, but by default
+ allows them. It also does this check for "interoperability with old
+ kernels". Note that our check refuses to change the values, while
+ Linux 2.3.42 just silently clears the high bits in an inode it updates,
+ even if it was updating it for an unrelated reason. */
+ if (np->dn->info.i_dtime != 0)
+ return 0;
+
+ return ((l & ~0xFFFF) == 0) ? 0 : EINVAL;
}
/* Return 0 if NP's owner can be changed to UID; otherwise return an error