cregit-Linux how code gets into the kernel

Release 4.10 fs/ext4/ext4.h

Directory: fs/ext4
/*
 *  ext4.h
 *
 * Copyright (C) 1992, 1993, 1994, 1995
 * Remy Card (card@masi.ibp.fr)
 * Laboratoire MASI - Institut Blaise Pascal
 * Universite Pierre et Marie Curie (Paris VI)
 *
 *  from
 *
 *  linux/include/linux/minix_fs.h
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */

#ifndef _EXT4_H

#define _EXT4_H

#include <linux/types.h>
#include <linux/blkdev.h>
#include <linux/magic.h>
#include <linux/jbd2.h>
#include <linux/quota.h>
#include <linux/rwsem.h>
#include <linux/rbtree.h>
#include <linux/seqlock.h>
#include <linux/mutex.h>
#include <linux/timer.h>
#include <linux/version.h>
#include <linux/wait.h>
#include <linux/blockgroup_lock.h>
#include <linux/percpu_counter.h>
#include <linux/ratelimit.h>
#include <crypto/hash.h>
#include <linux/fscrypto.h>
#include <linux/falloc.h>
#include <linux/percpu-rwsem.h>
#ifdef __KERNEL__
#include <linux/compat.h>
#endif

/*
 * The fourth extended filesystem constants/structures
 */

/*
 * with AGGRESSIVE_CHECK allocator runs consistency checks over
 * structures. these checks slow things down a lot
 */

#define AGGRESSIVE_CHECK__

/*
 * with DOUBLE_CHECK defined mballoc creates persistent in-core
 * bitmaps, maintains and uses them to check for double allocations
 */

#define DOUBLE_CHECK__

/*
 * Define EXT4FS_DEBUG to produce debug messages
 */

#undef EXT4FS_DEBUG

/*
 * Debug code
 */
#ifdef EXT4FS_DEBUG

#define ext4_debug(f, a...)						\
	do {                                                            \
                printk(KERN_DEBUG "EXT4-fs DEBUG (%s, %d): %s:",        \
                        __FILE__, __LINE__, __func__);                  \
                printk(KERN_DEBUG f, ## a);                             \
        } while (0)
#else

#define ext4_debug(fmt, ...)	no_printk(fmt, ##__VA_ARGS__)
#endif

/*
 * Turn on EXT_DEBUG to get lots of info about extents operations.
 */

#define EXT_DEBUG__
#ifdef EXT_DEBUG

#define ext_debug(fmt, ...)	printk(fmt, ##__VA_ARGS__)
#else

#define ext_debug(fmt, ...)	no_printk(fmt, ##__VA_ARGS__)
#endif

/* data type for block offset of block group */

typedef int ext4_grpblk_t;

/* data type for filesystem-wide blocks number */

typedef unsigned long long ext4_fsblk_t;

/* data type for file logical block number */

typedef __u32 ext4_lblk_t;

/* data type for block group number */

typedef unsigned int ext4_group_t;


enum SHIFT_DIRECTION {
	
SHIFT_LEFT = 0,
	
SHIFT_RIGHT,
};

/*
 * Flags used in mballoc's allocation_context flags field.
 *
 * Also used to show what's going on for debugging purposes when the
 * flag field is exported via the traceport interface
 */

/* prefer goal again. length */

#define EXT4_MB_HINT_MERGE		0x0001
/* blocks already reserved */

#define EXT4_MB_HINT_RESERVED		0x0002
/* metadata is being allocated */

#define EXT4_MB_HINT_METADATA		0x0004
/* first blocks in the file */

#define EXT4_MB_HINT_FIRST		0x0008
/* search for the best chunk */

#define EXT4_MB_HINT_BEST		0x0010
/* data is being allocated */

#define EXT4_MB_HINT_DATA		0x0020
/* don't preallocate (for tails) */

#define EXT4_MB_HINT_NOPREALLOC		0x0040
/* allocate for locality group */

#define EXT4_MB_HINT_GROUP_ALLOC	0x0080
/* allocate goal blocks or none */

#define EXT4_MB_HINT_GOAL_ONLY		0x0100
/* goal is meaningful */

#define EXT4_MB_HINT_TRY_GOAL		0x0200
/* blocks already pre-reserved by delayed allocation */

#define EXT4_MB_DELALLOC_RESERVED	0x0400
/* We are doing stream allocation */

#define EXT4_MB_STREAM_ALLOC		0x0800
/* Use reserved root blocks if needed */

#define EXT4_MB_USE_ROOT_BLOCKS		0x1000
/* Use blocks from reserved pool */

#define EXT4_MB_USE_RESERVED		0x2000


struct ext4_allocation_request {
	/* target inode for block we're allocating */
	
struct inode *inode;
	/* how many blocks we want to allocate */
	
unsigned int len;
	/* logical block in target inode */
	
ext4_lblk_t logical;
	/* the closest logical allocated block to the left */
	
ext4_lblk_t lleft;
	/* the closest logical allocated block to the right */
	
ext4_lblk_t lright;
	/* phys. target (a hint) */
	
ext4_fsblk_t goal;
	/* phys. block for the closest logical allocated block to the left */
	
ext4_fsblk_t pleft;
	/* phys. block for the closest logical allocated block to the right */
	
ext4_fsblk_t pright;
	/* flags. see above EXT4_MB_HINT_* */
	
unsigned int flags;
};

/*
 * Logical to physical block mapping, used by ext4_map_blocks()
 *
 * This structure is used to pass requests into ext4_map_blocks() as
 * well as to store the information returned by ext4_map_blocks().  It
 * takes less room on the stack than a struct buffer_head.
 */

#define EXT4_MAP_NEW		(1 << BH_New)

#define EXT4_MAP_MAPPED		(1 << BH_Mapped)

#define EXT4_MAP_UNWRITTEN	(1 << BH_Unwritten)

#define EXT4_MAP_BOUNDARY	(1 << BH_Boundary)

#define EXT4_MAP_FLAGS		(EXT4_MAP_NEW | EXT4_MAP_MAPPED |\
                                 EXT4_MAP_UNWRITTEN | EXT4_MAP_BOUNDARY)


