Commit 1500e7e0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ext2, quota, and udf updates from Jan Kara:

 - fixes for possible use-after-free issues with quota when racing with
   chown

 - fixes for ext2 crashing when xattr allocation races with another
   block allocation to the same file from page writeback code

 - fix for block number overflow in ext2

 - marking of reiserfs as obsolete in MAINTAINERS

 - assorted minor cleanups

* tag 'for_v6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  ext2: Fix kernel-doc warnings
  ext2: improve consistency of ext2_fsblk_t datatype usage
  ext2: dump current reservation window info
  ext2: fix race between setxattr and write back
  ext2: introduce new flags argument for ext2_new_blocks()
  ext2: remove ext2_new_block()
  ext2: fix datatype of block number in ext2_xattr_set2()
  udf: Drop pointless aops assignment
  quota: use lockdep_assert_held_write in dquot_load_quota_sb
  MAINTAINERS: change reiserfs status to obsolete
  udf: Fix -Wstringop-overflow warnings
  quota: simplify drop_dquot_ref()
  quota: fix dqput() to follow the guarantees dquot_srcu should provide
  quota: add new helper dquot_active()
  quota: rename dquot_active() to inode_quota_active()
  quota: factor out dquot_write_dquot()
  ext2: remove redundant assignment to variable desc and variable best_desc
parents 63580f66 df1ae36a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -18085,7 +18085,7 @@ F: include/linux/regmap.h
REISERFS FILE SYSTEM
L:	reiserfs-devel@vger.kernel.org
S:	Supported
S:	Obsolete
F:	fs/reiserfs/
REMOTE PROCESSOR (REMOTEPROC) SUBSYSTEM
+63 −73
Original line number Diff line number Diff line
@@ -472,7 +472,7 @@ void ext2_discard_reservation(struct inode *inode)
 * @block:		start physical block to free
 * @count:		number of blocks to free
 */
