Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (57 commits) jbd2: Fix oops in jbd2_journal_init_inode() on corrupted fs ext4: Remove "extents" mount option block: Add Kconfig help which notes that ext4 needs CONFIG_LBD ext4: Make printk's consistently prefixed with "EXT4-fs: " ext4: Add sanity checks for the superblock before mounting the filesystem ext4: Add mount option to set kjournald's I/O priority jbd2: Submit writes to the journal using WRITE_SYNC jbd2: Add pid and journal device name to the "kjournald2 starting" message ext4: Add markers for better debuggability ext4: Remove code to create the journal inode ext4: provide function to release metadata pages under memory pressure ext3: provide function to release metadata pages under memory pressure add releasepage hooks to block devices which can be used by file systems ext4: Fix s_dirty_blocks_counter if block allocation failed with nodelalloc ext4: Init the complete page while building buddy cache ext4: Don't allow new groups to be added during block allocation ext4: mark the blocks/inode bitmap beyond end of group as used ext4: Use new buffer_head flag to check uninit group bitmaps initialization ext4: Fix the race between read_inode_bitmap() and ext4_new_inode() ext4: code cleanup ...
This commit is contained in:
@ -368,6 +368,8 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
|
||||
goto fail;
|
||||
}
|
||||
hinfo->hash_version = root->info.hash_version;
|
||||
if (hinfo->hash_version <= DX_HASH_TEA)
|
||||
hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
|
||||
hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
|
||||
if (d_name)
|
||||
ext4fs_dirhash(d_name->name, d_name->len, hinfo);
|
||||
@ -637,6 +639,9 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
|
||||
dir = dir_file->f_path.dentry->d_inode;
|
||||
if (!(EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) {
|
||||
hinfo.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
|
||||
if (hinfo.hash_version <= DX_HASH_TEA)
|
||||
hinfo.hash_version +=
|
||||
EXT4_SB(dir->i_sb)->s_hash_unsigned;
|
||||
hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
|
||||
count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo,
|
||||
start_hash, start_minor_hash);
|
||||
@ -802,7 +807,7 @@ static inline int ext4_match (int len, const char * const name,
|
||||
static inline int search_dirblock(struct buffer_head *bh,
|
||||
struct inode *dir,
|
||||
const struct qstr *d_name,
|
||||
unsigned long offset,
|
||||
unsigned int offset,
|
||||
struct ext4_dir_entry_2 ** res_dir)
|
||||
{
|
||||
struct ext4_dir_entry_2 * de;
|
||||
@ -1039,11 +1044,11 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, stru
|
||||
bh = ext4_find_entry(dir, &dentry->d_name, &de);
|
||||
inode = NULL;
|
||||
if (bh) {
|
||||
unsigned long ino = le32_to_cpu(de->inode);
|
||||
__u32 ino = le32_to_cpu(de->inode);
|
||||
brelse(bh);
|
||||
if (!ext4_valid_inum(dir->i_sb, ino)) {
|
||||
ext4_error(dir->i_sb, "ext4_lookup",
|
||||
"bad inode number: %lu", ino);
|
||||
"bad inode number: %u", ino);
|
||||
return ERR_PTR(-EIO);
|
||||
}
|
||||
inode = ext4_iget(dir->i_sb, ino);
|
||||
@ -1056,7 +1061,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, stru
|
||||
|
||||
struct dentry *ext4_get_parent(struct dentry *child)
|
||||
{
|
||||
unsigned long ino;
|
||||
__u32 ino;
|
||||
struct inode *inode;
|
||||
static const struct qstr dotdot = {
|
||||
.name = "..",
|
||||
@ -1074,7 +1079,7 @@ struct dentry *ext4_get_parent(struct dentry *child)
|
||||
|
||||
if (!ext4_valid_inum(child->d_inode->i_sb, ino)) {
|
||||
ext4_error(child->d_inode->i_sb, "ext4_get_parent",
|
||||
"bad inode number: %lu", ino);
|
||||
"bad inode number: %u", ino);
|
||||
return ERR_PTR(-EIO);
|
||||
}
|
||||
|
||||
@ -1162,9 +1167,9 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
|
||||
u32 hash2;
|
||||
struct dx_map_entry *map;
|
||||
char *data1 = (*bh)->b_data, *data2;
|
||||
unsigned split, move, size, i;
|
||||
unsigned split, move, size;
|
||||
struct ext4_dir_entry_2 *de = NULL, *de2;
|
||||
int err = 0;
|
||||
int err = 0, i;
|
||||
|
||||
bh2 = ext4_append (handle, dir, &newblock, &err);
|
||||
if (!(bh2)) {
|
||||
@ -1224,10 +1229,10 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
|
||||
de = de2;
|
||||
}
|
||||
dx_insert_block(frame, hash2 + continued, newblock);
|
||||
err = ext4_journal_dirty_metadata(handle, bh2);
|
||||
err = ext4_handle_dirty_metadata(handle, dir, bh2);
|
||||
if (err)
|
||||
goto journal_error;
|
||||
err = ext4_journal_dirty_metadata(handle, frame->bh);
|
||||
err = ext4_handle_dirty_metadata(handle, dir, frame->bh);
|
||||
if (err)
|
||||
goto journal_error;
|
||||
brelse(bh2);
|
||||
@ -1262,7 +1267,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
|
||||
struct inode *dir = dentry->d_parent->d_inode;
|
||||
const char *name = dentry->d_name.name;
|
||||
int namelen = dentry->d_name.len;
|
||||
unsigned long offset = 0;
|
||||
unsigned int offset = 0;
|
||||
unsigned short reclen;
|
||||
int nlen, rlen, err;
|
||||
char *top;
|
||||
@ -1331,8 +1336,8 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
|
||||
ext4_update_dx_flag(dir);
|
||||
dir->i_version++;
|
||||
ext4_mark_inode_dirty(handle, dir);
|
||||
BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
|
||||
err = ext4_journal_dirty_metadata(handle, bh);
|
||||
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
|
||||
err = ext4_handle_dirty_metadata(handle, dir, bh);
|
||||
if (err)
|
||||
ext4_std_error(dir->i_sb, err);
|
||||
brelse(bh);
|
||||
@ -1404,6 +1409,8 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
|
||||
|
||||
/* Initialize as for dx_probe */
|
||||
hinfo.hash_version = root->info.hash_version;
|
||||
if (hinfo.hash_version <= DX_HASH_TEA)
|
||||
hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
|
||||
hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
|
||||
ext4fs_dirhash(name, namelen, &hinfo);
|
||||
frame = frames;
|
||||
@ -1433,7 +1440,6 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
|
||||
struct inode *inode)
|
||||
{
|
||||
struct inode *dir = dentry->d_parent->d_inode;
|
||||
unsigned long offset;
|
||||
struct buffer_head *bh;
|
||||
struct ext4_dir_entry_2 *de;
|
||||
struct super_block *sb;
|
||||
@ -1455,7 +1461,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
|
||||
ext4_mark_inode_dirty(handle, dir);
|
||||
}
|
||||
blocks = dir->i_size >> sb->s_blocksize_bits;
|
||||
for (block = 0, offset = 0; block < blocks; block++) {
|
||||
for (block = 0; block < blocks; block++) {
|
||||
bh = ext4_bread(handle, dir, block, 0, &retval);
|
||||
if(!bh)
|
||||
return retval;
|
||||
@ -1570,7 +1576,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
|
||||
dxtrace(dx_show_index("node", frames[1].entries));
|
||||
dxtrace(dx_show_index("node",
|
||||
((struct dx_node *) bh2->b_data)->entries));
|
||||
err = ext4_journal_dirty_metadata(handle, bh2);
|
||||
err = ext4_handle_dirty_metadata(handle, inode, bh2);
|
||||
if (err)
|
||||
goto journal_error;
|
||||
brelse (bh2);
|
||||
@ -1596,7 +1602,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
|
||||
if (err)
|
||||
goto journal_error;
|
||||
}
|
||||
ext4_journal_dirty_metadata(handle, frames[0].bh);
|
||||
ext4_handle_dirty_metadata(handle, inode, frames[0].bh);
|
||||
}
|
||||
de = do_split(handle, dir, &bh, frame, &hinfo, &err);
|
||||
if (!de)
|
||||
@ -1642,8 +1648,8 @@ static int ext4_delete_entry(handle_t *handle,
|
||||
else
|
||||
de->inode = 0;
|
||||
dir->i_version++;
|
||||
BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
|
||||
ext4_journal_dirty_metadata(handle, bh);
|
||||
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
|
||||
ext4_handle_dirty_metadata(handle, dir, bh);
|
||||
return 0;
|
||||
}
|
||||
i += ext4_rec_len_from_disk(de->rec_len);
|
||||
@ -1721,7 +1727,7 @@ retry:
|
||||
return PTR_ERR(handle);
|
||||
|
||||
if (IS_DIRSYNC(dir))
|
||||
handle->h_sync = 1;
|
||||
ext4_handle_sync(handle);
|
||||
|
||||
inode = ext4_new_inode (handle, dir, mode);
|
||||
err = PTR_ERR(inode);
|
||||
@ -1755,7 +1761,7 @@ retry:
|
||||
return PTR_ERR(handle);
|
||||
|
||||
if (IS_DIRSYNC(dir))
|
||||
handle->h_sync = 1;
|
||||
ext4_handle_sync(handle);
|
||||
|
||||
inode = ext4_new_inode(handle, dir, mode);
|
||||
err = PTR_ERR(inode);
|
||||
@ -1791,7 +1797,7 @@ retry:
|
||||
return PTR_ERR(handle);
|
||||
|
||||
if (IS_DIRSYNC(dir))
|
||||
handle->h_sync = 1;
|
||||
ext4_handle_sync(handle);
|
||||
|
||||
inode = ext4_new_inode(handle, dir, S_IFDIR | mode);
|
||||
err = PTR_ERR(inode);
|
||||
@ -1820,8 +1826,8 @@ retry:
|
||||
strcpy(de->name, "..");
|
||||
ext4_set_de_type(dir->i_sb, de, S_IFDIR);
|
||||
inode->i_nlink = 2;
|
||||
BUFFER_TRACE(dir_block, "call ext4_journal_dirty_metadata");
|
||||
ext4_journal_dirty_metadata(handle, dir_block);
|
||||
BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
|
||||
ext4_handle_dirty_metadata(handle, dir, dir_block);
|
||||
brelse(dir_block);
|
||||
ext4_mark_inode_dirty(handle, inode);
|
||||
err = ext4_add_entry(handle, dentry, inode);
|
||||
@ -1850,7 +1856,7 @@ out_stop:
|
||||
*/
|
||||
static int empty_dir(struct inode *inode)
|
||||
{
|
||||
unsigned long offset;
|
||||
unsigned int offset;
|
||||
struct buffer_head *bh;
|
||||
struct ext4_dir_entry_2 *de, *de1;
|
||||
struct super_block *sb;
|
||||
@ -1895,7 +1901,7 @@ static int empty_dir(struct inode *inode)
|
||||
if (err)
|
||||
ext4_error(sb, __func__,
|
||||
"error %d reading directory"
|
||||
" #%lu offset %lu",
|
||||
" #%lu offset %u",
|
||||
err, inode->i_ino, offset);
|
||||
offset += sb->s_blocksize;
|
||||
continue;
|
||||
@ -1933,6 +1939,9 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
|
||||
struct ext4_iloc iloc;
|
||||
int err = 0, rc;
|
||||
|
||||
if (!ext4_handle_valid(handle))
|
||||
return 0;
|
||||
|
||||
lock_super(sb);
|
||||
if (!list_empty(&EXT4_I(inode)->i_orphan))
|
||||
goto out_unlock;
|
||||
@ -1961,7 +1970,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
|
||||
/* Insert this inode at the head of the on-disk orphan list... */
|
||||
NEXT_ORPHAN(inode) = le32_to_cpu(EXT4_SB(sb)->s_es->s_last_orphan);
|
||||
EXT4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);
|
||||
err = ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
|
||||
err = ext4_handle_dirty_metadata(handle, inode, EXT4_SB(sb)->s_sbh);
|
||||
rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
|
||||
if (!err)
|
||||
err = rc;
|
||||
@ -1995,10 +2004,13 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
|
||||
struct list_head *prev;
|
||||
struct ext4_inode_info *ei = EXT4_I(inode);
|
||||
struct ext4_sb_info *sbi;
|
||||
unsigned long ino_next;
|
||||
__u32 ino_next;
|
||||
struct ext4_iloc iloc;
|
||||
int err = 0;
|
||||
|
||||
if (!ext4_handle_valid(handle))
|
||||
return 0;
|
||||
|
||||
lock_super(inode->i_sb);
|
||||
if (list_empty(&ei->i_orphan)) {
|
||||
unlock_super(inode->i_sb);
|
||||
@ -2017,7 +2029,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
|
||||
* transaction handle with which to update the orphan list on
|
||||
* disk, but we still need to remove the inode from the linked
|
||||
* list in memory. */
|
||||
if (!handle)
|
||||
if (sbi->s_journal && !handle)
|
||||
goto out;
|
||||
|
||||
err = ext4_reserve_inode_write(handle, inode, &iloc);
|
||||
@ -2025,19 +2037,19 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
|
||||
goto out_err;
|
||||
|
||||
if (prev == &sbi->s_orphan) {
|
||||
jbd_debug(4, "superblock will point to %lu\n", ino_next);
|
||||
jbd_debug(4, "superblock will point to %u\n", ino_next);
|
||||
BUFFER_TRACE(sbi->s_sbh, "get_write_access");
|
||||
err = ext4_journal_get_write_access(handle, sbi->s_sbh);
|
||||
if (err)
|
||||
goto out_brelse;
|
||||
sbi->s_es->s_last_orphan = cpu_to_le32(ino_next);
|
||||
err = ext4_journal_dirty_metadata(handle, sbi->s_sbh);
|
||||
err = ext4_handle_dirty_metadata(handle, inode, sbi->s_sbh);
|
||||
} else {
|
||||
struct ext4_iloc iloc2;
|
||||
struct inode *i_prev =
|
||||
&list_entry(prev, struct ext4_inode_info, i_orphan)->vfs_inode;
|
||||
|
||||
jbd_debug(4, "orphan inode %lu will point to %lu\n",
|
||||
jbd_debug(4, "orphan inode %lu will point to %u\n",
|
||||
i_prev->i_ino, ino_next);
|
||||
err = ext4_reserve_inode_write(handle, i_prev, &iloc2);
|
||||
if (err)
|
||||
@ -2082,7 +2094,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
goto end_rmdir;
|
||||
|
||||
if (IS_DIRSYNC(dir))
|
||||
handle->h_sync = 1;
|
||||
ext4_handle_sync(handle);
|
||||
|
||||
inode = dentry->d_inode;
|
||||
|
||||
@ -2136,7 +2148,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
|
||||
return PTR_ERR(handle);
|
||||
|
||||
if (IS_DIRSYNC(dir))
|
||||
handle->h_sync = 1;
|
||||
ext4_handle_sync(handle);
|
||||
|
||||
retval = -ENOENT;
|
||||
bh = ext4_find_entry(dir, &dentry->d_name, &de);
|
||||
@ -2193,7 +2205,7 @@ retry:
|
||||
return PTR_ERR(handle);
|
||||
|
||||
if (IS_DIRSYNC(dir))
|
||||
handle->h_sync = 1;
|
||||
ext4_handle_sync(handle);
|
||||
|
||||
inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO);
|
||||
err = PTR_ERR(inode);
|
||||
@ -2256,7 +2268,7 @@ retry:
|
||||
return PTR_ERR(handle);
|
||||
|
||||
if (IS_DIRSYNC(dir))
|
||||
handle->h_sync = 1;
|
||||
ext4_handle_sync(handle);
|
||||
|
||||
inode->i_ctime = ext4_current_time(inode);
|
||||
ext4_inc_count(handle, inode);
|
||||
@ -2305,7 +2317,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
return PTR_ERR(handle);
|
||||
|
||||
if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
|
||||
handle->h_sync = 1;
|
||||
ext4_handle_sync(handle);
|
||||
|
||||
old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de);
|
||||
/*
|
||||
@ -2359,8 +2371,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
new_dir->i_ctime = new_dir->i_mtime =
|
||||
ext4_current_time(new_dir);
|
||||
ext4_mark_inode_dirty(handle, new_dir);
|
||||
BUFFER_TRACE(new_bh, "call ext4_journal_dirty_metadata");
|
||||
ext4_journal_dirty_metadata(handle, new_bh);
|
||||
BUFFER_TRACE(new_bh, "call ext4_handle_dirty_metadata");
|
||||
ext4_handle_dirty_metadata(handle, new_dir, new_bh);
|
||||
brelse(new_bh);
|
||||
new_bh = NULL;
|
||||
}
|
||||
@ -2410,8 +2422,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
BUFFER_TRACE(dir_bh, "get_write_access");
|
||||
ext4_journal_get_write_access(handle, dir_bh);
|
||||
PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino);
|
||||
BUFFER_TRACE(dir_bh, "call ext4_journal_dirty_metadata");
|
||||
ext4_journal_dirty_metadata(handle, dir_bh);
|
||||
BUFFER_TRACE(dir_bh, "call ext4_handle_dirty_metadata");
|
||||
ext4_handle_dirty_metadata(handle, old_dir, dir_bh);
|
||||
ext4_dec_count(handle, old_dir);
|
||||
if (new_inode) {
|
||||
/* checked empty_dir above, can't have another parent,
|
||||
|
Reference in New Issue
Block a user