struct ext4_map_blocks {
	
ext4_fsblk_t m_pblk;
	
ext4_lblk_t m_lblk;
	
unsigned int m_len;
	
unsigned int m_flags;
};

/*
 * Flags for ext4_io_end->flags
 */

#define	EXT4_IO_END_UNWRITTEN	0x0001

/*
 * For converting unwritten extents on a work queue. 'handle' is used for
 * buffered writeback.
 */

typedef struct ext4_io_end {
	
struct list_head	list;		/* per-file finished IO list */
	
handle_t		*handle;	/* handle reserved for extent
                                                 * conversion */
	
struct inode		*inode;		/* file being written to */
	
struct bio		*bio;		/* Linked list of completed
                                                 * bios covering the extent */
	
unsigned int		flag;		/* unwritten or not */
	
atomic_t		count;		/* reference counter */
	
loff_t			offset;		/* offset in the file */
	
ssize_t			size;		/* size of the extent */
} 
ext4_io_end_t;


struct ext4_io_submit {
	
struct writeback_control *io_wbc;
	
struct bio		*io_bio;
	
ext4_io_end_t		*io_end;
	
sector_t		io_next_block;
};

/*
 * Special inodes numbers
 */

#define	EXT4_BAD_INO		 1	
/* Bad blocks inode */

#define EXT4_ROOT_INO		 2	
/* Root inode */

#define EXT4_USR_QUOTA_INO	 3	
/* User quota inode */

#define EXT4_GRP_QUOTA_INO	 4	
/* Group quota inode */

#define EXT4_BOOT_LOADER_INO	 5	
/* Boot loader inode */

#define EXT4_UNDEL_DIR_INO	 6	
/* Undelete directory inode */

#define EXT4_RESIZE_INO		 7	
/* Reserved group descriptors inode */

#define EXT4_JOURNAL_INO	 8	
/* Journal inode */

/* First non-reserved inode for old ext4 filesystems */

#define EXT4_GOOD_OLD_FIRST_INO	11

/*
 * Maximal count of links to a file
 */

#define EXT4_LINK_MAX		65000

/*
 * Macro-instructions used to manage several block sizes
 */

#define EXT4_MIN_BLOCK_SIZE		1024

#define	EXT4_MAX_BLOCK_SIZE		65536

#define EXT4_MIN_BLOCK_LOG_SIZE		10

#define EXT4_MAX_BLOCK_LOG_SIZE		16

#define EXT4_MAX_CLUSTER_LOG_SIZE	30
#ifdef __KERNEL__

# define EXT4_BLOCK_SIZE(s)		((s)->s_blocksize)
#else

# define EXT4_BLOCK_SIZE(s)		(EXT4_MIN_BLOCK_SIZE << (s)->s_log_block_size)
#endif

#define	EXT4_ADDR_PER_BLOCK(s)		(EXT4_BLOCK_SIZE(s) / sizeof(__u32))

#define EXT4_CLUSTER_SIZE(s)		(EXT4_BLOCK_SIZE(s) << \
                                         EXT4_SB(s)->s_cluster_bits)
#ifdef __KERNEL__

# define EXT4_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)

# define EXT4_CLUSTER_BITS(s)		(EXT4_SB(s)->s_cluster_bits)
#else

# define EXT4_BLOCK_SIZE_BITS(s)	((s)->s_log_block_size + 10)
#endif
#ifdef __KERNEL__

#define	EXT4_ADDR_PER_BLOCK_BITS(s)	(EXT4_SB(s)->s_addr_per_block_bits)

#define EXT4_INODE_SIZE(s)		(EXT4_SB(s)->s_inode_size)

#define EXT4_FIRST_INO(s)		(EXT4_SB(s)->s_first_ino)
#else

#define EXT4_INODE_SIZE(s)	(((s)->s_rev_level == EXT4_GOOD_OLD_REV) ? \
                                 EXT4_GOOD_OLD_INODE_SIZE : \
                                 (s)->s_inode_size)

#define EXT4_FIRST_INO(s)	(((s)->s_rev_level == EXT4_GOOD_OLD_REV) ? \
                                 EXT4_GOOD_OLD_FIRST_INO : \
                                 (s)->s_first_ino)
#endif

#define EXT4_BLOCK_ALIGN(size, blkbits)		ALIGN((size), (1 << (blkbits)))

#define EXT4_MAX_BLOCKS(size, offset, blkbits) \
	((EXT4_BLOCK_ALIGN(size + offset, blkbits) >> blkbits) - (offset >> \
                                                                  blkbits))

/* Translate a block number to a cluster number */

#define EXT4_B2C(sbi, blk)	((blk) >> (sbi)->s_cluster_bits)
/* Translate a cluster number to a block number */

#define EXT4_C2B(sbi, cluster)	((cluster) << (sbi)->s_cluster_bits)
/* Translate # of blks to # of clusters */

#define EXT4_NUM_B2C(sbi, blks)	(((blks) + (sbi)->s_cluster_ratio - 1) >> \
                                 (sbi)->s_cluster_bits)
