diff options
Diffstat (limited to 'include')
29 files changed, 589 insertions, 171 deletions
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h index 47a6b086eee2..5c60bfc1a84d 100644 --- a/include/asm-arm/bitops.h +++ b/include/asm-arm/bitops.h @@ -310,6 +310,8 @@ static inline int constant_fls(int x) _find_first_zero_bit_le(p,sz) #define ext2_find_next_zero_bit(p,sz,off) \ _find_next_zero_bit_le(p,sz,off) +#define ext2_find_next_bit(p, sz, off) \ + _find_next_bit_le(p, sz, off) /* * Minix is defined to use little-endian byte ordering. diff --git a/include/asm-avr32/setup.h b/include/asm-avr32/setup.h index b0828d43e110..ea3070ff13a5 100644 --- a/include/asm-avr32/setup.h +++ b/include/asm-avr32/setup.h @@ -110,7 +110,7 @@ struct tagtable { int (*parse)(struct tag *); }; -#define __tag __attribute_used__ __attribute__((__section__(".taglist.init"))) +#define __tag __used __attribute__((__section__(".taglist.init"))) #define __tagtable(tag, fn) \ static struct tagtable __tagtable_##fn __tag = { tag, fn } diff --git a/include/asm-generic/bitops/ext2-non-atomic.h b/include/asm-generic/bitops/ext2-non-atomic.h index 1697404afa05..63cf822431a2 100644 --- a/include/asm-generic/bitops/ext2-non-atomic.h +++ b/include/asm-generic/bitops/ext2-non-atomic.h @@ -14,5 +14,7 @@ generic_find_first_zero_le_bit((unsigned long *)(addr), (size)) #define ext2_find_next_zero_bit(addr, size, off) \ generic_find_next_zero_le_bit((unsigned long *)(addr), (size), (off)) +#define ext2_find_next_bit(addr, size, off) \ + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) #endif /* _ASM_GENERIC_BITOPS_EXT2_NON_ATOMIC_H_ */ diff --git a/include/asm-generic/bitops/le.h b/include/asm-generic/bitops/le.h index b9c7e5d2d2ad..80e3bf13b2b9 100644 --- a/include/asm-generic/bitops/le.h +++ b/include/asm-generic/bitops/le.h @@ -20,6 +20,8 @@ #define generic___test_and_clear_le_bit(nr, addr) __test_and_clear_bit(nr, addr) #define generic_find_next_zero_le_bit(addr, size, offset) find_next_zero_bit(addr, size, offset) +#define generic_find_next_le_bit(addr, size, offset) \ + find_next_bit(addr, size, offset) #elif defined(__BIG_ENDIAN) @@ -42,6 +44,8 @@ extern unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, unsigned long size, unsigned long offset); +extern unsigned long generic_find_next_le_bit(const unsigned long *addr, + unsigned long size, unsigned long offset); #else #error "Please fix <asm/byteorder.h>" diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 9f584cc5c5fb..76df771be585 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -9,10 +9,46 @@ /* Align . to a 8 byte boundary equals to maximum function alignment. */ #define ALIGN_FUNCTION() . = ALIGN(8) +/* The actual configuration determine if the init/exit sections + * are handled as text/data or they can be discarded (which + * often happens at runtime) + */ +#ifdef CONFIG_HOTPLUG +#define DEV_KEEP(sec) *(.dev##sec) +#define DEV_DISCARD(sec) +#else +#define DEV_KEEP(sec) +#define DEV_DISCARD(sec) *(.dev##sec) +#endif + +#ifdef CONFIG_HOTPLUG_CPU +#define CPU_KEEP(sec) *(.cpu##sec) +#define CPU_DISCARD(sec) +#else +#define CPU_KEEP(sec) +#define CPU_DISCARD(sec) *(.cpu##sec) +#endif + +#if defined(CONFIG_MEMORY_HOTPLUG) +#define MEM_KEEP(sec) *(.mem##sec) +#define MEM_DISCARD(sec) +#else +#define MEM_KEEP(sec) +#define MEM_DISCARD(sec) *(.mem##sec) +#endif + + /* .data section */ #define DATA_DATA \ *(.data) \ *(.data.init.refok) \ + *(.ref.data) \ + DEV_KEEP(init.data) \ + DEV_KEEP(exit.data) \ + CPU_KEEP(init.data) \ + CPU_KEEP(exit.data) \ + MEM_KEEP(init.data) \ + MEM_KEEP(exit.data) \ . = ALIGN(8); \ VMLINUX_SYMBOL(__start___markers) = .; \ *(__markers) \ @@ -132,6 +168,17 @@ *(__ksymtab_strings) \ } \ \ + /* __*init sections */ \ + __init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) { \ + *(.ref.rodata) \ + DEV_KEEP(init.rodata) \ + DEV_KEEP(exit.rodata) \ + CPU_KEEP(init.rodata) \ + CPU_KEEP(exit.rodata) \ + MEM_KEEP(init.rodata) \ + MEM_KEEP(exit.rodata) \ + } \ + \ /* Built-in module parameters. */ \ __param : AT(ADDR(__param) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___param) = .; \ @@ -139,7 +186,6 @@ VMLINUX_SYMBOL(__stop___param) = .; \ VMLINUX_SYMBOL(__end_rodata) = .; \ } \ - \ . = ALIGN((align)); /* RODATA provided for backward compatibility. @@ -158,8 +204,16 @@ #define TEXT_TEXT \ ALIGN_FUNCTION(); \ *(.text) \ + *(.ref.text) \ *(.text.init.refok) \ - *(.exit.text.refok) + *(.exit.text.refok) \ + DEV_KEEP(init.text) \ + DEV_KEEP(exit.text) \ + CPU_KEEP(init.text) \ + CPU_KEEP(exit.text) \ + MEM_KEEP(init.text) \ + MEM_KEEP(exit.text) + /* sched.text is aling to function alignment to secure we have same * address even at second ld pass when generating System.map */ @@ -183,6 +237,37 @@ *(.kprobes.text) \ VMLINUX_SYMBOL(__kprobes_text_end) = .; +/* init and exit section handling */ +#define INIT_DATA \ + *(.init.data) \ + DEV_DISCARD(init.data) \ + DEV_DISCARD(init.rodata) \ + CPU_DISCARD(init.data) \ + CPU_DISCARD(init.rodata) \ + MEM_DISCARD(init.data) \ + MEM_DISCARD(init.rodata) + +#define INIT_TEXT \ + *(.init.text) \ + DEV_DISCARD(init.text) \ + CPU_DISCARD(init.text) \ + MEM_DISCARD(init.text) + +#define EXIT_DATA \ + *(.exit.data) \ + DEV_DISCARD(exit.data) \ + DEV_DISCARD(exit.rodata) \ + CPU_DISCARD(exit.data) \ + CPU_DISCARD(exit.rodata) \ + MEM_DISCARD(exit.data) \ + MEM_DISCARD(exit.rodata) + +#define EXIT_TEXT \ + *(.exit.text) \ + DEV_DISCARD(exit.text) \ + CPU_DISCARD(exit.text) \ + MEM_DISCARD(exit.text) + /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ diff --git a/include/asm-ia64/gcc_intrin.h b/include/asm-ia64/gcc_intrin.h index e58d3298fa10..5b6665c754c9 100644 --- a/include/asm-ia64/gcc_intrin.h +++ b/include/asm-ia64/gcc_intrin.h @@ -24,7 +24,7 @@ extern void ia64_bad_param_for_setreg (void); extern void ia64_bad_param_for_getreg (void); -register unsigned long ia64_r13 asm ("r13") __attribute_used__; +register unsigned long ia64_r13 asm ("r13") __used; #define ia64_setreg(regnum, val) \ ({ \ diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h index 2976b5d68e96..83d1f286230b 100644 --- a/include/asm-m68k/bitops.h +++ b/include/asm-m68k/bitops.h @@ -410,6 +410,8 @@ static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size, res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); return (p - addr) * 32 + res; } +#define ext2_find_next_bit(addr, size, off) \ + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) #endif /* __KERNEL__ */ diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h index f8dfb7ba2e25..f43afe1fc3b3 100644 --- a/include/asm-m68knommu/bitops.h +++ b/include/asm-m68knommu/bitops.h @@ -294,6 +294,8 @@ found_middle: return result + ffz(__swab32(tmp)); } +#define ext2_find_next_bit(addr, size, off) \ + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) #include <asm-generic/bitops/minix.h> #endif /* __KERNEL__ */ diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h index 733b4af7f4f1..220d9a781ab9 100644 --- a/include/asm-powerpc/bitops.h +++ b/include/asm-powerpc/bitops.h @@ -359,6 +359,8 @@ static __inline__ int test_le_bit(unsigned long nr, unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, unsigned long size, unsigned long offset); +unsigned long generic_find_next_le_bit(const unsigned long *addr, + unsigned long size, unsigned long offset); /* Bitmap functions for the ext2 filesystem */ #define ext2_set_bit(nr,addr) \ @@ -378,6 +380,8 @@ unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, #define ext2_find_next_zero_bit(addr, size, off) \ generic_find_next_zero_le_bit((unsigned long*)addr, size, off) +#define ext2_find_next_bit(addr, size, off) \ + generic_find_next_le_bit((unsigned long *)addr, size, off) /* Bitmap functions for the minix filesystem. */ #define minix_test_and_set_bit(nr,addr) \ diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h index 34d9a6357c38..dba6fecad0be 100644 --- a/include/asm-s390/bitops.h +++ b/include/asm-s390/bitops.h @@ -772,6 +772,8 @@ static inline int sched_find_first_bit(unsigned long *b) test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) #define ext2_test_bit(nr, addr) \ test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) +#define ext2_find_next_bit(addr, size, off) \ + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) #ifndef __s390x__ diff --git a/include/asm-sh/machvec.h b/include/asm-sh/machvec.h index ddb18ad23303..b2e4124070ae 100644 --- a/include/asm-sh/machvec.h +++ b/include/asm-sh/machvec.h @@ -65,6 +65,6 @@ extern struct sh_machine_vector sh_mv; #define get_system_type() sh_mv.mv_name #define __initmv \ - __attribute_used__ __attribute__((__section__ (".machvec.init"))) + __used __section(.machvec.init) #endif /* _ASM_SH_MACHVEC_H */ diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h index c6577d3dc46d..c50e5d35fe84 100644 --- a/include/asm-sh/thread_info.h +++ b/include/asm-sh/thread_info.h @@ -68,7 +68,7 @@ struct thread_info { #define init_stack (init_thread_union.stack) /* how to get the current stack pointer from C */ -register unsigned long current_stack_pointer asm("r15") __attribute_used__; +register unsigned long current_stack_pointer asm("r15") __used; /* how to get the thread information struct from C */ static inline struct thread_info *current_thread_info(void) diff --git a/include/asm-x86/thread_info_32.h b/include/asm-x86/thread_info_32.h index ef58fd2a6eb0..a516e9192f11 100644 --- a/include/asm-x86/thread_info_32.h +++ b/include/asm-x86/thread_info_32.h @@ -85,7 +85,7 @@ struct thread_info { /* how to get the current stack pointer from C */ -register unsigned long current_stack_pointer asm("esp") __attribute_used__; +register unsigned long current_stack_pointer asm("esp") __used; /* how to get the thread information struct from C */ static inline struct thread_info *current_thread_info(void) diff --git a/include/linux/Kbuild b/include/linux/Kbuild index bd694f779346..ad99ce9f9169 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -34,7 +34,6 @@ header-y += atmsap.h header-y += atmsvc.h header-y += atm_zatm.h header-y += auto_fs4.h -header-y += auxvec.h header-y += ax25.h header-y += b1lli.h header-y += baycom.h @@ -73,7 +72,7 @@ header-y += gen_stats.h header-y += gigaset_dev.h header-y += hdsmart.h header-y += hysdn_if.h -header-y += i2c-dev.h +header-y += i2o-dev.h header-y += i8k.h header-y += if_arcnet.h header-y += if_bonding.h @@ -158,7 +157,6 @@ header-y += veth.h header-y += video_decoder.h header-y += video_encoder.h header-y += videotext.h -header-y += vt.h header-y += x25.h unifdef-y += acct.h @@ -173,6 +171,7 @@ unifdef-y += atm.h unifdef-y += atm_tcp.h unifdef-y += audit.h unifdef-y += auto_fs.h +unifdef-y += auxvec.h unifdef-y += binfmts.h unifdef-y += capability.h unifdef-y += capi.h @@ -214,7 +213,7 @@ unifdef-y += hdreg.h unifdef-y += hiddev.h unifdef-y += hpet.h unifdef-y += i2c.h -unifdef-y += i2o-dev.h +unifdef-y += i2c-dev.h unifdef-y += icmp.h unifdef-y += icmpv6.h unifdef-y += if_addr.h @@ -349,6 +348,7 @@ unifdef-y += videodev.h unifdef-y += virtio_config.h unifdef-y += virtio_blk.h unifdef-y += virtio_net.h +unifdef-y += vt.h unifdef-y += wait.h unifdef-y += wanrouter.h unifdef-y += watchdog.h diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index da0d83fbadc0..e98801f06dcc 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -192,6 +192,8 @@ int sync_dirty_buffer(struct buffer_head *bh); int submit_bh(int, struct buffer_head *); void write_boundary_block(struct block_device *bdev, sector_t bblock, unsigned blocksize); +int bh_uptodate_or_lock(struct buffer_head *bh); +int bh_submit_read(struct buffer_head *bh); extern int buffer_heads_over_limit; diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h index 2d8c0f48f55e..e5eb795f78a1 100644 --- a/include/linux/compiler-gcc3.h +++ b/include/linux/compiler-gcc3.h @@ -7,10 +7,8 @@ #if __GNUC_MINOR__ >= 3 # define __used __attribute__((__used__)) -# define __attribute_used__ __used /* deprecated */ #else # define __used __attribute__((__unused__)) -# define __attribute_used__ __used /* deprecated */ #endif #if __GNUC_MINOR__ >= 4 diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h index ee7ca5de970c..0ab3a3232330 100644 --- a/include/linux/compiler-gcc4.h +++ b/include/linux/compiler-gcc4.h @@ -15,7 +15,6 @@ #endif #define __used __attribute__((__used__)) -#define __attribute_used__ __used /* deprecated */ #define __must_check __attribute__((warn_unused_result)) #define __compiler_offsetof(a,b) __builtin_offsetof(a,b) #define __always_inline inline __attribute__((always_inline)) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index c68b67b86ef1..d0e17e1657dc 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -126,10 +126,6 @@ extern void __chk_io_ptr(const volatile void __iomem *); * Mark functions that are referenced only in inline assembly as __used so * the code is emitted even though it appears to be unreferenced. */ -#ifndef __attribute_used__ -# define __attribute_used__ /* deprecated */ -#endif - #ifndef __used # define __used /* unimplemented */ #endif @@ -175,4 +171,9 @@ extern void __chk_io_ptr(const volatile void __iomem *); #define __cold #endif +/* Simple shorthand for a section definition */ +#ifndef __section +# define __section(S) __attribute__ ((__section__(#S))) +#endif + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/elfnote.h b/include/linux/elfnote.h index e831759b2fb5..278e3ef05336 100644 --- a/include/linux/elfnote.h +++ b/include/linux/elfnote.h @@ -76,7 +76,7 @@ typeof(desc) _desc \ __attribute__((aligned(sizeof(Elf##size##_Word)))); \ } _ELFNOTE_PASTE(_note_, unique) \ - __attribute_used__ \ + __used \ __attribute__((section(".note." name), \ aligned(sizeof(Elf##size##_Word)), \ unused)) = { \ diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h index 97dd409d5f4a..1852313fc7c7 100644 --- a/include/linux/ext4_fs.h +++ b/include/linux/ext4_fs.h @@ -20,6 +20,8 @@ #include <linux/blkdev.h> #include <linux/magic.h> +#include <linux/ext4_fs_i.h> + /* * The second extended filesystem constants/structures */ @@ -51,6 +53,50 @@ #define ext4_debug(f, a...) do {} while (0) #endif +#define EXT4_MULTIBLOCK_ALLOCATOR 1 + +/* prefer goal again. length */ +#define EXT4_MB_HINT_MERGE 1 +/* blocks already reserved */ +#define EXT4_MB_HINT_RESERVED 2 +/* metadata is being allocated */ +#define EXT4_MB_HINT_METADATA 4 +/* first blocks in the file */ +#define EXT4_MB_HINT_FIRST 8 +/* search for the best chunk */ +#define EXT4_MB_HINT_BEST 16 +/* data is being allocated */ +#define EXT4_MB_HINT_DATA 32 +/* don't preallocate (for tails) */ +#define EXT4_MB_HINT_NOPREALLOC 64 +/* allocate for locality group */ +#define EXT4_MB_HINT_GROUP_ALLOC 128 +/* allocate goal blocks or none */ +#define EXT4_MB_HINT_GOAL_ONLY 256 +/* goal is meaningful */ +#define EXT4_MB_HINT_TRY_GOAL 512 + +struct ext4_allocation_request { + /* target inode for block we're allocating */ + struct inode *inode; + /* logical block in target inode */ + ext4_lblk_t logical; + /* phys. target (a hint) */ + ext4_fsblk_t goal; + /* the closest logical allocated block to the left */ + ext4_lblk_t lleft; + /* phys. block for ^^^ */ + ext4_fsblk_t pleft; + /* the closest logical allocated block to the right */ + ext4_lblk_t lright; + /* phys. block for ^^^ */ + ext4_fsblk_t pright; + /* how many blocks we want to allocate */ + unsigned long len; + /* flags. see above EXT4_MB_HINT_* */ + unsigned long flags; +}; + /* * Special inodes numbers */ @@ -73,8 +119,8 @@ * Macro-instructions used to manage several block sizes */ #define EXT4_MIN_BLOCK_SIZE 1024 -#define EXT4_MAX_BLOCK_SIZE 4096 -#define EXT4_MIN_BLOCK_LOG_SIZE 10 +#define EXT4_MAX_BLOCK_SIZE 65536 +#define EXT4_MIN_BLOCK_LOG_SIZE 10 #ifdef __KERNEL__ # define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize) #else @@ -118,6 +164,11 @@ struct ext4_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 */ + __u32 bg_reserved2[3]; }; #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ @@ -178,8 +229,9 @@ struct ext4_group_desc #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_RESERVED_FL 0x80000000 /* reserved for ext4 lib */ +#define EXT4_HUGE_FILE_FL 0x00040000 /* Set to each huge file */ #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ +#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */ #define EXT4_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */ #define EXT4_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ @@ -237,6 +289,7 @@ struct ext4_new_group_data { #endif #define EXT4_IOC_GETRSVSZ _IOR('f', 5, long) #define EXT4_IOC_SETRSVSZ _IOW('f', 6, long) +#define EXT4_IOC_MIGRATE _IO('f', 7) /* * ioctl commands in 32 bit emulation @@ -275,18 +328,18 @@ struct ext4_mount_options { struct ext4_inode { __le16 i_mode; /* File mode */ __le16 i_uid; /* Low 16 bits of Owner Uid */ - __le32 i_size; /* Size in bytes */ + __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; /* Blocks count */ + __le32 i_blocks_lo; /* Blocks count */ __le32 i_flags; /* File flags */ union { struct { - __u32 l_i_reserved1; + __le32 l_i_version; } linux1; struct { __u32 h_i_translator; @@ -297,12 +350,12 @@ struct ext4_inode { } osd1; /* OS dependent 1 */ __le32 i_block[EXT4_N_BLOCKS];/* Pointers to blocks */ __le32 i_generation; /* File version (for NFS) */ - __le32 i_file_acl; /* File ACL */ - __le32 i_dir_acl; /* Directory ACL */ + __le32 i_file_acl_lo; /* File ACL */ + __le32 i_size_high; __le32 i_obso_faddr; /* Obsoleted fragment address */ union { struct { - __le16 l_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ + __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] */ @@ -328,9 +381,9 @@ struct ext4_inode { __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 */ }; -#define i_size_high i_dir_acl #define EXT4_EPOCH_BITS 2 #define EXT4_EPOCH_MASK ((1 << EXT4_EPOCH_BITS) - 1) @@ -402,9 +455,12 @@ do { \ raw_inode->xtime ## _extra); \ } 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 @@ -461,7 +517,10 @@ do { \ #define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ #define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ #define EXT4_MOUNT_EXTENTS 0x400000 /* Extents support */ - +#define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ +#define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ +#define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ +#define EXT4_MOUNT_MBALLOC 0x4000000 /* Buddy allocation support */ /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */ #ifndef _LINUX_EXT2_FS_H #define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt @@ -481,6 +540,7 @@ do { \ #define ext4_test_bit ext2_test_bit #define ext4_find_first_zero_bit ext2_find_first_zero_bit #define ext4_find_next_zero_bit ext2_find_next_zero_bit +#define ext4_find_next_bit ext2_find_next_bit /* * Maximal mount counts between two filesystem checks @@ -671,6 +731,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 #define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 +#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 @@ -682,6 +743,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) #define EXT4_FEATURE_INCOMPAT_META_BG 0x0010 #define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 +#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 #define EXT4_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR @@ -696,7 +758,8 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \ EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \ - EXT4_FEATURE_RO_COMPAT_BTREE_DIR) + EXT4_FEATURE_RO_COMPAT_BTREE_DIR |\ + EXT4_FEATURE_RO_COMPAT_HUGE_FILE) /* * Default values for user and/or group using reserved blocks @@ -767,6 +830,26 @@ struct ext4_dir_entry_2 { #define EXT4_DIR_ROUND (EXT4_DIR_PAD - 1) #define EXT4_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT4_DIR_ROUND) & \ ~EXT4_DIR_ROUND) +#define EXT4_MAX_REC_LEN ((1<<16)-1) + +static inline unsigned ext4_rec_len_from_disk(__le16 dlen) +{ + unsigned len = le16_to_cpu(dlen); + + if (len == EXT4_MAX_REC_LEN) + return 1 << 16; + return len; +} + +static inline __le16 ext4_rec_len_to_disk(unsigned len) +{ + if (len == (1 << 16)) + return cpu_to_le16(EXT4_MAX_REC_LEN); + else if (len > (1 << 16)) + BUG(); + return cpu_to_le16(len); +} + /* * Hash Tree Directory indexing * (c) Daniel Phillips, 2001 @@ -810,7 +893,7 @@ struct ext4_iloc { struct buffer_head *bh; unsigned long offset; - unsigned long block_group; + ext4_group_t block_group; }; static inline struct ext4_inode *ext4_raw_inode(struct ext4_iloc *iloc) @@ -835,7 +918,7 @@ struct dir_private_info { /* calculate the first block number of the group */ static inline ext4_fsblk_t -ext4_group_first_block_no(struct super_block *sb, unsigned long group_no) +ext4_group_first_block_no(struct super_block *sb, ext4_group_t group_no) { return group_no * (ext4_fsblk_t)EXT4_BLOCKS_PER_GROUP(sb) + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); @@ -866,21 +949,24 @@ extern unsigned int ext4_block_group(struct super_block *sb, ext4_fsblk_t blocknr); extern ext4_grpblk_t ext4_block_group_offset(struct super_block *sb, ext4_fsblk_t blocknr); -extern int ext4_bg_has_super(struct super_block *sb, int group); -extern unsigned long ext4_bg_num_gdb(struct super_block *sb, int group); +extern int ext4_bg_has_super(struct super_block *sb, ext4_group_t group); +extern unsigned long ext4_bg_num_gdb(struct super_block *sb, + ext4_group_t group); extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode, ext4_fsblk_t goal, int *errp); extern ext4_fsblk_t ext4_new_blocks (handle_t *handle, struct inode *inode, ext4_fsblk_t goal, unsigned long *count, int *errp); +extern ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode, + ext4_fsblk_t goal, unsigned long *count, int *errp); extern void ext4_free_blocks (handle_t *handle, struct inode *inode, - ext4_fsblk_t block, unsigned long count); + ext4_fsblk_t block, unsigned long count, int metadata); extern void ext4_free_blocks_sb (handle_t *handle, struct super_block *sb, ext4_fsblk_t block, unsigned long count, unsigned long *pdquot_freed_blocks); extern ext4_fsblk_t ext4_count_free_blocks (struct super_block *); extern void ext4_check_blocks_bitmap (struct super_block *); extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, - unsigned int block_group, + ext4_group_t block_group, struct buffer_head ** bh); extern int ext4_should_retry_alloc(struct super_block *sb, int *retries); extern void ext4_init_block_alloc_info(struct inode *); @@ -911,15 +997,32 @@ extern unsigned long ext4_count_dirs (struct super_block *); extern void ext4_check_inodes_bitmap (struct super_block *); extern unsigned long ext4_count_free (struct buffer_head *, unsigned); +/* mballoc.c */ +extern long ext4_mb_stats; +extern long ext4_mb_max_to_scan; +extern int ext4_mb_init(struct super_block *, int); +extern int ext4_mb_release(struct super_block *); +extern ext4_fsblk_t ext4_mb_new_blocks(handle_t *, + struct ext4_allocation_request *, int *); +extern int ext4_mb_reserve_blocks(struct super_block *, int); +extern void ext4_mb_discard_inode_preallocations(struct inode *); +extern int __init init_ext4_mballoc(void); +extern void exit_ext4_mballoc(void); +extern void ext4_mb_free_blocks(handle_t *, struct inode *, + unsigned long, unsigned long, int, unsigned long *); + /* inode.c */ int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, struct buffer_head *bh, ext4_fsblk_t blocknr); -struct buffer_head * ext4_getblk (handle_t *, struct inode *, long, int, int *); -struct buffer_head * ext4_bread (handle_t *, struct inode *, int, int, int *); +struct buffer_head *ext4_getblk(handle_t *, struct inode *, + ext4_lblk_t, int, int *); +struct buffer_head *ext4_bread(handle_t *, struct inode *, + ext4_lblk_t, int, int *); int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, - sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result, - int create, int extend_disksize); + ext4_lblk_t iblock, unsigned long maxblocks, + struct buffer_head *bh_result, + int create, int extend_disksize); extern void ext4_read_inode (struct inode *); extern int ext4_write_inode (struct inode *, int); @@ -943,6 +1046,9 @@ extern int ext4_ioctl (struct inode *, struct file *, unsigned int, unsigned long); extern long ext4_compat_ioctl (struct file *, unsigned int, unsigned long); +/* migrate.c */ +extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int, + unsigned long); /* namei.c */ extern int ext4_orphan_add(handle_t *, struct inode *); extern int ext4_orphan_del(handle_t *, struct inode *); @@ -965,6 +1071,12 @@ extern void ext4_abort (struct super_block *, const char *, const char *, ...) extern void ext4_warning (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4))); extern void ext4_update_dynamic_rev (struct super_block *sb); +extern int ext4_update_compat_feature(handle_t *handle, struct super_block *sb, + __u32 compat); +extern int ext4_update_rocompat_feature(handle_t *handle, + struct super_block *sb, __u32 rocompat); +extern int ext4_update_incompat_feature(handle_t *handle, + struct super_block *sb, __u32 incompat); extern ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, struct ext4_group_desc *bg); extern ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, @@ -1017,6 +1129,29 @@ static inline void ext4_r_blocks_count_set(struct ext4_super_block *es, es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32); } +static inline loff_t ext4_isize(struct ext4_inode *raw_inode) +{ + return ((loff_t)le32_to_cpu(raw_inode->i_size_high) << 32) | + le32_to_cpu(raw_inode->i_size_lo); +} + +static inline void ext4_isize_set(struct ext4_inode *raw_inode, loff_t i_size) +{ + raw_inode->i_size_lo = cpu_to_le32(i_size); + raw_inode->i_size_high = cpu_to_le32(i_size >> 32); +} + +static inline +struct ext4_group_info *ext4_get_group_info(struct super_block *sb, + ext4_group_t group) +{ + struct ext4_group_info ***grp_info; + long indexv, indexh; + grp_info = EXT4_SB(sb)->s_group_info; + indexv = group >> (EXT4_DESC_PER_BLOCK_BITS(sb)); + indexh = group & ((EXT4_DESC_PER_BLOCK(sb)) - 1); + return grp_info[indexv][indexh]; +} #define ext4_std_error(sb, errno) \ @@ -1048,7 +1183,7 @@ extern const struct inode_operations ext4_fast_symlink_inode_operations; extern int ext4_ext_tree_init(handle_t *handle, struct inode *); extern int ext4_ext_writepage_trans_blocks(struct inode *, int); extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, - ext4_fsblk_t iblock, + ext4_lblk_t iblock, unsigned long max_blocks, struct buffer_head *bh_result, int create, int extend_disksize); extern void ext4_ext_truncate(struct inode *, struct page *); @@ -1056,19 +1191,10 @@ extern void ext4_ext_init(struct super_block *); extern void ext4_ext_release(struct super_block *); extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len); -static inline int -ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, - unsigned long max_blocks, struct buffer_head *bh, - int create, int extend_disksize) -{ - if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) - return ext4_ext_get_blocks(handle, inode, block, max_blocks, - bh, create, extend_disksize); - return ext4_get_blocks_handle(handle, inode, block, max_blocks, bh, - create, extend_disksize); -} - - +extern int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, + sector_t block, unsigned long max_blocks, + struct buffer_head *bh, int create, + int extend_disksize); #endif /* __KERNEL__ */ #endif /* _LINUX_EXT4_FS_H */ diff --git a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h index d2045a26195d..697da4bce6c5 100644 --- a/include/linux/ext4_fs_extents.h +++ b/include/linux/ext4_fs_extents.h @@ -124,20 +124,6 @@ struct ext4_ext_path { #define EXT4_EXT_CACHE_GAP 1 #define EXT4_EXT_CACHE_EXTENT 2 -/* - * to be called by ext4_ext_walk_space() - * negative retcode - error - * positive retcode - signal for ext4_ext_walk_space(), see below - * callback must return valid extent (passed or newly created) - */ -typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *, - struct ext4_ext_cache *, - void *); - -#define EXT_CONTINUE 0 -#define EXT_BREAK 1 -#define EXT_REPEAT 2 - #define EXT_MAX_BLOCK 0xffffffff @@ -226,6 +212,8 @@ static inline int ext4_ext_get_actual_len(struct ext4_extent *ext) (le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN)); } +extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *); +extern void ext4_ext_store_pblock(struct ext4_extent *, ext4_fsblk_t); extern int ext4_extent_tree_init(handle_t *, struct inode *); extern int ext4_ext_calc_credits_for_insert(struct inode *, struct ext4_ext_path *); extern int ext4_ext_try_to_merge(struct inode *inode, @@ -233,8 +221,11 @@ extern int ext4_ext_try_to_merge(struct inode *inode, struct ext4_extent *); extern unsigned int ext4_ext_check_overlap(struct inode *, struct ext4_extent *, struct ext4_ext_path *); extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *); -extern int ext4_ext_walk_space(struct inode *, unsigned long, unsigned long, ext_prepare_callback, void *); -extern struct ext4_ext_path * ext4_ext_find_extent(struct inode *, int, struct ext4_ext_path *); - +extern struct ext4_ext_path *ext4_ext_find_extent(struct inode *, ext4_lblk_t, + struct ext4_ext_path *); +extern int ext4_ext_search_left(struct inode *, struct ext4_ext_path *, + ext4_lblk_t *, ext4_fsblk_t *); +extern int ext4_ext_search_right(struct inode *, struct ext4_ext_path *, + ext4_lblk_t *, ext4_fsblk_t *); #endif /* _LINUX_EXT4_EXTENTS */ diff --git a/include/linux/ext4_fs_i.h b/include/linux/ext4_fs_i.h index 86ddfe2089f3..d5508d3cf290 100644 --- a/include/linux/ext4_fs_i.h +++ b/include/linux/ext4_fs_i.h @@ -27,6 +27,12 @@ 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 long ext4_group_t; + struct ext4_reserve_window { ext4_fsblk_t _rsv_start; /* First byte reserved */ ext4_fsblk_t _rsv_end; /* Last byte reserved or 0 */ @@ -48,7 +54,7 @@ struct ext4_block_alloc_info { * most-recently-allocated block in this file. * We use this for detecting linearly ascending allocation requests. */ - __u32 last_alloc_logical_block; + ext4_lblk_t last_alloc_logical_block; /* * Was i_next_alloc_goal in ext4_inode_info * is the *physical* companion to i_next_alloc_block. @@ -67,7 +73,7 @@ struct ext4_block_alloc_info { */ struct ext4_ext_cache { ext4_fsblk_t ec_start; - __u32 ec_block; + ext4_lblk_t ec_block; __u32 ec_len; /* must be 32bit to return holes */ __u32 ec_type; }; @@ -79,7 +85,6 @@ struct ext4_inode_info { __le32 i_data[15]; /* unconverted */ __u32 i_flags; ext4_fsblk_t i_file_acl; - __u32 i_dir_acl; __u32 i_dtime; /* @@ -89,13 +94,13 @@ struct ext4_inode_info { * place a file's data blocks near its inode block, and new inodes * near to their parent directory's inode. */ - __u32 i_block_group; + ext4_group_t i_block_group; __u32 i_state; /* Dynamic state flags for ext4 */ /* block reservation info */ struct ext4_block_alloc_info *i_block_alloc_info; - __u32 i_dir_start_lookup; + ext4_lblk_t i_dir_start_lookup; #ifdef CONFIG_EXT4DEV_FS_XATTR /* * Extended attributes can be read independently of the main file @@ -134,16 +139,16 @@ struct ext4_inode_info { __u16 i_extra_isize; /* - * truncate_mutex is for serialising ext4_truncate() against + * i_data_sem is for serialising ext4_truncate() against * ext4_getblock(). In the 2.4 ext2 design, great chunks of inode's * data tree are chopped off during truncate. We can't do that in * ext4 because whenever we perform intermediate commits during * truncate, the inode and all the metadata blocks *must* be in a * consistent state which allows truncation of the orphans to restart * during recovery. Hence we must fix the get_block-vs-truncate race - * by other means, so we have truncate_mutex. + * by other means, so we have i_data_sem. */ - struct mutex truncate_mutex; + struct rw_semaphore i_data_sem; struct inode vfs_inode; unsigned long i_ext_generation; @@ -153,6 +158,10 @@ struct ext4_inode_info { * struct timespec i_{a,c,m}time in the generic inode. */ struct timespec i_crtime; + + /* mballoc */ + struct list_head i_prealloc_list; + spinlock_t i_prealloc_lock; }; #endif /* _LINUX_EXT4_FS_I */ diff --git a/include/linux/ext4_fs_sb.h b/include/linux/ext4_fs_sb.h index b40e827cd495..abaae2c8cccf 100644 --- a/include/linux/ext4_fs_sb.h +++ b/include/linux/ext4_fs_sb.h @@ -35,9 +35,10 @@ struct ext4_sb_info { unsigned long s_itb_per_group; /* Number of inode table blocks per group */ unsigned long s_gdb_count; /* Number of group descriptor blocks */ unsigned long s_desc_per_block; /* Number of group descriptors per block */ - unsigned long s_groups_count; /* Number of groups in the fs */ + ext4_group_t s_groups_count; /* Number of groups in the fs */ unsigned long s_overhead_last; /* Last calculated overhead */ unsigned long s_blocks_last; /* Last seen block count */ + loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */ struct buffer_head * s_sbh; /* Buffer containing the super block */ struct ext4_super_block * s_es; /* Pointer to the super block in the buffer */ struct buffer_head ** s_group_desc; @@ -90,6 +91,58 @@ struct ext4_sb_info { unsigned long s_ext_blocks; unsigned long s_ext_extents; #endif + + /* for buddy allocator */ + struct ext4_group_info ***s_group_info; + struct inode *s_buddy_cache; + long s_blocks_reserved; + spinlock_t s_reserve_lock; + struct list_head s_active_transaction; + struct list_head s_closed_transaction; + struct list_head s_committed_transaction; + spinlock_t s_md_lock; + tid_t s_last_transaction; + unsigned short *s_mb_offsets, *s_mb_maxs; + + /* tunables */ + unsigned long s_stripe; + unsigned long s_mb_stream_request; + unsigned long s_mb_max_to_scan; + unsigned long s_mb_min_to_scan; + unsigned long s_mb_stats; + unsigned long s_mb_order2_reqs; + unsigned long s_mb_group_prealloc; + /* where last allocation was done - for stream allocation */ + unsigned long s_mb_last_group; + unsigned long s_mb_last_start; + + /* history to debug policy */ + struct ext4_mb_history *s_mb_history; + int s_mb_history_cur; + int s_mb_history_max; + int s_mb_history_num; + struct proc_dir_entry *s_mb_proc; + spinlock_t s_mb_history_lock; + int s_mb_history_filter; + + /* stats for buddy allocator */ + spinlock_t s_mb_pa_lock; + atomic_t s_bal_reqs; /* number of reqs with len > 1 */ + atomic_t s_bal_success; /* we found long enough chunks */ + atomic_t s_bal_allocated; /* in blocks */ + atomic_t s_bal_ex_scanned; /* total extents scanned */ + atomic_t s_bal_goals; /* goal hits */ + atomic_t s_bal_breaks; /* too long searches */ + atomic_t s_bal_2orders; /* 2^order hits */ + spinlock_t s_bal_lock; + unsigned long s_mb_buddies_generated; + unsigned long long s_mb_generation_time; + atomic_t s_mb_lost_chunks; + atomic_t s_mb_preallocated; + atomic_t s_mb_discarded; + + /* locality groups */ + struct ext4_locality_group *s_locality_groups; }; #endif /* _LINUX_EXT4_FS_SB */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 21398a5d688d..a516b6716870 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -124,6 +124,7 @@ extern int dir_notify_enable; #define MS_SHARED (1<<20) /* change to shared */ #define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */ #define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ +#define MS_I_VERSION (1<<23) /* Update inode I_version field */ #define MS_ACTIVE (1<<30) #define MS_NOUSER (1<<31) @@ -173,6 +174,7 @@ extern int dir_notify_enable; ((inode)->i_flags & (S_SYNC|S_DIRSYNC))) #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK) #define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME) +#define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION) #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA) #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) @@ -599,7 +601,7 @@ struct inode { uid_t i_uid; gid_t i_gid; dev_t i_rdev; - unsigned long i_version; + u64 i_version; loff_t i_size; #ifdef __NEED_I_SIZE_ORDERED seqcount_t i_size_seqcount; @@ -1394,6 +1396,21 @@ static inline void inode_dec_link_count(struct inode *inode) mark_inode_dirty(inode); } +/** + * inode_inc_iversion - increments i_version + * @inode: inode that need to be updated + * + * Every time the inode is modified, the i_version field will be incremented. + * The filesystem has to be mounted with i_version flag + */ + +static inline void inode_inc_iversion(struct inode *inode) +{ + spin_lock(&inode->i_lock); + inode->i_version++; + spin_unlock(&inode->i_lock); +} + extern void touch_atime(struct vfsmount *mnt, struct dentry *dentry); static inline void file_accessed(struct file *file) { diff --git a/include/linux/init.h b/include/linux/init.h index 5141381a7527..2efbda016741 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -40,10 +40,10 @@ /* These are for everybody (although not all archs will actually discard it in modules) */ -#define __init __attribute__ ((__section__ (".init.text"))) __cold -#define __initdata __attribute__ ((__section__ (".init.data"))) -#define __exitdata __attribute__ ((__section__(".exit.data"))) -#define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) +#define __init __section(.init.text) __cold +#define __initdata __section(.init.data) +#define __exitdata __section(.exit.data) +#define __exit_call __used __section(.exitcall.exit) /* modpost check for section mismatches during the kernel build. * A section mismatch happens when there are references from a @@ -52,25 +52,81 @@ * when early init has completed so all such references are potential bugs. * For exit sections the same issue exists. * The following markers are used for the cases where the reference to - * the init/exit section (code or data) is valid and will teach modpost - * not to issue a warning. + * the *init / *exit section (code or data) is valid and will teach + * modpost not to issue a warning. * The markers follow same syntax rules as __init / __initdata. */ -#define __init_refok noinline __attribute__ ((__section__ (".text.init.refok"))) -#define __initdata_refok __attribute__ ((__section__ (".data.init.refok"))) -#define __exit_refok noinline __attribute__ ((__section__ (".exit.text.refok"))) +#define __ref __section(.ref.text) noinline +#define __refdata __section(.ref.data) +#define __refconst __section(.ref.rodata) + +/* backward compatibility note + * A few places hardcode the old section names: + * .text.init.refok + * .data.init.refok + * .exit.text.refok + * They should be converted to use the defines from this file + */ + +/* compatibility defines */ +#define __init_refok __ref +#define __initdata_refok __refdata +#define __exit_refok __ref + #ifdef MODULE -#define __exit __attribute__ ((__section__(".exit.text"))) __cold +#define __exitused #else -#define __exit __attribute_used__ __attribute__ ((__section__(".exit.text"))) __cold +#define __exitused __used #endif +#define __exit __section(.exit.text) __exitused __cold + +/* Used for HOTPLUG */ +#define __devinit __section(.devinit.text) __cold +#define __devinitdata __section(.devinit.data) +#define __devinitconst __section(.devinit.rodata) +#define __devexit __section(.devexit.text) __exitused __cold +#define __devexitdata __section(.devexit.data) +#define __devexitconst __section(.devexit.rodata) + +/* Used for HOTPLUG_CPU */ +#define __cpuinit __section(.cpuinit.text) __cold +#define __cpuinitdata __section(.cpuinit.data) +#define __cpuinitconst __section(.cpuinit.rodata) +#define __cpuexit __section(.cpuexit.text) __exitused __cold +#define __cpuexitdata __section(.cpuexit.data) +#define __cpuexitconst __section(.cpuexit.rodata) + +/* Used for MEMORY_HOTPLUG */ +#define __meminit __section(.meminit.text) __cold +#define __meminitdata __section(.meminit.data) +#define __meminitconst __section(.meminit.rodata) +#define __memexit __section(.memexit.text) __exitused __cold +#define __memexitdata __section(.memexit.data) +#define __memexitconst __section(.memexit.rodata) + /* For assembly routines */ #define __INIT .section ".init.text","ax" -#define __INIT_REFOK .section ".text.init.refok","ax" #define __FINIT .previous + #define __INITDATA .section ".init.data","aw" -#define __INITDATA_REFOK .section ".data.init.refok","aw" + +#define __DEVINIT .section ".devinit.text", "ax" +#define __DEVINITDATA .section ".devinit.data", "aw" + +#define __CPUINIT .section ".cpuinit.text", "ax" +#define __CPUINITDATA .section ".cpuinit.data", "aw" + +#define __MEMINIT .section ".meminit.text", "ax" +#define __MEMINITDATA .section ".meminit.data", "aw" + +/* silence warnings when references are OK */ +#define __REF .section ".ref.text", "ax" +#define __REFDATA .section ".ref.data", "aw" +#define __REFCONST .section ".ref.rodata", "aw" +/* backward compatibility */ +#define __INIT_REFOK .section __REF +#define __INITDATA_REFOK .section __REFDATA #ifndef __ASSEMBLY__ /* @@ -108,7 +164,7 @@ void prepare_namespace(void); */ #define __define_initcall(level,fn,id) \ - static initcall_t __initcall_##fn##id __attribute_used__ \ + static initcall_t __initcall_##fn##id __used \ __attribute__((__section__(".initcall" level ".init"))) = fn /* @@ -142,11 +198,11 @@ void prepare_namespace(void); #define console_initcall(fn) \ static initcall_t __initcall_##fn \ - __attribute_used__ __attribute__((__section__(".con_initcall.init")))=fn + __used __section(.con_initcall.init) = fn #define security_initcall(fn) \ static initcall_t __initcall_##fn \ - __attribute_used__ __attribute__((__section__(".security_initcall.init"))) = fn + __used __section(.security_initcall.init) = fn struct obs_kernel_param { const char *str; @@ -163,8 +219,7 @@ struct obs_kernel_param { #define __setup_param(str, unique_id, fn, early) \ static char __setup_str_##unique_id[] __initdata __aligned(1) = str; \ static struct obs_kernel_param __setup_##unique_id \ - __attribute_used__ \ - __attribute__((__section__(".init.setup"))) \ + __used __section(.init.setup) \ __attribute__((aligned((sizeof(long))))) \ = { __setup_str_##unique_id, fn, early } @@ -242,7 +297,7 @@ void __init parse_early_param(void); #endif /* Data marked not to be saved by software suspend */ -#define __nosavedata __attribute__ ((__section__ (".data.nosave"))) +#define __nosavedata __section(.data.nosave) /* This means "can be init if no module support, otherwise module load may call it." */ @@ -254,43 +309,6 @@ void __init parse_early_param(void); #define __initdata_or_module __initdata #endif /*CONFIG_MODULES*/ -#ifdef CONFIG_HOTPLUG -#define __devinit -#define __devinitdata -#define __devexit -#define __devexitdata -#else -#define __devinit __init -#define __devinitdata __initdata -#define __devexit __exit -#define __devexitdata __exitdata -#endif - -#ifdef CONFIG_HOTPLUG_CPU -#define __cpuinit -#define __cpuinitdata -#define __cpuexit -#define __cpuexitdata -#else -#define __cpuinit __init -#define __cpuinitdata __initdata -#define __cpuexit __exit -#define __cpuexitdata __exitdata -#endif - -#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \ - || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) -#define __meminit -#define __meminitdata -#define __memexit -#define __memexitdata -#else -#define __meminit __init -#define __meminitdata __initdata -#define __memexit __exit -#define __memexitdata __exitdata -#endif - /* Functions marked as __devexit may be discarded at kernel link time, depending on config options. Newer versions of binutils detect references from retained sections to discarded sections and flag an error. Pointers to diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 06ef11457051..2cbf6fdb1799 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -149,6 +149,28 @@ typedef struct journal_header_s __be32 h_sequence; } journal_header_t; +/* + * Checksum types. + */ +#define JBD2_CRC32_CHKSUM 1 +#define JBD2_MD5_CHKSUM 2 +#define JBD2_SHA1_CHKSUM 3 + +#define JBD2_CRC32_CHKSUM_SIZE 4 + +#define JBD2_CHECKSUM_BYTES (32 / sizeof(u32)) +/* + * Commit block header for storing transactional checksums: + */ +struct commit_header { + __be32 h_magic; + __be32 h_blocktype; + __be32 h_sequence; + unsigned char h_chksum_type; + unsigned char h_chksum_size; + unsigned char h_padding[2]; + __be32 h_chksum[JBD2_CHECKSUM_BYTES]; +}; /* * The block tag: used to describe a single buffer in the journal. @@ -242,31 +264,25 @@ typedef struct journal_superblock_s ((j)->j_format_version >= 2 && \ ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask)))) -#define JBD2_FEATURE_INCOMPAT_REVOKE 0x00000001 -#define JBD2_FEATURE_INCOMPAT_64BIT 0x00000002 +#define JBD2_FEATURE_COMPAT_CHECKSUM 0x00000001 + +#define JBD2_FEATURE_INCOMPAT_REVOKE 0x00000001 +#define JBD2_FEATURE_INCOMPAT_64BIT 0x00000002 +#define JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT 0x00000004 /* Features known to this kernel version: */ -#define JBD2_KNOWN_COMPAT_FEATURES 0 +#define JBD2_KNOWN_COMPAT_FEATURES JBD2_FEATURE_COMPAT_CHECKSUM #define JBD2_KNOWN_ROCOMPAT_FEATURES 0 #define JBD2_KNOWN_INCOMPAT_FEATURES (JBD2_FEATURE_INCOMPAT_REVOKE | \ - JBD2_FEATURE_INCOMPAT_64BIT) + JBD2_FEATURE_INCOMPAT_64BIT | \ + JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) #ifdef __KERNEL__ #include <linux/fs.h> #include <linux/sched.h> -#define JBD2_ASSERTIONS -#ifdef JBD2_ASSERTIONS -#define J_ASSERT(assert) \ -do { \ - if (!(assert)) { \ - printk (KERN_EMERG \ - "Assertion failure in %s() at %s:%d: \"%s\"\n", \ - __FUNCTION__, __FILE__, __LINE__, # assert); \ - BUG(); \ - } \ -} while (0) +#define J_ASSERT(assert) BUG_ON(!(assert)) #if defined(CONFIG_BUFFER_DEBUG) void buffer_assertion_failure(struct buffer_head *bh); @@ -282,10 +298,6 @@ void buffer_assertion_failure(struct buffer_head *bh); #define J_ASSERT_JH(jh, expr) J_ASSERT(expr) #endif -#else -#define J_ASSERT(assert) do { } while (0) -#endif /* JBD2_ASSERTIONS */ - #if defined(JBD2_PARANOID_IOFAIL) #define J_EXPECT(expr, why...) J_ASSERT(expr) #define J_EXPECT_BH(bh, expr, why...) J_ASSERT_BH(bh, expr) @@ -406,9 +418,23 @@ struct handle_s unsigned int h_sync: 1; /* sync-on-close */ unsigned int h_jdata: 1; /* force data journaling */ unsigned int h_aborted: 1; /* fatal error on handle */ + +#ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lockdep_map h_lockdep_map; +#endif }; +/* + * Some stats for checkpoint phase + */ +struct transaction_chp_stats_s { + unsigned long cs_chp_time; + unsigned long cs_forced_to_close; + unsigned long cs_written; + unsigned long cs_dropped; +}; + /* The transaction_t type is the guts of the journaling mechanism. It * tracks a compound transaction through its various states: * @@ -456,6 +482,8 @@ struct transaction_s /* * Transaction's current state * [no locking - only kjournald2 alters this] + * [j_list_lock] guards transition of a transaction into T_FINISHED + * state and subsequent call of __jbd2_journal_drop_transaction() * FIXME: needs barriers * KLUDGE: [use j_state_lock] */ @@ -544,6 +572,21 @@ struct transaction_s spinlock_t t_handle_lock; /* + * Longest time some handle had to wait for running transaction + */ + unsigned long t_max_wait; + + /* + * When transaction started + */ + unsigned long t_start; + + /* + * Checkpointing stats [j_checkpoint_sem] + */ + struct transaction_chp_stats_s t_chp_stats; + + /* * Number of outstanding updates running on this transaction * [t_handle_lock] */ @@ -574,6 +617,39 @@ struct transaction_s }; +struct transaction_run_stats_s { + unsigned long rs_wait; + unsigned long rs_running; + unsigned long rs_locked; + unsigned long rs_flushing; + unsigned long rs_logging; + + unsigned long rs_handle_count; + unsigned long rs_blocks; + unsigned long rs_blocks_logged; +}; + +struct transaction_stats_s { + int ts_type; + unsigned long ts_tid; + union { + struct transaction_run_stats_s run; + struct transaction_chp_stats_s chp; + } u; +}; + +#define JBD2_STATS_RUN 1 +#define JBD2_STATS_CHECKPOINT 2 + +static inline unsigned long +jbd2_time_diff(unsigned long start, unsigned long end) +{ + if (end >= start) + return end - start; + + return end + (MAX_JIFFY_OFFSET - start); +} + /** * struct journal_s - The journal_s type is the concrete type associated with * journal_t. @@ -635,6 +711,12 @@ struct transaction_s * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the * number that will fit in j_blocksize * @j_last_sync_writer: most recent pid which did a synchronous write + * @j_history: Buffer storing the transactions statistics history + * @j_history_max: Maximum number of transactions in the statistics history + * @j_history_cur: Current number of transactions in the statistics history + * @j_history_lock: Protect the transactions statistics history + * @j_proc_entry: procfs entry for the jbd statistics directory + * @j_stats: Overall statistics * @j_private: An opaque pointer to fs-private information. */ @@ -827,6 +909,19 @@ struct journal_s pid_t j_last_sync_writer; /* + * Journal statistics + */ + struct transaction_stats_s *j_history; + int j_history_max; + int j_history_cur; + /* + * Protect the transactions statistics history + */ + spinlock_t j_history_lock; + struct proc_dir_entry *j_proc_entry; + struct transaction_stats_s j_stats; + + /* * An opaque pointer to fs-private information. ext3 puts its * superblock pointer here */ @@ -932,6 +1027,8 @@ extern int jbd2_journal_check_available_features (journal_t *, unsigned long, unsigned long, unsigned long); extern int jbd2_journal_set_features (journal_t *, unsigned long, unsigned long, unsigned long); +extern void jbd2_journal_clear_features + (journal_t *, unsigned long, unsigned long, unsigned long); extern int jbd2_journal_create (journal_t *); extern int jbd2_journal_load (journal_t *journal); extern void jbd2_journal_destroy (journal_t *); diff --git a/include/linux/module.h b/include/linux/module.h index c97bdb7eb957..ac481e2094fd 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -178,7 +178,7 @@ void *__symbol_get_gpl(const char *symbol); #define __CRC_SYMBOL(sym, sec) \ extern void *__crc_##sym __attribute__((weak)); \ static const unsigned long __kcrctab_##sym \ - __attribute_used__ \ + __used \ __attribute__((section("__kcrctab" sec), unused)) \ = (unsigned long) &__crc_##sym; #else @@ -193,7 +193,7 @@ void *__symbol_get_gpl(const char *symbol); __attribute__((section("__ksymtab_strings"))) \ = MODULE_SYMBOL_PREFIX #sym; \ static const struct kernel_symbol __ksymtab_##sym \ - __attribute_used__ \ + __used \ __attribute__((section("__ksymtab" sec), unused)) \ = { (unsigned long)&sym, __kstrtab_##sym } @@ -446,11 +446,14 @@ static inline void __module_get(struct module *module) __mod ? __mod->name : "kernel"; \ }) -/* For kallsyms to ask for address resolution. NULL means not found. */ -const char *module_address_lookup(unsigned long addr, - unsigned long *symbolsize, - unsigned long *offset, - char **modname); +/* For kallsyms to ask for address resolution. namebuf should be at + * least KSYM_NAME_LEN long: a pointer to namebuf is returned if + * found, otherwise NULL. */ +char *module_address_lookup(unsigned long addr, + unsigned long *symbolsize, + unsigned long *offset, + char **modname, + char *namebuf); int lookup_module_symbol_name(unsigned long addr, char *symname); int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name); @@ -516,10 +519,11 @@ static inline void module_put(struct module *module) #define module_name(mod) "kernel" /* For kallsyms to ask for address resolution. NULL means not found. */ -static inline const char *module_address_lookup(unsigned long addr, - unsigned long *symbolsize, - unsigned long *offset, - char **modname) +static inline char *module_address_lookup(unsigned long addr, + unsigned long *symbolsize, + unsigned long *offset, + char **modname, + char *namebuf) { return NULL; } diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 13410b20600f..8126e55c5bdc 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -18,7 +18,7 @@ #define __module_cat(a,b) ___module_cat(a,b) #define __MODULE_INFO(tag, name, info) \ static const char __module_cat(name,__LINE__)[] \ - __attribute_used__ \ + __used \ __attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info #else /* !MODULE */ #define __MODULE_INFO(tag, name, info) @@ -72,7 +72,7 @@ struct kparam_array BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \ static const char __param_str_##name[] = prefix #name; \ static struct kernel_param const __param_##name \ - __attribute_used__ \ + __used \ __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ = { __param_str_##name, perm, set, get, { arg } } diff --git a/include/linux/pci.h b/include/linux/pci.h index 0dd93bb62fbe..ae1006322f80 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -867,7 +867,7 @@ enum pci_fixup_pass { /* Anonymous variables would be nice... */ #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook) \ - static const struct pci_fixup __pci_fixup_##name __attribute_used__ \ + static const struct pci_fixup __pci_fixup_##name __used \ __attribute__((__section__(#section))) = { vendor, device, hook }; #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \ DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ |