Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1f63b9c1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (36 commits)
  ext4: fix up rb_root initializations to use RB_ROOT
  ext4: Code cleanup for EXT4_IOC_MOVE_EXT ioctl
  ext4: Fix the NULL reference in double_down_write_data_sem()
  ext4: Fix insertion point of extent in mext_insert_across_blocks()
  ext4: consolidate in_range() definitions
  ext4: cleanup to use ext4_grp_offs_to_block()
  ext4: cleanup to use ext4_group_first_block_no()
  ext4: Release page references acquired in ext4_da_block_invalidatepages
  ext4: Fix ext4_quota_write cross block boundary behaviour
  ext4: Convert BUG_ON checks to use ext4_error() instead
  ext4: Use direct_IO_no_locking in ext4 dio read
  ext4: use ext4_get_block_write in buffer write
  ext4: mechanical rename some of the direct I/O get_block's identifiers
  ext4: make "offset" consistent in ext4_check_dir_entry()
  ext4: Handle non empty on-disk orphan link
  ext4: explicitly remove inode from orphan list after failed direct io
  ext4: fix error handling in migrate
  ext4: deprecate obsoleted mount options
  ext4: Fix fencepost error in chosing choosing group vs file preallocation.
  jbd2: clean up an assertion in jbd2_journal_commit_transaction()
  ...
parents b24bc1e6 64e290ec
Loading
Loading
Loading
Loading
+11 −24
Original line number Diff line number Diff line
@@ -97,8 +97,8 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
		/* If checksum is bad mark all blocks used to prevent allocation
		 * essentially implementing a per-group read-only flag. */
		if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
			ext4_error(sb, __func__,
				  "Checksum bad for group %u", block_group);
			ext4_error(sb, "Checksum bad for group %u",
					block_group);
			ext4_free_blks_set(sb, gdp, 0);
			ext4_free_inodes_set(sb, gdp, 0);
			ext4_itable_unused_set(sb, gdp, 0);
@@ -130,8 +130,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
		 * to make sure we calculate the right free blocks
		 */
		group_blocks = ext4_blocks_count(sbi->s_es) -
			le32_to_cpu(sbi->s_es->s_first_data_block) -
			(EXT4_BLOCKS_PER_GROUP(sb) * (ngroups - 1));
			ext4_group_first_block_no(sb, ngroups - 1);
	} else {
		group_blocks = EXT4_BLOCKS_PER_GROUP(sb);
	}
@@ -189,9 +188,6 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
 * when a file system is mounted (see ext4_fill_super).
 */


#define in_range(b, first, len)	((b) >= (first) && (b) <= (first) + (len) - 1)