/* Mask out the low bits to get the starting block of the cluster */

#define EXT4_PBLK_CMASK(s, pblk) ((pblk) &                               \
                                  ~((ext4_fsblk_t) (s)->s_cluster_ratio - 1))

#define EXT4_LBLK_CMASK(s, lblk) ((lblk) &                               \
                                  ~((ext4_lblk_t) (s)->s_cluster_ratio - 1))
/* Get the cluster offset */

#define EXT4_PBLK_COFF(s, pblk) ((pblk) &                               \
                                 ((ext4_fsblk_t) (s)->s_cluster_ratio - 1))

#define EXT4_LBLK_COFF(s, lblk) ((lblk) &                               \
                                 ((ext4_lblk_t) (s)->s_cluster_ratio - 1))

/*
 * Structure of a blocks group descriptor
 */

struct ext4_group_desc
{
	
__le32	bg_block_bitmap_lo;	/* Blocks bitmap block */
	
__le32	bg_inode_bitmap_lo;	/* Inodes bitmap block */
	
__le32	bg_inode_table_lo;	/* Inodes table block */
	
__le16	bg_free_blocks_count_lo;/* Free blocks count */
	
__le16	bg_free_inodes_count_lo;/* Free inodes count */
	
__le16	bg_used_dirs_count_lo;	/* Directories count */
	
__le16	bg_flags;		/* EXT4_BG_flags (INODE_UNINIT, etc) */
	
__le32  bg_exclude_bitmap_lo;   /* Exclude bitmap for snapshots */
	
__le16  bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bbitmap) LE */
	
__le16  bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+ibitmap) LE */
	
__le16  bg_itable_unused_lo;	/* Unused inodes count */
	
__le16  bg_checksum;		/* crc16(sb_uuid+group+desc) */
	
__le32	bg_block_bitmap_hi;	/* Blocks bitmap block MSB */
	
__le32	bg_inode_bitmap_hi;	/* Inodes bitmap block MSB */
	
__le32	bg_inode_table_hi;	/* Inodes table block MSB */
	
__le16	bg_free_blocks_count_hi;/* Free blocks count MSB */
	
__le16	bg_free_inodes_count_hi;/* Free inodes count MSB */
	
__le16	bg_used_dirs_count_hi;	/* Directories count MSB */
	
__le16  bg_itable_unused_hi;    /* Unused inodes count MSB */
	
__le32  bg_exclude_bitmap_hi;   /* Exclude bitmap block MSB */
	
__le16  bg_block_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bbitmap) BE */
	
__le16  bg_inode_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+ibitmap) BE */
	
__u32   bg_reserved;
};


#define EXT4_BG_INODE_BITMAP_CSUM_HI_END	\
	(offsetof(struct ext4_group_desc, bg_inode_bitmap_csum_hi) + \
         sizeof(__le16))

#define EXT4_BG_BLOCK_BITMAP_CSUM_HI_END	\
	(offsetof(struct ext4_group_desc, bg_block_bitmap_csum_hi) + \
         sizeof(__le16))

/*
 * Structure of a flex block group info
 */


struct flex_groups {
	
atomic64_t	free_clusters;
	
atomic_t	free_inodes;
	
atomic_t	used_dirs;
};


#define EXT4_BG_INODE_UNINIT	0x0001 
/* Inode table/bitmap not in use */

#define EXT4_BG_BLOCK_UNINIT	0x0002 
/* Block bitmap not in use */

#define EXT4_BG_INODE_ZEROED	0x0004 
/* On-disk itable initialized to zero */

/*
 * Macro-instructions used to manage group descriptors
 */

#define EXT4_MIN_DESC_SIZE		32

#define EXT4_MIN_DESC_SIZE_64BIT	64

#define	EXT4_MAX_DESC_SIZE		EXT4_MIN_BLOCK_SIZE

#define EXT4_DESC_SIZE(s)		(EXT4_SB(s)->s_desc_size)
#ifdef __KERNEL__

# define EXT4_BLOCKS_PER_GROUP(s)	(EXT4_SB(s)->s_blocks_per_group)

# define EXT4_CLUSTERS_PER_GROUP(s)	(EXT4_SB(s)->s_clusters_per_group)

# define EXT4_DESC_PER_BLOCK(s)		(EXT4_SB(s)->s_desc_per_block)

# define EXT4_INODES_PER_GROUP(s)	(EXT4_SB(s)->s_inodes_per_group)

# define EXT4_DESC_PER_BLOCK_BITS(s)	(EXT4_SB(s)->s_desc_per_block_bits)
#else

# define EXT4_BLOCKS_PER_GROUP(s)	((s)->s_blocks_per_group)

# define EXT4_DESC_PER_BLOCK(s)		(EXT4_BLOCK_SIZE(s) / EXT4_DESC_SIZE(s))

# define EXT4_INODES_PER_GROUP(s)	((s)->s_inodes_per_group)
#endif

/*
 * Constants relative to the data blocks
 */

#define	EXT4_NDIR_BLOCKS		12

#define	EXT4_IND_BLOCK			EXT4_NDIR_BLOCKS

#define	EXT4_DIND_BLOCK			(EXT4_IND_BLOCK + 1)

#define	EXT4_TIND_BLOCK			(EXT4_DIND_BLOCK + 1)

#define	EXT4_N_BLOCKS			(EXT4_TIND_BLOCK + 1)

/*
 * Inode flags
 */

#define	EXT4_SECRM_FL			0x00000001 
/* Secure deletion */

#define	EXT4_UNRM_FL			0x00000002 
/* Undelete */

#define	EXT4_COMPR_FL			0x00000004 
/* Compress file */

