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

Commit a4277bf1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  ext4: Fix potential inode allocation soft lockup in Orlov allocator
  ext4: Make the extent validity check more paranoid
  jbd: use SWRITE_SYNC_PLUG when writing synchronous revoke records
  jbd2: use SWRITE_SYNC_PLUG when writing synchronous revoke records
  ext4: really print the find_group_flex fallback warning only once
parents 6ae85d6d b5451f7b
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -326,10 +326,13 @@ ext4_ext_max_entries(struct inode *inode, int depth)

static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext)
{
	ext4_fsblk_t block = ext_pblock(ext);
	ext4_fsblk_t block = ext_pblock(ext), valid_block;
	int len = ext4_ext_get_actual_len(ext);
	struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
	if (unlikely(block < le32_to_cpu(es->s_first_data_block) ||

	valid_block = le32_to_cpu(es->s_first_data_block) +
		EXT4_SB(inode->i_sb)->s_gdb_count;
	if (unlikely(block <= valid_block ||
		     ((block + len) > ext4_blocks_count(es))))
		return 0;
	else
@@ -339,9 +342,12 @@ static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext)
static int ext4_valid_extent_idx(struct inode *inode,
				struct ext4_extent_idx *ext_idx)
{
	ext4_fsblk_t block = idx_pblock(ext_idx);
	ext4_fsblk_t block = idx_pblock(ext_idx), valid_block;
	struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
	if (unlikely(block < le32_to_cpu(es->s_first_data_block) ||

	valid_block = le32_to_cpu(es->s_first_data_block) +
		EXT4_SB(inode->i_sb)->s_gdb_count;
	if (unlikely(block <= valid_block ||
		     (block >= ext4_blocks_count(es))))
		return 0;
	else
+4 −2
Original line number Diff line number Diff line
@@ -585,6 +585,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
fallback:
	ngroups = sbi->s_groups_count;
	avefreei = freei / ngroups;
fallback_retry:
	parent_group = EXT4_I(parent)->i_block_group;
	for (i = 0; i < ngroups; i++) {
		grp = (parent_group + i) % ngroups;
@@ -602,7 +603,7 @@ fallback:
		 * filesystems the above test can fail to find any blockgroups
		 */
		avefreei = 0;
		goto fallback;
		goto fallback_retry;
	}

	return -1;
@@ -831,12 +832,13 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
		ret2 = find_group_flex(sb, dir, &group);
		if (ret2 == -1) {
			ret2 = find_group_other(sb, dir, &group, mode);
			if (ret2 == 0 && once)
			if (ret2 == 0 && once) {
				once = 0;
				printk(KERN_NOTICE "ext4: find_group_flex "
				       "failed, fallback succeeded dir %lu\n",
				       dir->i_ino);
			}
		}
		goto got_group;
	}

+1 −1
Original line number Diff line number Diff line
@@ -502,7 +502,7 @@ void journal_commit_transaction(journal_t *journal)
		err = 0;
	}

	journal_write_revoke_records(journal, commit_transaction);
	journal_write_revoke_records(journal, commit_transaction, write_op);

	/*
	 * If we found any dirty or locked buffers, then we should have
+11 −9
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/init.h>
#include <linux/bio.h>
#endif
#include <linux/log2.h>

@@ -118,8 +119,8 @@ struct jbd_revoke_table_s
#ifdef __KERNEL__
static void write_one_revoke_record(journal_t *, transaction_t *,
				    struct journal_head **, int *,
				    struct jbd_revoke_record_s *);
static void flush_descriptor(journal_t *, struct journal_head *, int);
				    struct jbd_revoke_record_s *, int);
static void flush_descriptor(journal_t *, struct journal_head *, int, int);
#endif

/* Utility functions to maintain the revoke table */
@@ -500,7 +501,7 @@ void journal_switch_revoke_table(journal_t *journal)
 * revoke hash, deleting the entries as we go.
 */
void journal_write_revoke_records(journal_t *journal,
				  transaction_t *transaction)
				  transaction_t *transaction, int write_op)
{
	struct journal_head *descriptor;
	struct jbd_revoke_record_s *record;
@@ -524,14 +525,14 @@ void journal_write_revoke_records(journal_t *journal,
				hash_list->next;
			write_one_revoke_record(journal, transaction,
						&descriptor, &offset,
						record);
						record, write_op);
			count++;
			list_del(&record->hash);
			kmem_cache_free(revoke_record_cache, record);
		}
	}
	if (descriptor)
		flush_descriptor(journal, descriptor, offset);
		flush_descriptor(journal, descriptor, offset, write_op);
	jbd_debug(1, "Wrote %d revoke records\n", count);
}

@@ -544,7 +545,8 @@ static void write_one_revoke_record(journal_t *journal,
				    transaction_t *transaction,
				    struct journal_head **descriptorp,
				    int *offsetp,
				    struct jbd_revoke_record_s *record)
				    struct jbd_revoke_record_s *record,
				    int write_op)
{
	struct journal_head *descriptor;
	int offset;
@@ -563,7 +565,7 @@ static void write_one_revoke_record(journal_t *journal,
	/* Make sure we have a descriptor with space left for the record */
	if (descriptor) {
		if (offset == journal->j_blocksize) {
			flush_descriptor(journal, descriptor, offset);
			flush_descriptor(journal, descriptor, offset, write_op);
			descriptor = NULL;
		}
	}
@@ -600,7 +602,7 @@ static void write_one_revoke_record(journal_t *journal,

static void flush_descriptor(journal_t *journal,
			     struct journal_head *descriptor,
			     int offset)
			     int offset, int write_op)
{
	journal_revoke_header_t *header;
	struct buffer_head *bh = jh2bh(descriptor);
@@ -615,7 +617,7 @@ static void flush_descriptor(journal_t *journal,
	set_buffer_jwrite(bh);
	BUFFER_TRACE(bh, "write");
	set_buffer_dirty(bh);
	ll_rw_block(SWRITE, 1, &bh);
	ll_rw_block((write_op == WRITE) ? SWRITE : SWRITE_SYNC_PLUG, 1, &bh);
}
#endif

+2 −1
Original line number Diff line number Diff line
@@ -506,7 +506,8 @@ void jbd2_journal_commit_transaction(journal_t *journal)
	if (err)
		jbd2_journal_abort(journal, err);

	jbd2_journal_write_revoke_records(journal, commit_transaction);
	jbd2_journal_write_revoke_records(journal, commit_transaction,
					  write_op);

	jbd_debug(3, "JBD: commit phase 2\n");

Loading