/**
 * ext4_get_group_desc() -- load group descriptor from disk
 * @sb:			super block
@@ -210,10 +206,8 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb,
	struct ext4_sb_info *sbi = EXT4_SB(sb);

	if (block_group >= ngroups) {
		ext4_error(sb, "ext4_get_group_desc",
			   "block_group >= groups_count - "
			   "block_group = %u, groups_count = %u",
			   block_group, ngroups);
		ext4_error(sb, "block_group >= groups_count - block_group = %u,"
			   " groups_count = %u", block_group, ngroups);

		return NULL;
	}
@@ -221,8 +215,7 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb,
	group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb);
	offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1);
	if (!sbi->s_group_desc[group_desc]) {
		ext4_error(sb, "ext4_get_group_desc",
			   "Group descriptor not loaded - "
		ext4_error(sb, "Group descriptor not loaded - "
			   "block_group = %u, group_desc = %u, desc = %u",
			   block_group, group_desc, offset);
		return NULL;
@@ -282,9 +275,7 @@ static int ext4_valid_block_bitmap(struct super_block *sb,
		return 1;

err_out:
	ext4_error(sb, __func__,
			"Invalid block bitmap - "
			"block_group = %d, block = %llu",
	ext4_error(sb, "Invalid block bitmap - block_group = %d, block = %llu",
			block_group, bitmap_blk);
	return 0;
}
@@ -311,8 +302,7 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
	bitmap_blk = ext4_block_bitmap(sb, desc);
	bh = sb_getblk(sb, bitmap_blk);
	if (unlikely(!bh)) {
		ext4_error(sb, __func__,
			    "Cannot read block bitmap - "
		ext4_error(sb, "Cannot read block bitmap - "
			    "block_group = %u, block_bitmap = %llu",
			    block_group, bitmap_blk);
		return NULL;
@@ -354,8 +344,7 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
	set_bitmap_uptodate(bh);
	if (bh_submit_read(bh) < 0) {
		put_bh(bh);
		ext4_error(sb, __func__,
			    "Cannot read block bitmap - "
		ext4_error(sb, "Cannot read block bitmap - "
			    "block_group = %u, block_bitmap = %llu",
			    block_group, bitmap_blk);
		return NULL;
@@ -419,8 +408,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
	    in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) ||
	    in_range(block + count - 1, ext4_inode_table(sb, desc),
		     sbi->s_itb_per_group)) {
		ext4_error(sb, __func__,
			   "Adding blocks in system zones - "
		ext4_error(sb, "Adding blocks in system zones - "
			   "Block = %llu, count = %lu",
			   block, count);
		goto error_return;
@@ -453,8 +441,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
		BUFFER_TRACE(bitmap_bh, "clear bit");
		if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group),
						bit + i, bitmap_bh->b_data)) {
			ext4_error(sb, __func__,
				   "bit already cleared for block %llu",
			ext4_error(sb, "bit already cleared for block %llu",
				   (ext4_fsblk_t)(block + i));
			BUFFER_TRACE(bitmap_bh, "bit already cleared");
		} else {
+2 −2
Original line number Diff line number Diff line
@@ -205,14 +205,14 @@ void ext4_release_system_zone(struct super_block *sb)
		entry = rb_entry(n, struct ext4_system_zone, node);
		kmem_cache_free(ext4_system_zone_cachep, entry);
		if (!parent)
			EXT4_SB(sb)->system_blks.rb_node = NULL;
			EXT4_SB(sb)->system_blks = RB_ROOT;
		else if (parent->rb_left == n)
			parent->rb_left = NULL;
		else if (parent->rb_right == n)
			parent->rb_right = NULL;
		n = parent;
	}
	EXT4_SB(sb)->system_blks.rb_node = NULL;
	EXT4_SB(sb)->system_blks = RB_ROOT;
}

/*
+8 −6
Original line number Diff line number Diff line
@@ -83,10 +83,12 @@ int ext4_check_dir_entry(const char *function, struct inode *dir,
		error_msg = "inode out of bounds";

	if (error_msg != NULL)
		ext4_error(dir->i_sb, function,
			"bad entry in directory #%lu: %s - "
			"offset=%u, inode=%u, rec_len=%d, name_len=%d",
			dir->i_ino, error_msg, offset,
		__ext4_error(dir->i_sb, function,
			"bad entry in directory #%lu: %s - block=%llu"
			"offset=%u(%u), inode=%u, rec_len=%d, name_len=%d",
			dir->i_ino, error_msg, 
			(unsigned long long) bh->b_blocknr,     
			(unsigned) (offset%bh->b_size), offset,
			le32_to_cpu(de->inode),
			rlen, de->name_len);
	return error_msg == NULL ? 1 : 0;
@@ -150,7 +152,7 @@ static int ext4_readdir(struct file *filp,
		 */
		if (!bh) {
			if (!dir_has_error) {
				ext4_error(sb, __func__, "directory #%lu "
				ext4_error(sb, "directory #%lu "
					   "contains a hole at offset %Lu",
					   inode->i_ino,
					   (unsigned long long) filp->f_pos);
@@ -303,7 +305,7 @@ static void free_rb_tree_fname(struct rb_root *root)
			kfree(old);
		}
		if (!parent)
			root->rb_node = NULL;
			*root = RB_ROOT;
		else if (parent->rb_left == n)
			parent->rb_left = NULL;
		else if (parent->rb_right == n)
+77 −29
Original line number Diff line number Diff line
@@ -53,6 +53,12 @@
#define ext4_debug(f, a...)	do {} while (0)
#endif

#define EXT4_ERROR_INODE(inode, fmt, a...) \
	ext4_error_inode(__func__, (inode), (fmt), ## a);

#define EXT4_ERROR_FILE(file, fmt, a...)	\
	ext4_error_file(__func__, (file), (fmt), ## a);

/* data type for block offset of block group */
typedef int ext4_grpblk_t;

@@ -133,14 +139,14 @@ struct mpage_da_data {
	int pages_written;
	int retval;
};
#define	DIO_AIO_UNWRITTEN	0x1
#define	EXT4_IO_UNWRITTEN	0x1
typedef struct ext4_io_end {
	struct list_head	list;		/* per-file finished AIO list */
	struct inode		*inode;		/* file being written to */
	unsigned int		flag;		/* unwritten or not */
	int			error;		/* I/O error code */
	ext4_lblk_t		offset;		/* offset in the file */
	size_t			size;		/* size of the extent */
	struct page		*page;		/* page struct for buffer write */
	loff_t			offset;		/* offset in the file */
	ssize_t			size;		/* size of the extent */
	struct work_struct	work;		/* data work queue */
} ext4_io_end_t;

@@ -284,10 +290,12 @@ struct flex_groups {
#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_RESERVED_FL		0x80000000 /* reserved for ext4 lib */

#define EXT4_FL_USER_VISIBLE		0x000BDFFF /* User visible flags */
#define EXT4_FL_USER_MODIFIABLE		0x000B80FF /* User modifiable flags */
#define EXT4_FL_USER_VISIBLE		0x004BDFFF /* User visible flags */
#define EXT4_FL_USER_MODIFIABLE		0x004B80FF /* User modifiable flags */

/* Flags that should be inherited by new inodes from their parent. */
#define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
@@ -313,17 +321,6 @@ static inline __u32 ext4_mask_flags(umode_t mode, __u32 flags)
		return flags & EXT4_OTHER_FLMASK;
}

/*
 * Inode dynamic state flags
 */
#define EXT4_STATE_JDATA		0x00000001 /* journaled data exists */
#define EXT4_STATE_NEW			0x00000002 /* inode is newly created */
#define EXT4_STATE_XATTR		0x00000004 /* has in-inode xattrs */
#define EXT4_STATE_NO_EXPAND		0x00000008 /* No space for expansion */
#define EXT4_STATE_DA_ALLOC_CLOSE	0x00000010 /* Alloc DA blks on close */
#define EXT4_STATE_EXT_MIGRATE		0x00000020 /* Inode is migrating */
#define EXT4_STATE_DIO_UNWRITTEN	0x00000040 /* need convert on dio done*/

/* Used to pass group descriptor data when online resize is done */
struct ext4_new_group_input {
	__u32 group;		/* Group number for this data */
@@ -364,19 +361,20 @@ struct ext4_new_group_data {
	/* caller is from the direct IO path, request to creation of an
	unitialized extents if not allocated, split the uninitialized
	extent if blocks has been preallocated already*/
#define EXT4_GET_BLOCKS_DIO			0x0008
#define EXT4_GET_BLOCKS_PRE_IO			0x0008
#define EXT4_GET_BLOCKS_CONVERT			0x0010
#define EXT4_GET_BLOCKS_DIO_CREATE_EXT		(EXT4_GET_BLOCKS_DIO|\
#define EXT4_GET_BLOCKS_IO_CREATE_EXT		(EXT4_GET_BLOCKS_PRE_IO|\
					 EXT4_GET_BLOCKS_CREATE_UNINIT_EXT)
	/* Convert extent to initialized after IO complete */
#define EXT4_GET_BLOCKS_IO_CONVERT_EXT		(EXT4_GET_BLOCKS_CONVERT|\
					 EXT4_GET_BLOCKS_CREATE_UNINIT_EXT)
	/* Convert extent to initialized after direct IO complete */
#define EXT4_GET_BLOCKS_DIO_CONVERT_EXT		(EXT4_GET_BLOCKS_CONVERT|\
					 EXT4_GET_BLOCKS_DIO_CREATE_EXT)

/*
 * Flags used by ext4_free_blocks
 */
#define EXT4_FREE_BLOCKS_METADATA	0x0001
#define EXT4_FREE_BLOCKS_FORGET		0x0002
#define EXT4_FREE_BLOCKS_VALIDATED	0x0004

/*
 * ioctl commands
@@ -630,7 +628,7 @@ struct ext4_inode_info {
	 * near to their parent directory's inode.
	 */
	ext4_group_t	i_block_group;
	__u32	i_state;		/* Dynamic state flags for ext4 */
	unsigned long	i_state_flags;		/* Dynamic state flags */

	ext4_lblk_t		i_dir_start_lookup;
#ifdef CONFIG_EXT4_FS_XATTR
@@ -708,8 +706,9 @@ struct ext4_inode_info {
	qsize_t i_reserved_quota;
#endif

	/* completed async DIOs that might need unwritten extents handling */
	struct list_head i_aio_dio_complete_list;
	/* completed IOs that might need unwritten extents handling */
	struct list_head i_completed_io_list;
	spinlock_t i_completed_io_lock;
	/* current io_end structure for async DIO write*/
	ext4_io_end_t *cur_aio_dio;

@@ -760,6 +759,7 @@ struct ext4_inode_info {
#define EXT4_MOUNT_QUOTA		0x80000 /* Some quota option set */
#define EXT4_MOUNT_USRQUOTA		0x100000 /* "old" user quota */
#define EXT4_MOUNT_GRPQUOTA		0x200000 /* "old" group quota */
#define EXT4_MOUNT_DIOREAD_NOLOCK	0x400000 /* Enable support for dio read nolocking */
#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 */
@@ -1050,6 +1050,34 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
		(ino >= EXT4_FIRST_INO(sb) &&
		 ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count));
}

/*
 * Inode dynamic state flags
 */
enum {
	EXT4_STATE_JDATA,		/* journaled data exists */
	EXT4_STATE_NEW,			/* inode is newly created */
	EXT4_STATE_XATTR,		/* has in-inode xattrs */
	EXT4_STATE_NO_EXPAND,		/* No space for expansion */
	EXT4_STATE_DA_ALLOC_CLOSE,	/* Alloc DA blks on close */
	EXT4_STATE_EXT_MIGRATE,		/* Inode is migrating */
	EXT4_STATE_DIO_UNWRITTEN,	/* need convert on dio done*/
};

static inline int ext4_test_inode_state(struct inode *inode, int bit)
{
	return test_bit(bit, &EXT4_I(inode)->i_state_flags);
}

static inline void ext4_set_inode_state(struct inode *inode, int bit)
{
	set_bit(bit, &EXT4_I(inode)->i_state_flags);
}

static inline void ext4_clear_inode_state(struct inode *inode, int bit)
{
	clear_bit(bit, &EXT4_I(inode)->i_state_flags);
}
#else
/* Assume that user mode programs are passing in an ext4fs superblock, not
 * a kernel struct super_block.  This will allow us to call the feature-test
@@ -1126,6 +1154,8 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
#define EXT4_FEATURE_INCOMPAT_64BIT		0x0080
#define EXT4_FEATURE_INCOMPAT_MMP               0x0100
#define EXT4_FEATURE_INCOMPAT_FLEX_BG		0x0200
#define EXT4_FEATURE_INCOMPAT_EA_INODE		0x0400 /* EA in inode */
#define EXT4_FEATURE_INCOMPAT_DIRDATA		0x1000 /* data in dirent */

#define EXT4_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
#define EXT4_FEATURE_INCOMPAT_SUPP	(EXT4_FEATURE_INCOMPAT_FILETYPE| \
@@ -1439,7 +1469,7 @@ extern int ext4_block_truncate_page(handle_t *handle,
		struct address_space *mapping, loff_t from);
extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
extern qsize_t *ext4_get_reserved_space(struct inode *inode);
extern int flush_aio_dio_completed_IO(struct inode *inode);
extern int flush_completed_IO(struct inode *inode);
extern void ext4_da_update_reserve_space(struct inode *inode,
					int used, int quota_claim);
/* ioctl.c */
@@ -1465,13 +1495,20 @@ extern int ext4_group_extend(struct super_block *sb,
				ext4_fsblk_t n_blocks_count);

/* super.c */
extern void ext4_error(struct super_block *, const char *, const char *, ...)
extern void __ext4_error(struct super_block *, const char *, const char *, ...)
	__attribute__ ((format (printf, 3, 4)));
#define ext4_error(sb, message...)	__ext4_error(sb, __func__, ## message)
extern void ext4_error_inode(const char *, struct inode *, const char *, ...)
	__attribute__ ((format (printf, 3, 4)));
extern void ext4_error_file(const char *, struct file *, const char *, ...)
	__attribute__ ((format (printf, 3, 4)));
extern void __ext4_std_error(struct super_block *, const char *, int);
extern void ext4_abort(struct super_block *, const char *, const char *, ...)
	__attribute__ ((format (printf, 3, 4)));
extern void ext4_warning(struct super_block *, const char *, const char *, ...)
extern void __ext4_warning(struct super_block *, const char *,
			  const char *, ...)
	__attribute__ ((format (printf, 3, 4)));
#define ext4_warning(sb, message...)	__ext4_warning(sb, __func__, ## message)
extern void ext4_msg(struct super_block *, const char *, const char *, ...)
	__attribute__ ((format (printf, 3, 4)));
extern void ext4_grp_locked_error(struct super_block *, ext4_group_t,
@@ -1744,7 +1781,7 @@ extern void ext4_ext_release(struct super_block *);
extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset,
			  loff_t len);
extern int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
			  loff_t len);
			  ssize_t len);
extern int ext4_get_blocks(handle_t *handle, struct inode *inode,
			   sector_t block, unsigned int max_blocks,
			   struct buffer_head *bh, int flags);
@@ -1756,6 +1793,15 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,
			     __u64 len, __u64 *moved_len);