#define EXT4_SYNC_FL			0x00000008 
/* Synchronous updates */

#define EXT4_IMMUTABLE_FL		0x00000010 
/* Immutable file */

#define EXT4_APPEND_FL			0x00000020 
/* writes to file may only append */

#define EXT4_NODUMP_FL			0x00000040 
/* do not dump file */

#define EXT4_NOATIME_FL			0x00000080 
/* do not update atime */
/* Reserved for compression usage... */

#define EXT4_DIRTY_FL			0x00000100

#define EXT4_COMPRBLK_FL		0x00000200 
/* One or more compressed clusters */

#define EXT4_NOCOMPR_FL			0x00000400 
/* Don't compress */
	/* nb: was previously EXT2_ECOMPR_FL */

#define EXT4_ENCRYPT_FL			0x00000800 
/* encrypted file */
/* End compression flags --- maybe not all used */

#define EXT4_INDEX_FL			0x00001000 
/* hash-indexed directory */

#define EXT4_IMAGIC_FL			0x00002000 
/* AFS directory */

#define EXT4_JOURNAL_DATA_FL		0x00004000 
/* file data should be journaled */

#define EXT4_NOTAIL_FL			0x00008000 
/* file tail should not be merged */

#define EXT4_DIRSYNC_FL			0x00010000 
/* dirsync behaviour (directories only) */

#define EXT4_TOPDIR_FL			0x00020000 
/* Top of directory hierarchies*/

#define EXT4_HUGE_FILE_FL               0x00040000 
/* Set to each huge file */

#define EXT4_EXTENTS_FL			0x00080000 
/* Inode uses extents */

#define EXT4_EA_INODE_FL	        0x00200000 
/* Inode used for large EA */

#define EXT4_EOFBLOCKS_FL		0x00400000 
/* Blocks allocated beyond EOF */

#define EXT4_INLINE_DATA_FL		0x10000000 
/* Inode has inline data. */

#define EXT4_PROJINHERIT_FL		0x20000000 
/* Create with parents projid */

#define EXT4_RESERVED_FL		0x80000000 
/* reserved for ext4 lib */


#define EXT4_FL_USER_VISIBLE		0x304BDFFF 
/* User visible flags */

#define EXT4_FL_USER_MODIFIABLE		0x204BC0FF 
/* User modifiable flags */

/* Flags we can manipulate with through EXT4_IOC_FSSETXATTR */

#define EXT4_FL_XFLAG_VISIBLE		(EXT4_SYNC_FL | \
                                         EXT4_IMMUTABLE_FL | \
                                         EXT4_APPEND_FL | \
                                         EXT4_NODUMP_FL | \
                                         EXT4_NOATIME_FL | \
                                         EXT4_PROJINHERIT_FL)

/* Flags that should be inherited by new inodes from their parent. */

#define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
                           EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
                           EXT4_NOCOMPR_FL | EXT4_JOURNAL_DATA_FL |\
                           EXT4_NOTAIL_FL | EXT4_DIRSYNC_FL |\
                           EXT4_PROJINHERIT_FL)

/* Flags that are appropriate for regular files (all but dir-specific ones). */

#define EXT4_REG_FLMASK (~(EXT4_DIRSYNC_FL | EXT4_TOPDIR_FL))

/* Flags that are appropriate for non-directories/regular files. */

#define EXT4_OTHER_FLMASK (EXT4_NODUMP_FL | EXT4_NOATIME_FL)

/* Mask out flags that are inappropriate for the given type of inode. */

static inline __u32 ext4_mask_flags(umode_t mode, __u32 flags) { if (S_ISDIR(mode)) return flags; else if (S_ISREG(mode)) return flags & EXT4_REG_FLMASK; else return flags & EXT4_OTHER_FLMASK; }

Contributors

PersonTokensPropCommitsCommitProp
duane griffinduane griffin42100.00%1100.00%
Total42100.00%1100.00%

