Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/ext2fs/ext2_inode_cnv.c
Show All 25 Lines | |||||
/* | /* | ||||
* routines to convert on disk ext2 inodes into inodes and back | * routines to convert on disk ext2 inodes into inodes and back | ||||
*/ | */ | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/endian.h> | #include <sys/endian.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/sdt.h> | |||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/vnode.h> | #include <sys/vnode.h> | ||||
#include <fs/ext2fs/fs.h> | #include <fs/ext2fs/fs.h> | ||||
#include <fs/ext2fs/inode.h> | #include <fs/ext2fs/inode.h> | ||||
#include <fs/ext2fs/ext2fs.h> | #include <fs/ext2fs/ext2fs.h> | ||||
#include <fs/ext2fs/ext2_dinode.h> | #include <fs/ext2fs/ext2_dinode.h> | ||||
#include <fs/ext2fs/ext2_extern.h> | #include <fs/ext2fs/ext2_extern.h> | ||||
SDT_PROVIDER_DECLARE(ext2fs); | |||||
/* | |||||
* ext2fs trace probe: | |||||
* arg0: verbosity. Higher numbers give more verbose messages | |||||
* arg1: Textual message | |||||
*/ | |||||
SDT_PROBE_DEFINE2(ext2fs, , trace, inode_cnv, "int", "char*"); | |||||
#define XTIME_TO_NSEC(x) ((x & EXT3_NSEC_MASK) >> 2) | #define XTIME_TO_NSEC(x) ((x & EXT3_NSEC_MASK) >> 2) | ||||
#define NSEC_TO_XTIME(t) (le32toh(t << 2) & EXT3_NSEC_MASK) | #define NSEC_TO_XTIME(t) (le32toh(t << 2) & EXT3_NSEC_MASK) | ||||
#ifdef EXT2FS_DEBUG | #ifdef EXT2FS_PRINT_EXTENTS | ||||
void | void | ||||
ext2_print_inode(struct inode *in) | ext2_print_inode(struct inode *in) | ||||
{ | { | ||||
int i; | int i; | ||||
struct ext4_extent_header *ehp; | struct ext4_extent_header *ehp; | ||||
struct ext4_extent *ep; | struct ext4_extent *ep; | ||||
printf("Inode: %5ju", (uintmax_t)in->i_number); | printf("Inode: %5ju", (uintmax_t)in->i_number); | ||||
Show All 23 Lines | if (in->i_flag & IN_E4EXTENTS) { | ||||
printf("\n"); | printf("\n"); | ||||
} else { | } else { | ||||
printf("BLOCKS:"); | printf("BLOCKS:"); | ||||
for (i = 0; i < (in->i_blocks <= 24 ? (in->i_blocks + 1) / 2 : 12); i++) | for (i = 0; i < (in->i_blocks <= 24 ? (in->i_blocks + 1) / 2 : 12); i++) | ||||
printf(" %d", in->i_db[i]); | printf(" %d", in->i_db[i]); | ||||
printf("\n"); | printf("\n"); | ||||
} | } | ||||
} | } | ||||
#endif /* EXT2FS_DEBUG */ | #endif /* EXT2FS_PRINT_EXTENTS */ | ||||
/* | /* | ||||
* raw ext2 inode to inode | * raw ext2 inode to inode | ||||
*/ | */ | ||||
int | int | ||||
ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) | ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) | ||||
{ | { | ||||
struct m_ext2fs *fs = ip->i_e2fs; | struct m_ext2fs *fs = ip->i_e2fs; | ||||
if ((ip->i_number < EXT2_FIRST_INO(fs) && ip->i_number != EXT2_ROOTINO) || | if ((ip->i_number < EXT2_FIRST_INO(fs) && ip->i_number != EXT2_ROOTINO) || | ||||
(ip->i_number < EXT2_ROOTINO) || | (ip->i_number < EXT2_ROOTINO) || | ||||
(ip->i_number > fs->e2fs->e2fs_icount)) { | (ip->i_number > fs->e2fs->e2fs_icount)) { | ||||
printf("ext2fs: bad inode number %ju\n", ip->i_number); | SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "bad inode number"); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
if (ip->i_number == EXT2_ROOTINO && ei->e2di_nlink == 0) { | if (ip->i_number == EXT2_ROOTINO && ei->e2di_nlink == 0) { | ||||
printf("ext2fs: root inode unallocated\n"); | SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "root inode unallocated"); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
ip->i_nlink = ei->e2di_nlink; | ip->i_nlink = ei->e2di_nlink; | ||||
/* Check extra inode size */ | /* Check extra inode size */ | ||||
if (EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE) { | if (EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE) { | ||||
if (E2FS_REV0_INODE_SIZE + ei->e2di_extra_isize > | if (E2FS_REV0_INODE_SIZE + ei->e2di_extra_isize > | ||||
EXT2_INODE_SIZE(fs) || (ei->e2di_extra_isize & 3)) { | EXT2_INODE_SIZE(fs) || (ei->e2di_extra_isize & 3)) { | ||||
printf("ext2fs: bad extra inode size %u, inode size=%u\n", | SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, | ||||
ei->e2di_extra_isize, EXT2_INODE_SIZE(fs)); | "bad extra inode size"); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Godmar thinks - if the link count is zero, then the inode is | * Godmar thinks - if the link count is zero, then the inode is | ||||
* unused - according to ext2 standards. Ufs marks this fact by | * unused - according to ext2 standards. Ufs marks this fact by | ||||
* setting i_mode to zero - why ? I can see that this might lead to | * setting i_mode to zero - why ? I can see that this might lead to | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei) | ||||
ei->e2di_flags = 0; | ei->e2di_flags = 0; | ||||
ei->e2di_flags |= (ip->i_flags & SF_APPEND) ? EXT2_APPEND : 0; | ei->e2di_flags |= (ip->i_flags & SF_APPEND) ? EXT2_APPEND : 0; | ||||
ei->e2di_flags |= (ip->i_flags & SF_IMMUTABLE) ? EXT2_IMMUTABLE : 0; | ei->e2di_flags |= (ip->i_flags & SF_IMMUTABLE) ? EXT2_IMMUTABLE : 0; | ||||
ei->e2di_flags |= (ip->i_flags & UF_NODUMP) ? EXT2_NODUMP : 0; | ei->e2di_flags |= (ip->i_flags & UF_NODUMP) ? EXT2_NODUMP : 0; | ||||
ei->e2di_flags |= (ip->i_flag & IN_E3INDEX) ? EXT3_INDEX : 0; | ei->e2di_flags |= (ip->i_flag & IN_E3INDEX) ? EXT3_INDEX : 0; | ||||
ei->e2di_flags |= (ip->i_flag & IN_E4EXTENTS) ? EXT4_EXTENTS : 0; | ei->e2di_flags |= (ip->i_flag & IN_E4EXTENTS) ? EXT4_EXTENTS : 0; | ||||
if (ip->i_blocks > ~0U && | if (ip->i_blocks > ~0U && | ||||
!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_HUGE_FILE)) { | !EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_HUGE_FILE)) { | ||||
ext2_fserr(fs, ip->i_uid, "i_blocks value is out of range"); | SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "i_blocks value is out of range"); | ||||
return (EIO); | return (EIO); | ||||
} | } | ||||
if (ip->i_blocks <= 0xffffffffffffULL) { | if (ip->i_blocks <= 0xffffffffffffULL) { | ||||
ei->e2di_nblock = ip->i_blocks & 0xffffffff; | ei->e2di_nblock = ip->i_blocks & 0xffffffff; | ||||
ei->e2di_nblock_high = ip->i_blocks >> 32 & 0xffff; | ei->e2di_nblock_high = ip->i_blocks >> 32 & 0xffff; | ||||
} else { | } else { | ||||
ei->e2di_flags |= EXT4_HUGE_FILE; | ei->e2di_flags |= EXT4_HUGE_FILE; | ||||
ei->e2di_nblock = dbtofsb(fs, ip->i_blocks); | ei->e2di_nblock = dbtofsb(fs, ip->i_blocks); | ||||
Show All 17 Lines |