/* BH_Uninit flag: blocks are allocated but uninitialized on disk */
enum ext4_state_bits {
	BH_Uninit	/* blocks are allocated but uninitialized on disk */
	  = BH_JBDPrivateStart,
};

BUFFER_FNS(Uninit, uninit)
TAS_BUFFER_FNS(Uninit, uninit)

/*
 * Add new method to test wether block and inode bitmaps are properly
 * initialized. With uninit_bg reading the block from disk is not enough
@@ -1773,6 +1819,8 @@ static inline void set_bitmap_uptodate(struct buffer_head *bh)
	set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state);
}

#define in_range(b, first, len)	((b) >= (first) && (b) <= (first) + (len) - 1)

#endif	/* __KERNEL__ */

#endif	/* _EXT4_H */
+2 −2
Original line number Diff line number Diff line
@@ -125,14 +125,14 @@ int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
			ext4_journal_abort_handle(where, __func__, bh,
						  handle, err);
	} else {
		if (inode && bh)
		if (inode)
			mark_buffer_dirty_inode(bh, inode);
		else
			mark_buffer_dirty(bh);
		if (inode && inode_needs_sync(inode)) {
			sync_dirty_buffer(bh);
			if (buffer_req(bh) && !buffer_uptodate(bh)) {
				ext4_error(inode->i_sb, __func__,
				ext4_error(inode->i_sb,
					   "IO error syncing inode, "
					   "inode=%lu, block=%llu",
					   inode->i_ino,
Loading