/* * Inode flags used for atomic set/get */ enum { EXT4_INODE_SECRM = 0, /* Secure deletion */ EXT4_INODE_UNRM = 1, /* Undelete */ EXT4_INODE_COMPR = 2, /* Compress file */ EXT4_INODE_SYNC = 3, /* Synchronous updates */ EXT4_INODE_IMMUTABLE = 4, /* Immutable file */ EXT4_INODE_APPEND = 5, /* writes to file may only append */ EXT4_INODE_NODUMP = 6, /* do not dump file */ EXT4_INODE_NOATIME = 7, /* do not update atime */ /* Reserved for compression usage... */ EXT4_INODE_DIRTY = 8, EXT4_INODE_COMPRBLK = 9, /* One or more compressed clusters */ EXT4_INODE_NOCOMPR = 10, /* Don't compress */ EXT4_INODE_ENCRYPT = 11, /* Encrypted file */ /* End compression flags --- maybe not all used */ EXT4_INODE_INDEX = 12, /* hash-indexed directory */ EXT4_INODE_IMAGIC = 13, /* AFS directory */ EXT4_INODE_JOURNAL_DATA = 14, /* file data should be journaled */ EXT4_INODE_NOTAIL = 15, /* file tail should not be merged */ EXT4_INODE_DIRSYNC = 16, /* dirsync behaviour (directories only) */ EXT4_INODE_TOPDIR = 17, /* Top of directory hierarchies*/ EXT4_INODE_HUGE_FILE = 18, /* Set to each huge file */ EXT4_INODE_EXTENTS = 19, /* Inode uses extents */ EXT4_INODE_EA_INODE = 21, /* Inode used for large EA */ EXT4_INODE_EOFBLOCKS = 22, /* Blocks allocated beyond EOF */ EXT4_INODE_INLINE_DATA = 28, /* Data in inode. */ EXT4_INODE_PROJINHERIT = 29, /* Create with parents projid */ EXT4_INODE_RESERVED = 31, /* reserved for ext4 lib */ }; /* * Since it's pretty easy to mix up bit numbers and hex values, we use a * build-time check to make sure that EXT4_XXX_FL is consistent with respect to * EXT4_INODE_XXX. If all is well, the macros will be dropped, so, it won't cost * any extra space in the compiled kernel image, otherwise, the build will fail. * It's important that these values are the same, since we are using * EXT4_INODE_XXX to test for flag values, but EXT4_XXX_FL must be consistent * with the values of FS_XXX_FL defined in include/linux/fs.h and the on-disk * values found in ext2, ext3 and ext4 filesystems, and of course the values * defined in e2fsprogs. * * It's not paranoia if the Murphy's Law really *is* out to get you. :-) */ #define TEST_FLAG_VALUE(FLAG) (EXT4_##FLAG##_FL == (1 << EXT4_INODE_##FLAG)) #define CHECK_FLAG_VALUE(FLAG) BUILD_BUG_ON(!TEST_FLAG_VALUE(FLAG))
static inline void ext4_check_flag_values(void) { CHECK_FLAG_VALUE(SECRM); CHECK_FLAG_VALUE(UNRM); CHECK_FLAG_VALUE(COMPR); CHECK_FLAG_VALUE(SYNC); CHECK_FLAG_VALUE(IMMUTABLE); CHECK_FLAG_VALUE(APPEND); CHECK_FLAG_VALUE(NODUMP); CHECK_FLAG_VALUE(NOATIME); CHECK_FLAG_VALUE(DIRTY); CHECK_FLAG_VALUE(COMPRBLK); CHECK_FLAG_VALUE(NOCOMPR); CHECK_FLAG_VALUE(ENCRYPT); CHECK_FLAG_VALUE(INDEX); CHECK_FLAG_VALUE(IMAGIC); CHECK_FLAG_VALUE(JOURNAL_DATA); CHECK_FLAG_VALUE(NOTAIL); CHECK_FLAG_VALUE(DIRSYNC); CHECK_FLAG_VALUE(TOPDIR); CHECK_FLAG_VALUE(HUGE_FILE); CHECK_FLAG_VALUE(EXTENTS); CHECK_FLAG_VALUE(EA_INODE); CHECK_FLAG_VALUE(EOFBLOCKS); CHECK_FLAG_VALUE(INLINE_DATA); CHECK_FLAG_VALUE(PROJINHERIT); CHECK_FLAG_VALUE(RESERVED); }

Contributors

PersonTokensPropCommitsCommitProp
dmitriy monakhovdmitriy monakhov12391.79%125.00%
theodore tsotheodore tso64.48%250.00%
tao matao ma53.73%125.00%
Total134100.00%4100.00%

