From 1317ca3f44b4b785118985479c268875f29571df Mon Sep 17 00:00:00 2001 From: pfg Date: Tue, 21 Jan 2014 19:06:29 +0000 Subject: [PATCH] ext2fs: Translate the EXT4_EXTENTS and EXT4_INDEX to the inode flags. r260545 cleared the inode flags to fix corruption problems but we still need to pass some EXT4 flags for the ext4 read-only mode. None of these attributes has an equivalent in FreeBSD and are uninteresting for the system utilities so they should be innaccessible in ext2_getattrib(). Note: we also use EXT4_HUGE_FILE but we use it directly from the dinode structure so it is not necessary to translate it, Suggested by: bde MFC after: 3 days --- sys/fs/ext2fs/ext2_bmap.c | 2 +- sys/fs/ext2fs/ext2_dinode.h | 20 +++++++++++--------- sys/fs/ext2fs/ext2_htree.c | 4 ++-- sys/fs/ext2fs/ext2_inode_cnv.c | 2 ++ sys/fs/ext2fs/ext2_lookup.c | 3 ++- sys/fs/ext2fs/ext2_subr.c | 8 ++++---- sys/fs/ext2fs/ext2_vfsops.c | 6 +++--- sys/fs/ext2fs/ext2_vnops.c | 4 +++- sys/fs/ext2fs/inode.h | 7 +++++++ 9 files changed, 35 insertions(+), 21 deletions(-) diff --git a/sys/fs/ext2fs/ext2_bmap.c b/sys/fs/ext2fs/ext2_bmap.c index 29cd7af64ea2..ca679c5a9baf 100644 --- a/sys/fs/ext2fs/ext2_bmap.c +++ b/sys/fs/ext2fs/ext2_bmap.c @@ -74,7 +74,7 @@ ext2_bmap(struct vop_bmap_args *ap) if (ap->a_bnp == NULL) return (0); - if (VTOI(ap->a_vp)->i_flags & EXT4_EXTENTS) + if (VTOI(ap->a_vp)->i_flags & E4_EXTENTS) error = ext4_bmapext(ap->a_vp, ap->a_bn, &blkno, ap->a_runp, ap->a_runb); else diff --git a/sys/fs/ext2fs/ext2_dinode.h b/sys/fs/ext2fs/ext2_dinode.h index 41b0236e732a..2f2a963f153d 100644 --- a/sys/fs/ext2fs/ext2_dinode.h +++ b/sys/fs/ext2fs/ext2_dinode.h @@ -50,22 +50,24 @@ /* * Inode flags - * The current implementation uses only EXT2_IMMUTABLE and EXT2_APPEND flags + * The system supports EXT2_IMMUTABLE, EXT2_APPEND and EXT2_NODUMP flags. + * The current implementation also uses EXT4_INDEX, EXT4_EXTENTS and + * EXT4_HUGE_FILE with some restrictions, imposed the lack of write + * support. */ #define EXT2_SECRM 0x00000001 /* Secure deletion */ #define EXT2_UNRM 0x00000002 /* Undelete */ #define EXT2_COMPR 0x00000004 /* Compress file */ #define EXT2_SYNC 0x00000008 /* Synchronous updates */ #define EXT2_IMMUTABLE 0x00000010 /* Immutable file */ -#define EXT2_APPEND 0x00000020 /* writes to file may only append */ -#define EXT2_NODUMP 0x00000040 /* do not dump file */ -#define EXT2_NOATIME 0x00000080 /* do not update atime */ - -#define EXT4_INDEX 0x00001000 /* hash-indexed directory */ +#define EXT2_APPEND 0x00000020 /* Writes to file may only append */ +#define EXT2_NODUMP 0x00000040 /* Do not dump file */ +#define EXT2_NOATIME 0x00000080 /* Do not update atime */ +#define EXT4_INDEX 0x00001000 /* Hash-indexed directory */ #define EXT4_IMAGIC 0x00002000 /* AFS directory */ -#define EXT4_JOURNAL_DATA 0x00004000 /* file data should be journaled */ -#define EXT4_NOTAIL 0x00008000 /* file tail should not be merged */ -#define EXT4_DIRSYNC 0x00010000 /* dirsync behaviour */ +#define EXT4_JOURNAL_DATA 0x00004000 /* File data should be journaled */ +#define EXT4_NOTAIL 0x00008000 /* File tail should not be merged */ +#define EXT4_DIRSYNC 0x00010000 /* Dirsync behaviour */ #define EXT4_TOPDIR 0x00020000 /* Top of directory hierarchies*/ #define EXT4_HUGE_FILE 0x00040000 /* Set to each huge file */ #define EXT4_EXTENTS 0x00080000 /* Inode uses extents */ diff --git a/sys/fs/ext2fs/ext2_htree.c b/sys/fs/ext2fs/ext2_htree.c index ff1e1a5ef61e..7eeab12d4e93 100644 --- a/sys/fs/ext2fs/ext2_htree.c +++ b/sys/fs/ext2fs/ext2_htree.c @@ -91,7 +91,7 @@ ext2_htree_has_idx(struct inode *ip) { #ifdef EXT2FS_HTREE if (EXT2_HAS_COMPAT_FEATURE(ip->i_e2fs, EXT2F_COMPAT_DIRHASHINDEX) && - ip->i_flags & EXT4_INDEX) + ip->i_flags & E4_INDEX) return (1); else #endif @@ -656,7 +656,7 @@ ext2_htree_create_index(struct vnode *vp, struct componentname *cnp, ((char *)ep + ep->e2d_reclen); ep->e2d_reclen = buf1 + blksize - (char *)ep; - dp->i_flags |= EXT4_INDEX; + dp->i_flags |= E4_INDEX; /* * Initialize index root. diff --git a/sys/fs/ext2fs/ext2_inode_cnv.c b/sys/fs/ext2fs/ext2_inode_cnv.c index 67712d070cf7..2205e3ba6ed4 100644 --- a/sys/fs/ext2fs/ext2_inode_cnv.c +++ b/sys/fs/ext2fs/ext2_inode_cnv.c @@ -108,6 +108,8 @@ ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) ip->i_flags |= (ei->e2di_flags & EXT2_APPEND) ? SF_APPEND : 0; ip->i_flags |= (ei->e2di_flags & EXT2_IMMUTABLE) ? SF_IMMUTABLE : 0; ip->i_flags |= (ei->e2di_flags & EXT2_NODUMP) ? UF_NODUMP : 0; + ip->i_flags |= (ei->e2di_flags & EXT4_INDEX) ? E4_INDEX : 0; + ip->i_flags |= (ei->e2di_flags & EXT4_EXTENTS) ? E4_EXTENTS : 0; ip->i_blocks = ei->e2di_nblock; if (E2DI_HAS_HUGE_FILE(ip)) { ip->i_blocks |= (uint64_t)ei->e2di_nblock_high << 32; diff --git a/sys/fs/ext2fs/ext2_lookup.c b/sys/fs/ext2fs/ext2_lookup.c index d6075542fa8d..02e66f76724a 100644 --- a/sys/fs/ext2fs/ext2_lookup.c +++ b/sys/fs/ext2fs/ext2_lookup.c @@ -888,8 +888,9 @@ ext2_direnter(struct inode *ip, struct vnode *dvp, struct componentname *cnp) if (ext2_htree_has_idx(dp)) { error = ext2_htree_add_entry(dvp, &newdir, cnp); if (error) { - dp->i_flags &= ~EXT4_INDEX; + /* XXX: These seem to be set in the wrong place. */ dp->i_flags |= IN_CHANGE | IN_UPDATE; + dp->i_flags &= ~E4_INDEX; } return (error); } diff --git a/sys/fs/ext2fs/ext2_subr.c b/sys/fs/ext2fs/ext2_subr.c index ec10ea86dabf..09fcee80654e 100644 --- a/sys/fs/ext2fs/ext2_subr.c +++ b/sys/fs/ext2fs/ext2_subr.c @@ -82,10 +82,10 @@ ext2_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp) *bpp = NULL; /* - * The EXT4_EXTENTS requires special treatment, otherwise we can - * fall back to the normal path. + * E4_EXTENTS requires special treatment otherwise we can fall + * back to the normal path. */ - if (!(ip->i_flags & EXT4_EXTENTS)) + if (!(ip->i_flags & E4_EXTENTS)) goto normal; memset(&path, 0, sizeof(path)); @@ -110,7 +110,7 @@ ext2_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp) if (res) *res = (char *)bp->b_data + blkoff(fs, offset); /* - * If EXT4_EXTENTS is enabled we would get a wrong offset so + * If E4_EXTENTS is enabled we would get a wrong offset so * reset b_offset here. */ bp->b_offset = lbn * bsize; diff --git a/sys/fs/ext2fs/ext2_vfsops.c b/sys/fs/ext2fs/ext2_vfsops.c index b4683564bd8f..3ad5786af495 100644 --- a/sys/fs/ext2fs/ext2_vfsops.c +++ b/sys/fs/ext2fs/ext2_vfsops.c @@ -964,10 +964,10 @@ ext2_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) * blocks are zeroed out - ext2_balloc depends on this * although for regular files and directories only * - * If EXT4_EXTENTS flag is enabled, unused blocks aren't - * zeroed out because we could corrupt the extent tree. + * If E4_EXTENTS is enabled, unused blocks are not zeroed + * out because we could corrupt the extent tree. */ - if (!(ip->i_flags & EXT4_EXTENTS) && + if (!(ip->i_flags & E4_EXTENTS) && (S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode))) { used_blocks = (ip->i_size+fs->e2fs_bsize-1) / fs->e2fs_bsize; for (i = used_blocks; i < EXT2_NDIR_BLOCKS; i++) diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c index 04ef9e2b81d8..72a008bd3338 100644 --- a/sys/fs/ext2fs/ext2_vnops.c +++ b/sys/fs/ext2fs/ext2_vnops.c @@ -344,6 +344,8 @@ ext2_getattr(struct vop_getattr_args *ap) vap->va_birthtime.tv_nsec = ip->i_birthnsec; } vap->va_flags = ip->i_flags; + /* E4_* flags are private to the driver */ + vap->va_flags &= !(E4_INDEX | E4_EXTENTS); vap->va_gen = ip->i_gen; vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize; vap->va_bytes = dbtob((u_quad_t)ip->i_blocks); @@ -1615,7 +1617,7 @@ ext2_read(struct vop_read_args *ap) ip = VTOI(vp); /*EXT4_EXT_LOCK(ip);*/ - if (ip->i_flags & EXT4_EXTENTS) + if (ip->i_flags & E4_EXTENTS) error = ext4_ext_read(ap); else error = ext2_ind_read(ap); diff --git a/sys/fs/ext2fs/inode.h b/sys/fs/ext2fs/inode.h index e2016c51a02f..af244adecd2d 100644 --- a/sys/fs/ext2fs/inode.h +++ b/sys/fs/ext2fs/inode.h @@ -153,6 +153,13 @@ struct inode { #define IN_LAZYACCESS 0x0100 /* Process IN_ACCESS after the suspension finished */ +/* + * These are translation flags for some attributes that Ext4 + * passes as inode flags but that we cannot pass directly. + */ +#define E4_INDEX 0x01000000 +#define E4_EXTENTS 0x02000000 + #define i_devvp i_ump->um_devvp #ifdef _KERNEL