summaryrefslogtreecommitdiff
path: root/fs/ext4/ialloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/ialloc.c')
-rw-r--r--fs/ext4/ialloc.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index b20a1bf866ab..a5831fc536db 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -66,14 +66,16 @@ void ext4_mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
}
-void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate)
+void ext4_end_bitmap_read(struct bio *bio)
{
+ struct buffer_head *bh;
+ bool uptodate = bio_endio_bh(bio, &bh);
+
if (uptodate) {
set_buffer_uptodate(bh);
set_bitmap_uptodate(bh);
}
unlock_buffer(bh);
- put_bh(bh);
}
static int ext4_validate_inode_bitmap(struct super_block *sb,
@@ -252,14 +254,14 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
"nonexistent device\n", __func__, __LINE__);
return;
}
- if (icount_read(inode) > 1) {
- ext4_msg(sb, KERN_ERR, "%s:%d: inode #%lu: count=%d",
+ if (icount_read_once(inode) > 1) {
+ ext4_msg(sb, KERN_ERR, "%s:%d: inode #%llu: count=%d",
__func__, __LINE__, inode->i_ino,
- icount_read(inode));
+ icount_read_once(inode));
return;
}
if (inode->i_nlink) {
- ext4_msg(sb, KERN_ERR, "%s:%d: inode #%lu: nlink=%d\n",
+ ext4_msg(sb, KERN_ERR, "%s:%d: inode #%llu: nlink=%d\n",
__func__, __LINE__, inode->i_ino, inode->i_nlink);
return;
}
@@ -631,7 +633,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
*
* So add our directory's i_ino into the starting point for the hash.
*/
- *group = (*group + parent->i_ino) % ngroups;
+ *group = (*group + (unsigned int)parent->i_ino) % ngroups;
/*
* Use a quadratic hash to find a group with a free inode and some free
@@ -686,6 +688,12 @@ static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino)
if (unlikely(!gdp))
return 0;
+ /* Inode was never used in this filesystem? */
+ if (ext4_has_group_desc_csum(sb) &&
+ (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT) ||
+ ino >= EXT4_INODES_PER_GROUP(sb) - ext4_itable_unused_count(sb, gdp)))
+ return 0;
+
bh = sb_find_get_block(sb, ext4_inode_table(sb, gdp) +
(ino / inodes_per_block));
if (!bh || !buffer_uptodate(bh))
@@ -989,6 +997,8 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap,
err = fscrypt_prepare_new_inode(dir, inode, &encrypt);
if (err)
goto out;
+ if (encrypt)
+ i_flags |= EXT4_ENCRYPT_FL;
}
err = dquot_initialize(inode);
@@ -1275,7 +1285,7 @@ got:
* twice.
*/
err = -EIO;
- ext4_error(sb, "failed to insert inode %lu: doubly allocated?",
+ ext4_error(sb, "failed to insert inode %llu: doubly allocated?",
inode->i_ino);
ext4_mark_group_bitmap_corrupted(sb, group,
EXT4_GROUP_INFO_IBITMAP_CORRUPT);
@@ -1298,6 +1308,8 @@ got:
ei->i_extra_isize = sbi->s_want_extra_isize;
ei->i_inline_off = 0;
if (ext4_has_feature_inline_data(sb) &&
+ /* Encrypted inodes cannot have inline data */
+ !(ei->i_flags & EXT4_ENCRYPT_FL) &&
(!(ei->i_flags & (EXT4_DAX_FL|EXT4_EA_INODE_FL)) || S_ISDIR(mode)))
ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
ret = inode;
@@ -1344,7 +1356,7 @@ got:
goto fail_free_drop;
}
- ext4_debug("allocating inode %lu\n", inode->i_ino);
+ ext4_debug("allocating inode %llu\n", inode->i_ino);
trace_ext4_allocate_inode(inode, dir, mode);
brelse(inode_bitmap_bh);
return ret;