/* Used to pass group descriptor data when online resize is done */ struct ext4_new_group_input { __u32 group; /* Group number for this data */ __u64 block_bitmap; /* Absolute block number of block bitmap */ __u64 inode_bitmap; /* Absolute block number of inode bitmap */ __u64 inode_table; /* Absolute block number of inode table start */ __u32 blocks_count; /* Total number of blocks in this group */ __u16 reserved_blocks; /* Number of reserved blocks in this group */ __u16 unused; }; #if defined(__KERNEL__) && defined(CONFIG_COMPAT) struct compat_ext4_new_group_input { u32 group; compat_u64 block_bitmap; compat_u64 inode_bitmap; compat_u64 inode_table; u32 blocks_count; u16 reserved_blocks; u16 unused; }; #endif /* The struct ext4_new_group_input in kernel space, with free_blocks_count */ struct ext4_new_group_data { __u32 group; __u64 block_bitmap; __u64 inode_bitmap; __u64 inode_table; __u32 blocks_count; __u16 reserved_blocks; __u16 unused; __u32 free_blocks_count; }; /* Indexes used to index group tables in ext4_new_group_data */ enum { BLOCK_BITMAP = 0, /* block bitmap */ INODE_BITMAP, /* inode bitmap */ INODE_TABLE, /* inode tables */ GROUP_TABLE_COUNT, }; /* * Flags used by ext4_map_blocks() */ /* Allocate any needed blocks and/or convert an unwritten extent to be an initialized ext4 */ #define EXT4_GET_BLOCKS_CREATE 0x0001 /* Request the creation of an unwritten extent */ #define EXT4_GET_BLOCKS_UNWRIT_EXT 0x0002 #define EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT (EXT4_GET_BLOCKS_UNWRIT_EXT|\ EXT4_GET_BLOCKS_CREATE) /* Caller is from the delayed allocation writeout path * finally doing the actual allocation of delayed blocks */ #define EXT4_GET_BLOCKS_DELALLOC_RESERVE 0x0004 /* caller is from the direct IO path, request to creation of an unwritten extents if not allocated, split the unwritten extent if blocks has been preallocated already*/ #define EXT4_GET_BLOCKS_PRE_IO 0x0008 #define EXT4_GET_BLOCKS_CONVERT 0x0010 #define EXT4_GET_BLOCKS_IO_CREATE_EXT (EXT4_GET_BLOCKS_PRE_IO|\ EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT) /* Convert extent to initialized after IO complete */ #define EXT4_GET_BLOCKS_IO_CONVERT_EXT (EXT4_GET_BLOCKS_CONVERT|\ EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT) /* Eventual metadata allocation (due to growing extent tree) * should not fail, so try to use reserved blocks for that.*/ #define EXT4_GET_BLOCKS_METADATA_NOFAIL 0x0020 /* Don't normalize allocation size (used for fallocate) */ #define EXT4_GET_BLOCKS_NO_NORMALIZE 0x0040 /* Request will not result in inode size update (user for fallocate) */ #define EXT4_GET_BLOCKS_KEEP_SIZE 0x0080 /* Convert written extents to unwritten */ #define EXT4_GET_BLOCKS_CONVERT_UNWRITTEN 0x0100 /* Write zeros to newly created written extents */ #define EXT4_GET_BLOCKS_ZERO 0x0200 #define EXT4_GET_BLOCKS_CREATE_ZERO (EXT4_GET_BLOCKS_CREATE |\ EXT4_GET_BLOCKS_ZERO) /* Caller will submit data before dropping transaction handle. This * allows jbd2 to avoid submitting data before commit. */ #define EXT4_GET_BLOCKS_IO_SUBMIT 0x0400 /* * The bit position of these flags must not overlap with any of the * EXT4_GET_BLOCKS_*. They are used by ext4_find_extent(), * read_extent_tree_block(), ext4_split_extent_at(), * ext4_ext_insert_extent(), and ext4_ext_create_new_leaf(). * EXT4_EX_NOCACHE is used to indicate that the we shouldn't be * caching the extents when reading from the extent tree while a * truncate or punch hole operation is in progress. */ #define EXT4_EX_NOCACHE 0x40000000 #define EXT4_EX_FORCE_CACHE 0x20000000 /* * Flags used by ext4_free_blocks */ #define EXT4_FREE_BLOCKS_METADATA 0x0001 #define EXT4_FREE_BLOCKS_FORGET 0x0002 #define EXT4_FREE_BLOCKS_VALIDATED 0x0004 #define EXT4_FREE_BLOCKS_NO_QUOT_UPDATE 0x0008 #define EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER 0x0010 #define EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER 0x0020 /* * ioctl commands */ #define EXT4_IOC_GETFLAGS FS_IOC_GETFLAGS #define EXT4_IOC_SETFLAGS FS_IOC_SETFLAGS #define EXT4_IOC_GETVERSION _IOR('f', 3, long) #define EXT4_IOC_SETVERSION _IOW('f', 4, long) #define EXT4_IOC_GETVERSION_OLD FS_IOC_GETVERSION #define EXT4_IOC_SETVERSION_OLD FS_IOC_SETVERSION #define EXT4_IOC_GETRSVSZ _IOR('f', 5, long) #define EXT4_IOC_SETRSVSZ _IOW('f', 6, long) #define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) #define EXT4_IOC_GROUP_ADD _IOW('f', 8, struct ext4_new_group_input) #define EXT4_IOC_MIGRATE _IO('f', 9) /* note ioctl 10 reserved for an early version of the FIEMAP ioctl */ /* note ioctl 11 reserved for filesystem-independent FIEMAP ioctl */ #define EXT4_IOC_ALLOC_DA_BLKS _IO('f', 12) #define EXT4_IOC_MOVE_EXT _IOWR('f', 15, struct move_extent) #define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64) #define EXT4_IOC_SWAP_BOOT _IO('f', 17) #define EXT4_IOC_PRECACHE_EXTENTS _IO('f', 18) #define EXT4_IOC_SET_ENCRYPTION_POLICY FS_IOC_SET_ENCRYPTION_POLICY #define EXT4_IOC_GET_ENCRYPTION_PWSALT FS_IOC_GET_ENCRYPTION_PWSALT #define EXT4_IOC_GET_ENCRYPTION_POLICY FS_IOC_GET_ENCRYPTION_POLICY #ifndef FS_IOC_FSGETXATTR /* Until the uapi changes get merged for project quota... */ #define FS_IOC_FSGETXATTR _IOR('X', 31, struct fsxattr) #define FS_IOC_FSSETXATTR _IOW('X', 32, struct fsxattr) /* * Structure for FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR. */ struct fsxattr { __u32 fsx_xflags; /* xflags field value (get/set) */ __u32 fsx_extsize; /* extsize field value (get/set)*/ __u32 fsx_nextents; /* nextents field value (get) */ __u32 fsx_projid; /* project identifier (get/set) */ unsigned char fsx_pad[12]; }; /* * Flags for the fsx_xflags field */ #define FS_XFLAG_REALTIME 0x00000001 /* data in realtime volume */ #define FS_XFLAG_PREALLOC 0x00000002 /* preallocated file extents */ #define FS_XFLAG_IMMUTABLE 0x00000008 /* file cannot be modified */ #define FS_XFLAG_APPEND 0x00000010 /* all writes append */ #define FS_XFLAG_SYNC 0x00000020 /* all writes synchronous */ #define FS_XFLAG_NOATIME 0x00000040 /* do not update access time */ #define FS_XFLAG_NODUMP 0x00000080 /* do not include in backups */ #define FS_XFLAG_RTINHERIT 0x00000100 /* create with rt bit set */ #define FS_XFLAG_PROJINHERIT 0x00000200 /* create with parents projid */ #define FS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */ #define FS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */ #define FS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ #define FS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */ #define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */ #define FS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ #endif /* !defined(FS_IOC_FSGETXATTR) */ #define EXT4_IOC_FSGETXATTR FS_IOC_FSGETXATTR #define EXT4_IOC_FSSETXATTR FS_IOC_FSSETXATTR #if defined(__KERNEL__) && defined(CONFIG_COMPAT) /* * ioctl commands in 32 bit emulation */ #define EXT4_IOC32_GETFLAGS FS_IOC32_GETFLAGS #define EXT4_IOC32_SETFLAGS FS_IOC32_SETFLAGS #define EXT4_IOC32_GETVERSION _IOR('f', 3, int) #define EXT4_IOC32_SETVERSION _IOW('f', 4, int) #define EXT4_IOC32_GETRSVSZ _IOR('f', 5, int) #define EXT4_IOC32_SETRSVSZ _IOW('f', 6, int) #define EXT4_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) #define EXT4_IOC32_GROUP_ADD _IOW('f', 8, struct compat_ext4_new_group_input) #define EXT4_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION #define EXT4_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION #endif /* Max physical block we can address w/o extents */ #define EXT4_MAX_BLOCK_FILE_PHYS 0xFFFFFFFF /* * Structure of an inode on the disk */ struct ext4_inode { __le16 i_mode; /* File mode */ __le16 i_uid; /* Low 16 bits of Owner Uid */ __le32 i_size_lo; /* Size in bytes */ __le32 i_atime; /* Access time */ __le32 i_ctime; /* Inode Change time */ __le32 i_mtime; /* Modification time */ __le32 i_dtime; /* Deletion Time */ __le16 i_gid; /* Low 16 bits of Group Id */ __le16 i_links_count; /* Links count */ __le32 i_blocks_lo; /* Blocks count */ __le32 i_flags; /* File flags */ union { struct { __le32 l_i_version; } linux1; struct { __u32 h_i_translator; } hurd1; struct { __u32 m_i_reserved1; } masix1; } osd1; /* OS dependent 1 */ __le32 i_block[EXT4_N_BLOCKS];/* Pointers to blocks */ __le32 i_generation; /* File version (for NFS) */ __le32 i_file_acl_lo; /* File ACL */ __le32 i_size_high; __le32 i_obso_faddr; /* Obsoleted fragment address */ union { struct { __le16 l_i_blocks_high; /* were l_i_reserved1 */ __le16 l_i_file_acl_high; __le16 l_i_uid_high; /* these 2 fields */ __le16 l_i_gid_high; /* were reserved2[0] */ __le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */ __le16 l_i_reserved; } linux2; struct { __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ __u16 h_i_mode_high; __u16 h_i_uid_high; __u16 h_i_gid_high; __u32 h_i_author; } hurd2; struct { __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ __le16 m_i_file_acl_high; __u32 m_i_reserved2[2]; } masix2; } osd2; /* OS dependent 2 */ __le16 i_extra_isize; __le16 i_checksum_hi; /* crc32c(uuid+inum+inode) BE */ __le32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */ __le32 i_mtime_extra; /* extra Modification time(nsec << 2 | epoch) */ __le32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */ __le32 i_crtime; /* File Creation time */ __le32 i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */ __le32 i_version_hi; /* high 32 bits for 64-bit version */ __le32 i_projid; /* Project ID */ }; struct move_extent { __u32 reserved; /* should be zero */ __u32 donor_fd; /* donor file descriptor */ __u64 orig_start; /* logical start offset in block for orig */ __u64 donor_start; /* logical start offset in block for donor */ __u64 len; /* block length to be moved */ __u64 moved_len; /* moved block length */ }; #define EXT4_EPOCH_BITS 2 #define EXT4_EPOCH_MASK ((1 << EXT4_EPOCH_BITS) - 1) #define EXT4_NSEC_MASK (~0UL << EXT4_EPOCH_BITS) /* * Extended fields will fit into an inode if the filesystem was formatted * with large inodes (-I 256 or larger) and there are not currently any EAs * consuming all of the available space. For new inodes we always reserve * enough space for the kernel's known extended fields, but for inodes * created with an old kernel this might not have been the case. None of * the extended inode fields is critical for correct filesystem operation. * This macro checks if a certain field fits in the inode. Note that * inode-size = GOOD_OLD_INODE_SIZE + i_extra_isize */ #define EXT4_FITS_IN_INODE(ext4_inode, einode, field) \ ((offsetof(typeof(*ext4_inode), field) + \ sizeof((ext4_inode)->field)) \ <= (EXT4_GOOD_OLD_INODE_SIZE + \ (einode)->i_extra_isize)) \ /* * We use an encoding that preserves the times for extra epoch "00": * * extra msb of adjust for signed * epoch 32-bit 32-bit tv_sec to * bits time decoded 64-bit tv_sec 64-bit tv_sec valid time range * 0 0 1 -0x80000000..-0x00000001 0x000000000 1901-12-13..1969-12-31 * 0 0 0 0x000000000..0x07fffffff 0x000000000 1970-01-01..2038-01-19 * 0 1 1 0x080000000..0x0ffffffff 0x100000000 2038-01-19..2106-02-07 * 0 1 0 0x100000000..0x17fffffff 0x100000000 2106-02-07..2174-02-25 * 1 0 1 0x180000000..0x1ffffffff 0x200000000 2174-02-25..2242-03-16 * 1 0 0 0x200000000..0x27fffffff 0x200000000 2242-03-16..2310-04-04 * 1 1 1 0x280000000..0x2ffffffff 0x300000000 2310-04-04..2378-04-22 * 1 1 0 0x300000000..0x37fffffff 0x300000000 2378-04-22..2446-05-10 * * Note that previous versions of the kernel on 64-bit systems would * incorrectly use extra epoch bits 1,1 for dates between 1901 and * 1970. e2fsck will correct this, assuming that it is run on the * affected filesystem before 2242. */
static inline __le32 ext4_encode_extra_time(struct timespec *time) { u32 extra = sizeof(time->tv_sec) > 4 ? ((time->tv_sec - (s32)time->tv_sec) >> 32) & EXT4_EPOCH_MASK : 0; return cpu_to_le32(extra | (time->tv_nsec << EXT4_EPOCH_BITS)); }