void ext2_free_blocks (struct inode * inode, unsigned long block,
void ext2_free_blocks(struct inode * inode, ext2_fsblk_t block,
		      unsigned long count)
{
	struct buffer_head *bitmap_bh = NULL;
@@ -716,36 +716,34 @@ ext2_try_to_allocate(struct super_block *sb, int group,
}

/**
 * 	find_next_reservable_window():
 *		find a reservable space within the given range.
 *		It does not allocate the reservation window for now:
 *		alloc_new_reservation() will do the work later.
 * find_next_reservable_window - Find a reservable space within the given range.
 * @search_head: The list to search.
 * @my_rsv: The reservation we're currently using.
 * @sb: The super block.
 * @start_block: The first block we consider to start the real search from
 * @last_block: The maximum block number that our goal reservable space
 *	could start from.
 *
 * 	@search_head: the head of the searching list;
 *		This is not necessarily the list head of the whole filesystem
 * It does not allocate the reservation window: alloc_new_reservation()
 * will do the work later.
 *
 *		We have both head and start_block to assist the search
 *		for the reservable space. The list starts from head,
 *		but we will shift to the place where start_block is,
 *		then start from there, when looking for a reservable space.
 * We search the given range, rather than the whole reservation double
 * linked list, (start_block, last_block) to find a free region that is
 * of my size and has not been reserved.
 *
 *	@sb: the super block.
 * @search_head is not necessarily the list head of the whole filesystem.
 * We have both head and @start_block to assist the search for the
 * reservable space. The list starts from head, but we will shift to
 * the place where start_block is, then start from there, when looking
 * for a reservable space.
 *
 * 	@start_block: the first block we consider to start the real search from
 *
 * 	@last_block:
 *		the maximum block number that our goal reservable space
 *		could start from. This is normally the last block in this
 *		group. The search will end when we found the start of next
 *		possible reservable space is out of this boundary.
 *		This could handle the cross boundary reservation window
 *		request.
 *
 * 	basically we search from the given range, rather than the whole
 * 	reservation double linked list, (start_block, last_block)
 * 	to find a free region that is of my size and has not
 * 	been reserved.
 * @last_block is normally the last block in this group. The search will end
 * when we found the start of next possible reservable space is out
 * of this boundary.  This could handle the cross boundary reservation
 * window request.
 *
 * Return: -1 if we could not find a range of sufficient size.  If we could,
 * return 0 and fill in @my_rsv with the range information.
 */
static int find_next_reservable_window(
				struct ext2_reserve_window_node *search_head,
@@ -833,41 +831,34 @@ static int find_next_reservable_window(
}

/**
 * 	alloc_new_reservation()--allocate a new reservation window
 * alloc_new_reservation - Allocate a new reservation window.
 * @my_rsv: The reservation we're currently using.
 * @grp_goal: The goal block relative to the start of the group.
 * @sb: The super block.
 * @group: The group we are trying to allocate in.
 * @bitmap_bh: The block group block bitmap.
 *
 *		To make a new reservation, we search part of the filesystem
 *		reservation list (the list that inside the group). We try to
 *		allocate a new reservation window near the allocation goal,
 *		or the beginning of the group, if there is no goal.
 *
 *		We first find a reservable space after the goal, then from
 *		there, we check the bitmap for the first free block after
 *		it. If there is no free block until the end of group, then the
 *		whole group is full, we failed. Otherwise, check if the free
 *		block is inside the expected reservable space, if so, we
 *		succeed.
 *		If the first free block is outside the reservable space, then
 *		start from the first free block, we search for next available
 *		space, and go on.
 * To make a new reservation, we search part of the filesystem reservation
 * list (the list inside the group). We try to allocate a new
 * reservation window near @grp_goal, or the beginning of the
 * group, if @grp_goal is negative.
 *
 *	on succeed, a new reservation will be found and inserted into the list
 *	It contains at least one free block, and it does not overlap with other
 *	reservation windows.
 * We first find a reservable space after the goal, then from there,
 * we check the bitmap for the first free block after it. If there is
 * no free block until the end of group, then the whole group is full,
 * we failed. Otherwise, check if the free block is inside the expected
 * reservable space, if so, we succeed.
 *
 *	failed: we failed to find a reservation window in this group
 * If the first free block is outside the reservable space, then start
 * from the first free block, we search for next available space, and
 * go on.
 *
 *	@my_rsv: the reservation
 *
 *	@grp_goal: The goal (group-relative).  It is where the search for a
 *		free reservable space should start from.
 *		if we have a goal(goal >0 ), then start from there,
 *		no goal(goal = -1), we start from the first block
 *		of the group.
 *
 *	@sb: the super block
 *	@group: the group we are trying to allocate in
 *	@bitmap_bh: the block group block bitmap
 * on succeed, a new reservation will be found and inserted into the
 * list. It contains at least one free block, and it does not overlap
 * with other reservation windows.
 *
 * Return: 0 on success, -1 if we failed to find a reservation window
 * in this group
 */
static int alloc_new_reservation(struct ext2_reserve_window_node *my_rsv,
		ext2_grpblk_t grp_goal, struct super_block *sb,
@@ -1131,8 +1122,13 @@ ext2_try_to_allocate_with_rsv(struct super_block *sb, unsigned int group,

		if ((my_rsv->rsv_start > group_last_block) ||
				(my_rsv->rsv_end < group_first_block)) {
			ext2_error(sb, __func__,
				   "Reservation out of group %u range goal %d fsb[%lu,%lu] rsv[%lu, %lu]",
				   group, grp_goal, group_first_block,
				   group_last_block, my_rsv->rsv_start,
				   my_rsv->rsv_end);
			rsv_window_dump(&EXT2_SB(sb)->s_rsv_window_root, 1);
			BUG();
			return -1;
		}
		ret = ext2_try_to_allocate(sb, group, bitmap_bh, grp_goal,
					   &num, &my_rsv->rsv_window);
@@ -1193,6 +1189,7 @@ int ext2_data_block_valid(struct ext2_sb_info *sbi, ext2_fsblk_t start_blk,
 * @goal:		given target block(filesystem wide)
 * @count:		target number of blocks to allocate
 * @errp:		error code
 * @flags:		allocate flags
 *
 * ext2_new_blocks uses a goal block to assist allocation.  If the goal is
 * free, or there is a free block within 32 blocks of the goal, that block
@@ -1202,7 +1199,7 @@ int ext2_data_block_valid(struct ext2_sb_info *sbi, ext2_fsblk_t start_blk,
 * This function also updates quota and i_blocks field.
 */
ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
		    unsigned long *count, int *errp)
		    unsigned long *count, int *errp, unsigned int flags)
{
	struct buffer_head *bitmap_bh = NULL;
	struct buffer_head *gdp_bh;
@@ -1241,15 +1238,15 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
	es = EXT2_SB(sb)->s_es;
	ext2_debug("goal=%lu.\n", goal);
	/*
	 * Allocate a block from reservation only when
	 * filesystem is mounted with reservation(default,-o reservation), and
	 * it's a regular file, and
	 * the desired window size is greater than 0 (One could use ioctl
	 * command EXT2_IOC_SETRSVSZ to set the window size to 0 to turn off
	 * reservation on that particular file)
	 * Allocate a block from reservation only when the filesystem is
	 * mounted with reservation(default,-o reservation), and it's a regular
	 * file, and the desired window size is greater than 0 (One could use
	 * ioctl command EXT2_IOC_SETRSVSZ to set the window size to 0 to turn
	 * off reservation on that particular file). Also do not use the
	 * reservation window if the caller asked us not to do it.
	 */
	block_i = EXT2_I(inode)->i_block_alloc_info;
	if (block_i) {
	if (!(flags & EXT2_ALLOC_NORESERVE) && block_i) {
		windowsz = block_i->rsv_window_node.rsv_goal_size;
		if (windowsz > 0)
			my_rsv = &block_i->rsv_window_node;
@@ -1429,13 +1426,6 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
	return 0;
}

ext2_fsblk_t ext2_new_block(struct inode *inode, unsigned long goal, int *errp)
{
	unsigned long count = 1;

	return ext2_new_blocks(inode, goal, &count, errp);
}

#ifdef EXT2FS_DEBUG

unsigned long ext2_count_free(struct buffer_head *map, unsigned int numchars)
+9 −5
Original line number Diff line number Diff line
@@ -398,6 +398,12 @@ struct ext2_inode {
#define EXT2_ERRORS_PANIC		3	/* Panic */
#define EXT2_ERRORS_DEFAULT		EXT2_ERRORS_CONTINUE

/*
 * Allocation flags
 */
#define EXT2_ALLOC_NORESERVE            0x1	/* Do not use reservation
						 * window for allocation */

/*
 * Structure of the super block
 */
@@ -695,13 +701,11 @@ static inline struct ext2_inode_info *EXT2_I(struct inode *inode)
/* balloc.c */
extern int ext2_bg_has_super(struct super_block *sb, int group);
extern unsigned long ext2_bg_num_gdb(struct super_block *sb, int group);
extern ext2_fsblk_t ext2_new_block(struct inode *, unsigned long, int *);
extern ext2_fsblk_t ext2_new_blocks(struct inode *, unsigned long,
				unsigned long *, int *);
extern ext2_fsblk_t ext2_new_blocks(struct inode *, ext2_fsblk_t,
				unsigned long *, int *, unsigned int);
extern int ext2_data_block_valid(struct ext2_sb_info *sbi, ext2_fsblk_t start_blk,
				 unsigned int count);
extern void ext2_free_blocks (struct inode *, unsigned long,
			      unsigned long);
extern void ext2_free_blocks(struct inode *, ext2_fsblk_t, unsigned long);
extern unsigned long ext2_count_free_blocks (struct super_block *);
extern unsigned long ext2_count_dirs (struct super_block *);
extern struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
+0 −3
Original line number Diff line number Diff line
@@ -273,7 +273,6 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)

	if ((parent == d_inode(sb->s_root)) ||
	    (EXT2_I(parent)->i_flags & EXT2_TOPDIR_FL)) {
		struct ext2_group_desc *best_desc = NULL;
		int best_ndir = inodes_per_group;
		int best_group = -1;

@@ -291,10 +290,8 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
				continue;
			best_group = group;
			best_ndir = le16_to_cpu(desc->bg_used_dirs_count);
			best_desc = desc;
		}
		if (best_group >= 0) {
			desc = best_desc;
			group = best_group;
			goto found;
		}
+14 −10
Original line number Diff line number Diff line
@@ -385,12 +385,16 @@ ext2_blks_to_allocate(Indirect * branch, int k, unsigned long blks,
}

/**
 *	ext2_alloc_blocks: multiple allocate blocks needed for a branch
 *	@indirect_blks: the number of blocks need to allocate for indirect
 *			blocks
 *	@blks: the number of blocks need to allocate for direct blocks
 *	@new_blocks: on return it will store the new block numbers for
 *	the indirect blocks(if needed) and the first direct block,
 * ext2_alloc_blocks: Allocate multiple blocks needed for a branch.
 * @inode: Owner.
 * @goal: Preferred place for allocation.
 * @indirect_blks: The number of blocks needed to allocate for indirect blocks.
 * @blks: The number of blocks need to allocate for direct blocks.
 * @new_blocks: On return it will store the new block numbers for
 *	the indirect blocks(if needed) and the first direct block.
 * @err: Error pointer.
 *
 * Return: Number of blocks allocated.
 */
static int ext2_alloc_blocks(struct inode *inode,
			ext2_fsblk_t goal, int indirect_blks, int blks,
@@ -415,7 +419,7 @@ static int ext2_alloc_blocks(struct inode *inode,
	while (1) {
		count = target;
		/* allocating blocks for indirect blocks and direct blocks */
		current_block = ext2_new_blocks(inode,goal,&count,err);
		current_block = ext2_new_blocks(inode, goal, &count, err, 0);
		if (*err)
			goto failed_out;

@@ -1082,8 +1086,8 @@ static Indirect *ext2_find_shared(struct inode *inode,
 */
static inline void ext2_free_data(struct inode *inode, __le32 *p, __le32 *q)
{
	unsigned long block_to_free = 0, count = 0;
	unsigned long nr;
	ext2_fsblk_t block_to_free = 0, count = 0;
	ext2_fsblk_t nr;

	for ( ; p < q ; p++) {
		nr = le32_to_cpu(*p);
@@ -1123,7 +1127,7 @@ static inline void ext2_free_data(struct inode *inode, __le32 *p, __le32 *q)
static void ext2_free_branches(struct inode *inode, __le32 *p, __le32 *q, int depth)
{
	struct buffer_head * bh;
	unsigned long nr;
	ext2_fsblk_t nr;

	if (depth--) {
		int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
Loading