Contributors

PersonTokensPropCommitsCommitProp
kalpak shahkalpak shah2745.76%133.33%
david turnerdavid turner2745.76%133.33%
theodore tsotheodore tso58.47%133.33%
Total59100.00%3100.00%


static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra) { if (unlikely(sizeof(time->tv_sec) > 4 && (extra & cpu_to_le32(EXT4_EPOCH_MASK)))) { #if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0) /* Handle legacy encoding of pre-1970 dates with epoch * bits 1,1. We assume that by kernel version 4.20, * everyone will have run fsck over the affected * filesystems to correct the problem. (This * backwards compatibility may be removed before this * time, at the discretion of the ext4 developers.) */ u64 extra_bits = le32_to_cpu(extra) & EXT4_EPOCH_MASK; if (extra_bits == 3 && ((time->tv_sec) & 0x80000000) != 0) extra_bits = 0; time->tv_sec += extra_bits << 32; #else time->tv_sec += (u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK) << 32; #endif } time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS; }

Contributors

PersonTokensPropCommitsCommitProp
david turnerdavid turner7356.15%133.33%
kalpak shahkalpak shah5643.08%133.33%
theodore tsotheodore tso10.77%133.33%
Total130100.00%3100.00%

#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \ do { \ (raw_inode)->xtime = cpu_to_le32((inode)->xtime.tv_sec); \ if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra)) \ (raw_inode)->xtime ## _extra = \ ext4_encode_extra_time(&(inode)->xtime); \ } while (0) #define EXT4_EINODE_SET_XTIME(xtime, einode, raw_inode) \ do { \ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime)) \ (raw_inode)->xtime = cpu_to_le32((einode)->xtime.tv_sec); \ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \ (raw_inode)->xtime ## _extra = \ ext4_encode_extra_time(&(einode)->xtime); \ } while (0) #define EXT4_INODE_GET_XTIME(xtime, inode, raw_inode) \ do { \ (inode)->xtime.tv_sec = (signed)le32_to_cpu((raw_inode)->xtime); \ if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra)) \ ext4_decode_extra_time(&(inode)->xtime, \ raw_inode->xtime ## _extra); \ else \ (inode)->xtime.tv_nsec = 0; \ } while (0) #define EXT4_EINODE_GET_XTIME(xtime, einode, raw_inode) \ do { \ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime)) \ (einode)->xtime.tv_sec = \ (signed)le32_to_cpu((raw_inode)->xtime); \ else \ (einode)->xtime.tv_sec = 0; \ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \ ext4_decode_extra_time(&(einode)->xtime, \ raw_inode->xtime ## _extra); \ else \ (einode)->xtime.tv_nsec = 0; \ } while (0) #define i_disk_version osd1.linux1.l_i_version #if defined(__KERNEL__) || defined(__linux__) #define i_reserved1 osd1.linux1.l_i_reserved1 #define i_file_acl_high osd2.linux2.l_i_file_acl_high #define i_blocks_high osd2.linux2.l_i_blocks_high #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_checksum_lo osd2.linux2.l_i_checksum_lo #elif defined(__GNU__) #define i_translator osd1.hurd1.h_i_translator #define i_uid_high osd2.hurd2.h_i_uid_high #define i_gid_high osd2.hurd2.h_i_gid_high #define i_author osd2.hurd2.h_i_author #elif defined(__masix__) #define i_reserved1 osd1.masix1.m_i_reserved1 #define i_file_acl_high osd2.masix2.m_i_file_acl_high #define i_reserved2 osd2.masix2.m_i_reserved2 #endif /* defined(__KERNEL__) || defined(__linux__) */ #include "extents_status.h" /* * Lock subclasses for i_data_sem in the ext4_inode_info structure. * * These are needed to avoid lockdep false positives when we need to * allocate blocks to the quota inode during ext4_map_blocks(), while * holding i_data_sem for a normal (non-quota) inode. Since we don't * do quota tracking for the quota inode, this avoids deadlock (as * well as infinite recursion, since it isn't turtles all the way * down...) * * I_DATA_SEM_NORMAL - Used for most inodes * I_DATA_SEM_OTHER - Used by move_inode.c for the second normal inode * where the second inode has larger inode number * than the first * I_DATA_SEM_QUOTA - Used for quota inodes only */ enum { I_DATA_SEM_NORMAL = 0, I_DATA_SEM_OTHER, I_DATA_SEM_QUOTA, }; /* * fourth extended file system inode data in memory */ struct ext4_inode_info { __le32 i_data[15]; /* unconverted */ __u32 i_dtime; ext4_fsblk_t i_file_acl; /* * i_block_group is the number of the block group which contains * this file's inode. Constant across the lifetime of the inode, * it is ued for making block allocation decisions - we try to * place a file's data blocks near its inode block, and new inodes * near to their parent directory's inode. */ ext4_group_t i_block_group; ext4_lblk_t i_dir_start_lookup; #if (BITS_PER_LONG < 64) unsigned long i_state_flags; /* Dynamic state flags */ #endif unsigned long i_flags; /* * Extended attributes can be read independently of the main file * data. Taking i_mutex even when reading would cause contention * between readers of EAs and writers of regular file data, so * instead we synchronize on xattr_sem when reading or changing * EAs. */ struct rw_semaphore xattr_sem; struct list_head