===================================================================
--- linux-stage.orig/fs/ext4/super.c
+++ linux-stage/fs/ext4/super.c
-@@ -334,6 +334,8 @@ void ext4_journal_abort_handle(const cha
- jbd2_journal_abort_handle(handle);
- }
-
-+EXPORT_SYMBOL(ext4_journal_abort_handle);
-+
- /* Deal with the reporting of failure conditions on a filesystem such as
- * inconsistencies detected or read IO failures.
- *
-@@ -3529,6 +3531,8 @@ out_fail:
- return ret;
- }
-
-+EXPORT_SYMBOL(ext4_force_commit);
-+
- /*
- * Setup any per-fs journal parameters now. We'll do this both on
- * initial mount, once the journal has been initialised but before we've
-@@ -4642,6 +4646,12 @@ static void __exit exit_ext4_fs(void)
+@@ -4642,6 +4646,11 @@ static void __exit exit_ext4_fs(void)
exit_ext4_system_zone();
}
-+EXPORT_SYMBOL(ext4_xattr_get);
-+EXPORT_SYMBOL(ext4_xattr_set_handle);
+EXPORT_SYMBOL(ext4_bread);
+EXPORT_SYMBOL(ext4_journal_start_sb);
+EXPORT_SYMBOL(__ext4_journal_stop);
++EXPORT_SYMBOL(ext4_force_commit);
+
MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
MODULE_DESCRIPTION("Fourth Extended Filesystem");
* dirent test below. */
if (ext4_rec_len_from_disk(de->rec_len,
- sb->s_blocksize) < EXT4_DIR_REC_LEN(1))
-+ sb->s_blocksize) < __EXT4_DIR_REC_LEN(1))
++ sb->s_blocksize) < __EXT4_DIR_REC_LEN(1))
break;
i += ext4_rec_len_from_disk(de->rec_len,
sb->s_blocksize);
while (*p) {
@@ -452,7 +457,7 @@ int ext4_htree_store_dirent(struct file
- if (ext4_check_dir_entry(dir, NULL, de, bh,
- buf, buf_size, offset))
- return -EIO;
+ if (ext4_check_dir_entry(dir, NULL, de, bh,
+ buf, buf_size, offset))
+ return -EIO;
- nlen = EXT4_DIR_REC_LEN(de->name_len);
+ nlen = EXT4_DIR_REC_LEN(de);
- rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
- de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
- offset += rlen;
+ rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
+ de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
+ offset += rlen;
Index: linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/ext4.h
===================================================================
--- linux-3.10.0-123.13.2.el7.x86_64.orig/fs/ext4/ext4.h
+ __u32 edp_magic; /* EXT4_LUFID_MAGIC */
+ char edp_len; /* size of edp_data in bytes */
+ char edp_data[0]; /* packed array of data */
-+} __attribute__((packed));
++} __packed;
+
+static inline unsigned char *ext4_dentry_get_data(struct super_block *sb,
-+ struct ext4_dentry_param* p)
++ struct ext4_dentry_param *p)
+
+{
+ if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_DIRDATA))
- return ext4_filetype_table[filetype];
+ if (!test_opt(sb, DIRDATA))
-+ return (ext4_filetype_table[fl_index]);
++ return ext4_filetype_table[fl_index];
+
+ return (ext4_filetype_table[fl_index]) |
+ (filetype & EXT4_DIRENT_LUFID);
static struct dx_frame *dx_probe(const struct qstr *d_name,
struct inode *dir,
@@ -504,11 +505,12 @@ ext4_next_entry(struct ext4_dir_entry_2
- */
- struct dx_root_info * dx_get_dx_info(struct ext4_dir_entry_2 *de)
+ */
+ struct dx_root_info *dx_get_dx_info(struct ext4_dir_entry_2 *de)
{
-- /* get dotdot first */
-- de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(1));
+- /* get dotdot first */
+- de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(1));
+ BUG_ON(de->name_len != 1);
+ /* get dotdot first */
+ de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(de));
-- /* dx root info is after dotdot entry */
-- de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(2));
+- /* dx root info is after dotdot entry */
+- de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(2));
+ /* dx root info is after dotdot entry */
+ de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(de));
- return (struct dx_root_info *) de;
+ return (struct dx_root_info *)de;
}
@@ -553,10 +555,16 @@ static inline void dx_set_limit(struct d
((struct dx_countlimit *) entries)->limit = cpu_to_le16(value);
names++;
}
de = ext4_next_entry(de, size);
-@@ -723,6 +731,7 @@ dx_probe(const struct qstr *d_name, stru
+@@ -723,12 +731,15 @@ dx_probe(const struct qstr *d_name, stru
+
entries = (struct dx_entry *) (((char *)info) + info->info_length);
- if (dx_get_limit(entries) != dx_root_limit(dir,
-+ (struct ext4_dir_entry_2*)bh->b_data,
- info->info_length)) {
- ext4_warning(dir->i_sb, "dx entry: limit != root limit");
+- if (dx_get_limit(entries) != dx_root_limit(dir,
+- info->info_length)) {
++ if (dx_get_limit(entries) !=
++ dx_root_limit(dir, (struct ext4_dir_entry_2 *)bh->b_data,
++ info->info_length)) {
+ ext4_warning(dir->i_sb, "dx entry: limit != root limit "
+ "inode #%lu: dx entry: limit %u != root limit %u",
+ dir->i_ino, dx_get_limit(entries),
+- dx_root_limit(dir, info->info_length));
++ dx_root_limit(dir,
++ (struct ext4_dir_entry_2 *)bh->b_data,
++ info->info_length));
brelse(bh);
+ *err = ERR_BAD_DX_DIR;
+ goto fail;
@@ -916,7 +925,7 @@ static int htree_dirblock_to_tree(struct
de = (struct ext4_dir_entry_2 *) bh->b_data;
top = (struct ext4_dir_entry_2 *) ((char *) de +
if (de > to)
memmove(to, de, rec_len);
to->rec_len = ext4_rec_len_to_disk(rec_len, blocksize);
-@@ -1664,14 +1673,15 @@ int ext4_find_dest_de(struct inode *dir,
+@@ -1664,14 +1673,16 @@ int ext4_find_dest_de(struct inode *dir,
struct buffer_head *bh,
void *buf, int buf_size,
const char *name, int namelen,
{
struct ext4_dir_entry_2 *de;
- unsigned short reclen = EXT4_DIR_REC_LEN(namelen);
-+ unsigned short reclen = __EXT4_DIR_REC_LEN(namelen) + (dlen ? *dlen:0);
++ unsigned short reclen = __EXT4_DIR_REC_LEN(namelen) +
++ (dlen ? *dlen : 0);
int nlen, rlen;
unsigned int offset = 0;
char *top;
-+ dlen ? *dlen = 0: 0; /* default set to 0 */
++ dlen ? *dlen = 0 : 0; /* default set to 0 */
de = (struct ext4_dir_entry_2 *)buf;
top = buf + buf_size - reclen;
while ((char *) de <= top) {
+ data = ext4_dentry_get_data(inode->i_sb, (struct ext4_dentry_param *)
+ dentry->d_fsdata);
- if (ext4_has_metadata_csum(inode->i_sb))
+ if (ext4_has_metadata_csum(inode->i_sb))
csum_size = sizeof(struct ext4_dir_entry_tail);
if (!de) {
/* By now the buffer is marked for journaling */
- ext4_insert_dentry(inode, de, blocksize, name, namelen);
-+ /* If we're writing the short form of "dotdot", don't add the data section */
++ /* If writing the short form of "dotdot", don't add the data section */
+ if (dlen == 1)
+ data = NULL;
+ ext4_insert_dentry(inode, de, blocksize, name, namelen, data);
- assert(le16_to_cpu(de->rec_len) >= EXT4_DIR_REC_LEN(2));
+ assert(le16_to_cpu(de->rec_len) >= __EXT4_DIR_REC_LEN(2));
de->name_len = 2;
- strcpy (de->name, "..");
+ strcpy(de->name, "..");
- ext4_set_de_type(dir->i_sb, de, S_IFDIR);
+ if (data != NULL && ext4_get_dirent_data_len(de) >= dlen) {
+ de->name[2] = 0;
+ int dot_reclen = 0;
+
+ if (dotdot_real_len == 10) {
-+ struct tp_block *tpb = (struct tp_block*)inode;
++ struct tp_block *tpb = (struct tp_block *)inode;
+ data1 = tpb->data1;
+ data2 = tpb->data2;
+ inode = tpb->inode;
- strcpy(de->name, "..");
- ext4_set_de_type(inode->i_sb, de, S_IFDIR);
- return ext4_next_entry(de, blocksize);
+ return ext4_next_entry(de, blocksize);
}
@@ -2457,8 +2540,10 @@ struct ext4_dir_entry_2 *ext4_init_dot_d
}
@@ -2508,7 +2597,8 @@ out:
/* Initialize @inode as a subdirectory of @dir, and add the
* "." and ".." entries into the first directory block. */
- int ext4_add_dot_dotdot(handle_t *handle, struct inode * dir,
+ int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
- struct inode *inode)
+ struct inode *inode,
-+ const void *data1, const void *data2)
++ const void *data1, const void *data2)
{
if (IS_ERR(handle))
return PTR_ERR(handle);
err = ext4_find_dest_de(dir, inode, iloc->bh,
inline_start, inline_size,
- name, namelen, &de);
-+ name, namelen, &de, NULL);
++ name, namelen, &de, NULL);
if (err)
return err;
+ if (!test_opt(inode->i_sb, NO_MBCACHE))
+ ce = mb_cache_entry_get(ext4_xattr_cache, bh->b_bdev,
+ bh->b_blocknr);
- BUFFER_TRACE(bh, "get_write_access");
+ BUFFER_TRACE(bh, "get_write_access");
error = ext4_journal_get_write_access(handle, bh);
if (error)
@@ -1037,8 +1040,10 @@ ext4_xattr_block_set(handle_t *handle, s
+ ce = mb_cache_entry_get(ext4_xattr_cache,
+ bs->bh->b_bdev,
+ bs->bh->b_blocknr);
- BUFFER_TRACE(bs->bh, "get_write_access");
+ BUFFER_TRACE(bs->bh, "get_write_access");
error = ext4_journal_get_write_access(handle, bs->bh);
if (error)
@@ -1055,7 +1060,7 @@ ext4_xattr_block_set(handle_t *handle, s
+/* update ".." for hash-indexed directory, split the item "." if necessary */
+static int ext4_update_dotdot(handle_t *handle, struct dentry *dentry,
-+ struct inode *inode)
++ struct inode *inode)
+{
-+ struct inode * dir = dentry->d_parent->d_inode;
-+ struct buffer_head * dir_block;
-+ struct ext4_dir_entry_2 * de;
++ struct inode *dir = dentry->d_parent->d_inode;
++ struct buffer_head *dir_block;
++ struct ext4_dir_entry_2 *de;
+ int len, journal = 0, err = 0;
+
+ if (IS_ERR(handle))
+ else
+ assert(le16_to_cpu(de->rec_len) >= EXT4_DIR_REC_LEN(2));
+ de->name_len = 2;
-+ strcpy (de->name, "..");
++ strcpy(de->name, "..");
+ ext4_set_de_type(dir->i_sb, de, S_IFDIR);
+
+out_journal:
+ err = ext4_handle_dirty_dirent_node(handle, dir, dir_block);
+ ext4_mark_inode_dirty(handle, dir);
+ }
-+ brelse (dir_block);
++ brelse(dir_block);
+
+out:
+ return err;
@@ -4286,10 +4286,10 @@ struct inode *ext4_iget(struct super_blo
EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode);
- if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) {
+ if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) {
- inode->i_version = le32_to_cpu(raw_inode->i_disk_version);
+ ei->i_fs_version = le32_to_cpu(raw_inode->i_disk_version);
if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi))
- inode->i_version |=
+ ei->i_fs_version |=
- (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32;
- }
- }
+ (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32;
+ }
+ }
@@ -4506,11 +4506,11 @@ static int ext4_do_update_inode(handle_t
}
- if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) {
+ if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) {
- raw_inode->i_disk_version = cpu_to_le32(inode->i_version);
+ raw_inode->i_disk_version = cpu_to_le32(ei->i_fs_version);
if (ei->i_extra_isize) {
if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi))
- raw_inode->i_version_hi =
+ raw_inode->i_version_hi =
- cpu_to_le32(inode->i_version >> 32);
+ cpu_to_le32(ei->i_fs_version >> 32);
- raw_inode->i_extra_isize =
- cpu_to_le16(ei->i_extra_isize);
- }
+ raw_inode->i_extra_isize =
+ cpu_to_le16(ei->i_extra_isize);
+ }
Index: linux-3.10.0-123.el7.x86_64/fs/ext4/ialloc.c
===================================================================
--- linux-3.10.0-123.el7.x86_64.orig/fs/ext4/ialloc.c
* Future: use high four bits of block for coalesce-on-delete flags
* Mask them off for now.
*/
-+struct dx_root_info * dx_get_dx_info(struct ext4_dir_entry_2 *de)
++struct dx_root_info *dx_get_dx_info(struct ext4_dir_entry_2 *de)
+{
-+ /* get dotdot first */
-+ de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(1));
++ /* get dotdot first */
++ de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(1));
+
-+ /* dx root info is after dotdot entry */
-+ de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(2));
++ /* dx root info is after dotdot entry */
++ de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(2));
+
-+ return (struct dx_root_info *) de;
++ return (struct dx_root_info *)de;
+}
static inline ext4_lblk_t dx_get_block(struct dx_entry *entry)
unsigned count, indirect;
struct dx_entry *at, *entries, *p, *q, *m;
- struct dx_root *root;
-+ struct dx_root_info * info;
++ struct dx_root_info *info;
struct buffer_head *bh;
struct dx_frame *frame = frame_in;
u32 hash;
- if (root->info.hash_version != DX_HASH_TEA &&
- root->info.hash_version != DX_HASH_HALF_MD4 &&
- root->info.hash_version != DX_HASH_LEGACY) {
+- ext4_warning(dir->i_sb, "Unrecognised inode hash code %d for directory "
+- "#%lu", root->info.hash_version, dir->i_ino);
+
-+ info = dx_get_dx_info((struct ext4_dir_entry_2*)bh->b_data);
++ info = dx_get_dx_info((struct ext4_dir_entry_2 *)bh->b_data);
+ if (info->hash_version != DX_HASH_TEA &&
+ info->hash_version != DX_HASH_HALF_MD4 &&
+ info->hash_version != DX_HASH_LEGACY) {
- ext4_warning(dir->i_sb, "Unrecognised inode hash code %d for directory "
-- "#%lu", root->info.hash_version, dir->i_ino);
-+ "#%lu", info->hash_version, dir->i_ino);
++ ext4_warning(dir->i_sb, "inode #%lu: unrecognised hash code %u",
++ dir->i_ino, info->hash_version);
brelse(bh);
*err = ERR_BAD_DX_DIR;
goto fail;
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;
-@@ -702,27 +704,26 @@ dx_probe(const struct qstr *d_name, stru
+@@ -702,28 +704,33 @@ dx_probe(const struct qstr *d_name, stru
ext4fs_dirhash(d_name->name, d_name->len, hinfo);
hash = hinfo->hash;
- if (root->info.unused_flags & 1) {
-+ if (info->unused_flags & 1) {
- ext4_warning(dir->i_sb, "Unimplemented inode hash flags: %#06x",
+- ext4_warning(dir->i_sb, "Unimplemented inode hash flags: %#06x",
- root->info.unused_flags);
-+ info->unused_flags);
++ if (info->unused_flags & 1) {
++ ext4_warning(dir->i_sb,
++ "inode #%lu: unimplemented hash flags: %#06x",
++ dir->i_ino, info->unused_flags);
brelse(bh);
*err = ERR_BAD_DX_DIR;
goto fail;
}
- if ((indirect = root->info.indirect_levels) > 1) {
-+ if ((indirect = info->indirect_levels) > 1) {
- ext4_warning(dir->i_sb, "Unimplemented inode hash depth: %#06x",
+- ext4_warning(dir->i_sb, "Unimplemented inode hash depth: %#06x",
- root->info.indirect_levels);
-+ info->indirect_levels);
++ indirect = info->indirect_levels;
++ if (indirect > 1) {
++ ext4_warning(dir->i_sb,
++ "inode #%lu: unimplemented hash depth %u",
++ dir->i_ino, info->indirect_levels);
brelse(bh);
*err = ERR_BAD_DX_DIR;
goto fail;
- entries = (struct dx_entry *) (((char *)&root->info) +
- root->info.info_length);
-+ entries = (struct dx_entry *) (((char *)info) + info->info_length);
++ entries = (struct dx_entry *)(((char *)info) + info->info_length);
if (dx_get_limit(entries) != dx_root_limit(dir,
- root->info.info_length)) {
+- ext4_warning(dir->i_sb, "dx entry: limit != root limit");
+ info->info_length)) {
- ext4_warning(dir->i_sb, "dx entry: limit != root limit");
++ ext4_warning(dir->i_sb, "dx entry: limit != root limit "
++ "inode #%lu: dx entry: limit %u != root limit %u",
++ dir->i_ino, dx_get_limit(entries),
++ dx_root_limit(dir, info->info_length));
brelse(bh);
*err = ERR_BAD_DX_DIR;
+ goto fail;
@@ -807,10 +808,12 @@ fail:
static void dx_release (struct dx_frame *frames)
return;
- if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
-+ info = dx_get_dx_info((struct ext4_dir_entry_2*)frames[0].bh->b_data);
++ info = dx_get_dx_info((struct ext4_dir_entry_2 *)frames[0].bh->b_data);
+ if (info->indirect_levels)
brelse(frames[1].bh);
brelse(frames[0].bh);
}
- root = (struct dx_root *) bh->b_data;
+
-+ dot_de = (struct ext4_dir_entry_2 *) bh->b_data;
++ dot_de = (struct ext4_dir_entry_2 *)bh->b_data;
+ dotdot_de = ext4_next_entry(dot_de, blocksize);
/* The 0th block becomes the root, move the dirents out */
- if ((char *) de >= (((char *) root) + blocksize)) {
+ de = (struct ext4_dir_entry_2 *)((char *)dotdot_de +
+ ext4_rec_len_from_disk(dotdot_de->rec_len, blocksize));
-+ if ((char *) de >= (((char *) dot_de) + blocksize)) {
++ if ((char *)de >= (((char *)dot_de) + blocksize)) {
EXT4_ERROR_INODE(dir, "invalid rec_len for '..'");
brelse(bh);
return -EIO;
}
- len = ((char *) root) + (blocksize - csum_size) - (char *) de;
-+ len = ((char *) dot_de) + (blocksize - csum_size) - (char *) de;
++ len = ((char *)dot_de) + (blocksize - csum_size) - (char *)de;
/* Allocate new block for the 0th block's dirents */
bh2 = ext4_append(handle, dir, &block);
-@@ -1850,19 +1853,23 @@ static int make_indexed_dir(handle_t *ha
+@@ -1850,19 +1853,24 @@ static int make_indexed_dir(handle_t *ha
}
/* Initialize the root; the dot dirents already exist */
- root->info.info_length = sizeof(root->info);
- root->info.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
- entries = root->entries;
-+ dotdot_de->rec_len = ext4_rec_len_to_disk(blocksize -
-+ le16_to_cpu(dot_de->rec_len), blocksize);
++ dotdot_de->rec_len =
++ ext4_rec_len_to_disk(blocksize - le16_to_cpu(dot_de->rec_len),
++ blocksize);
+
+ /* initialize hashing info */
+ dx_info = dx_get_dx_info(dot_de);
-+ memset (dx_info, 0, sizeof(*dx_info));
++ memset(dx_info, 0, sizeof(*dx_info));
+ dx_info->info_length = sizeof(*dx_info);
+ dx_info->hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
+
goto journal_error;
brelse (bh2);
} else {
-+ struct dx_root_info * info;
++ struct dx_root_info *info;
dxtrace(printk(KERN_DEBUG
"Creating second level index...\n"));
memcpy((char *) entries2, (char *) entries,
dx_set_count(entries, 1);
dx_set_block(entries + 0, newblock);
- ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
-+ info = dx_get_dx_info((struct ext4_dir_entry_2*)
-+ frames[0].bh->b_data);
++ info = dx_get_dx_info((struct ext4_dir_entry_2 *)
++ frames[0].bh->b_data);
+ info->indirect_levels = 1;
/* Add new access path frame */
bh = ext4_read_dirblock(dir, 0, INDEX);
if (IS_ERR(bh)) {
*err = PTR_ERR(bh);
-@@ -714,9 +721,16 @@ dx_probe(const struct qstr *d_name, stru
- goto fail;
+@@ -714,10 +721,15 @@ dx_probe(const struct qstr *d_name, stru
}
-- if ((indirect = info->indirect_levels) > 1) {
-- ext4_warning(dir->i_sb, "Unimplemented inode hash depth: %#06x",
-- info->indirect_levels);
-+ indirect = info->indirect_levels;
+ indirect = info->indirect_levels;
+- if (indirect > 1) {
+- ext4_warning(dir->i_sb,
+- "inode #%lu: unimplemented hash depth %u",
+- dir->i_ino, info->indirect_levels);
+ if (indirect >= ext4_dir_htree_level(dir->i_sb)) {
+ ext4_warning(dir->i_sb,
+ "inode #%lu: comm %s: htree depth %#06x exceed max depth %u",
if (frames[0].bh == NULL)
return;
- info = dx_get_dx_info((struct ext4_dir_entry_2*)frames[0].bh->b_data);
+ info = dx_get_dx_info((struct ext4_dir_entry_2 *)frames[0].bh->b_data);
- if (info->indirect_levels)
- brelse(frames[1].bh);
- brelse(frames[0].bh);
+ goto cleanup;
+ }
} else {
- struct dx_root_info * info;
+ struct dx_root_info *info;
- dxtrace(printk(KERN_DEBUG
- "Creating second level index...\n"));
- memcpy((char *) entries2, (char *) entries,
@@ -2224,21 +2267,14 @@ static int ext4_dx_add_entry(handle_t *h
dx_set_block(entries + 0, newblock);
info = dx_get_dx_info((struct ext4_dir_entry_2*)
- frames[0].bh->b_data);
+ frames[0].bh->b_data);
- info->indirect_levels = 1;
-
- /* Add new access path frame */
--- linux-3.10.0-123.13.2.el7.x86_64.orig/fs/ext4/inode.c
+++ linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/inode.c
@@ -133,8 +183,6 @@ void ext4_evict_inode(struct inode *inod
- unsigned int length);
+ unsigned int length);
static int __ext4_journalled_writepage(struct page *page, unsigned int len);
static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh);
-static int ext4_meta_trans_blocks(struct inode *inode, int lblocks,
*/
-static int ext4_meta_trans_blocks(struct inode *inode, int lblocks,
+int ext4_meta_trans_blocks(struct inode *inode, int lblocks,
- int pextents)
+ int pextents)
{
ext4_group_t groups, ngroups = ext4_get_groups_count(inode->i_sb);
int gdpblocks;
size_t offs = le16_to_cpu(last->e_value_offs);
if (offs < *min_offs)
*min_offs = offs;
-@@ -577,16 +693,171 @@ static size_t ext4_xattr_free_space(stru
+@@ -577,16 +693,172 @@ static size_t ext4_xattr_free_space(stru
return (*min_offs - ((void *)last - base) - sizeof(__u32));
}
+ map.m_lblk = block += ret;
+ map.m_len = max_blocks -= ret;
+
-+ ret = ext4_map_blocks(handle, ea_inode, &map, EXT4_GET_BLOCKS_CREATE);
++ ret = ext4_map_blocks(handle, ea_inode, &map,
++ EXT4_GET_BLOCKS_CREATE);
+ if (ret <= 0) {
+ ext4_mark_inode_dirty(handle, ea_inode);
+ if (ret == -ENOSPC &&
+ return -ENOMEM;
+ memcpy(new_array, *lea_ino_array,
+ offsetof(struct ext4_xattr_ino_array,
-+ xia_inodes[count]));
++ xia_inodes[count]));
+ kfree(*lea_ino_array);
+ *lea_ino_array = new_array;
+ }
===================================================================
--- linux-3.10.9-200.fc17.x86_64.orig/fs/ext4/namei.c
+++ linux-3.10.9-200.fc17.x86_64/fs/ext4/namei.c
-@@ -1438,6 +1438,32 @@ static struct dentry *ext4_lookup(struct
+@@ -1438,6 +1438,33 @@ static struct dentry *ext4_lookup(struct
return ERR_PTR(-EIO);
}
}
+ /* ".." shouldn't go into dcache to preserve dcache hierarchy
+ * otherwise we'll get parent being a child of actual child.
+ * see bug 10458 for details -bzzz */
-+ if (inode && (dentry->d_name.name[0] == '.' && (dentry->d_name.len == 1 ||
-+ (dentry->d_name.len == 2 && dentry->d_name.name[1] == '.')))) {
++ if (inode && (dentry->d_name.name[0] == '.' &&
++ (dentry->d_name.len == 1 || (dentry->d_name.len == 2 &&
++ dentry->d_name.name[1] == '.')))) {
+ struct dentry *goal = NULL;
+
+ /* first, look for an existing dentry - any one is good */
@@ -2476,8 +2476,11 @@ static ssize_t sbi_ui_show(struct ext4_a
struct ext4_sb_info *sbi, char *buf)
{
- unsigned int *ui = (unsigned int *) (((char *) sbi) + a->u.offset);
+ unsigned int *ui = (unsigned int *) (((char *) sbi) + a->u.offset);
+ unsigned int v = *ui;
- return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
- grp->bb_free);
- set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
+ struct ext4_group_desc *gdp;
-+ gdp = ext4_get_group_desc (sb, group, NULL);
++ gdp = ext4_get_group_desc(sb, group, NULL);
+ ext4_error(sb, "group %lu: %u blocks in bitmap, %u in bb, "
+ "%u in gd, %lu pa's\n", (long unsigned int)group,
+ free, grp->bb_free, ext4_free_group_clusters(sb, gdp),
+ int err;
int len;
-+ gdp = ext4_get_group_desc (sb, group, NULL);
++ gdp = ext4_get_group_desc(sb, group, NULL);
+ if (gdp == NULL)
+ return -EIO;
+
BUG_ON(groupnr != group);
ext4_set_bits(bitmap, start, len);
preallocated += len;
-+ count ++;
++ count++;
+ }
+ if (count + skip != grp->bb_prealloc_nr) {
+ ext4_error(sb, "lost preallocations: "
--- linux-3.10.0-123.13.2.el7.x86_64.orig/fs/ext4/mballoc.c
+++ linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/mballoc.c
@@ -5281,7 +5281,6 @@ out:
- void *buddy, void *bitmap, ext4_group_t group)
+ void *buddy, void *bitmap, ext4_group_t group)
{
- struct ext4_group_info *grp = ext4_get_group_info(sb, group);
+ struct ext4_group_info *grp = ext4_get_group_info(sb, group);
- struct ext4_sb_info *sbi = EXT4_SB(sb);
- ext4_grpblk_t max = EXT4_CLUSTERS_PER_GROUP(sb);
- ext4_grpblk_t i = 0;
- ext4_grpblk_t first;
+ ext4_grpblk_t max = EXT4_CLUSTERS_PER_GROUP(sb);
+ ext4_grpblk_t i = 0;
+ ext4_grpblk_t first;
static inline struct timespec ext4_current_time(struct inode *inode)
{
+ if (IS_NOCMTIME(inode))
-+ return inode->i_ctime;
++ return inode->i_ctime;
return (inode->i_sb->s_time_gran < NSEC_PER_SEC) ?
current_fs_time(inode->i_sb) : CURRENT_TIME_SEC;
}
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
+extern struct inode *ext4_create_inode(handle_t *handle,
-+ struct inode * dir, int mode);
++ struct inode *dir, int mode);
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
-+ struct ext4_dir_entry_2 * de_del,
-+ struct buffer_head * bh);
++ struct ext4_dir_entry_2 *de_del,
++ struct buffer_head *bh);
+extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
+ struct inode *inode);
extern int search_dir(struct buffer_head *bh,
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
-+struct inode * ext4_create_inode(handle_t *handle, struct inode * dir, int mode)
++struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode)
+{
+ struct inode *inode;
+
+/* Initialize @inode as a subdirectory of @dir, and add the
+ * "." and ".." entries into the first directory block. */
-+int ext4_add_dot_dotdot(handle_t *handle, struct inode * dir,
++int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
+ struct inode *inode)
+{
+ if (IS_ERR(handle))
unsigned count, indirect;
- struct dx_entry *at, *entries, *p, *q, *m;
+ struct dx_entry *at, *entries, *p, *q, *m, *dx = NULL;
- struct dx_root_info * info;
+ struct dx_root_info *info;
struct buffer_head *bh;
struct dx_frame *frame = frame_in;
@@ -750,8 +980,15 @@ dx_probe(const struct qstr *d_name, stru
/*
* The routine scans buddy structures (not bitmap!) from given order
* to max order and tries to find big enough chunk to satisfy the req
-@@ -2263,6 +2282,86 @@ static const struct seq_operations ext4_
+@@ -2263,6 +2282,91 @@ static const struct seq_operations ext4_
.show = ext4_mb_seq_groups_show,
};
+ cur = str;
+ end = str + cnt;
+ while (cur < end) {
-+ while ((cur < end) && (*cur == ' ')) cur++;
-+ value = simple_strtol(cur, &cur, 0);
++ int rc;
++ while ((cur < end) && (*cur == ' '))
++ cur++;
++ rc = kstrtol(cur, 0, &value);
++ if (rc != 0)
++ return -EINVAL;
+ if (value == 0)
+ break;
+ if (value <= prev)
+ cur = str;
+ end = str + cnt;
+ while (cur < end && i < num) {
-+ while ((cur < end) && (*cur == ' ')) cur++;
++ while (cur < end && *cur == ' ')
++ cur++;
+ value = simple_strtol(cur, &cur, 0);
+ ext4_mb_prealloc_table_add(sbi, value);
+ i++;
+
+static int mb_prealloc_table_seq_show(struct seq_file *m, void *v)
+{
-+ struct ext4_sb_info *sbi = EXT4_SB(m->private);
++ struct ext4_sb_info *sbi = EXT4_SB(m->private);
+ int i;
+
+ for (i = 0; i < sbi->s_mb_prealloc_table_size; i++)
+ return single_open(file, mb_prealloc_table_seq_show, PDE_DATA(inode));
+}
+
-+struct file_operations ext4_mb_prealloc_seq_fops = {
++static const struct file_operations ext4_mb_prealloc_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = mb_prealloc_table_seq_open,
+ .read = seq_read,
===================================================================
--- linux-3.10.0-123.el7.x86_64.orig/fs/ext4/inode.c
+++ linux-3.10.0-123.el7.x86_64/fs/ext4/inode.c
-@@ -2476,6 +2476,10 @@ static int ext4_da_writepages(struct add
+@@ -2476,6 +2476,9 @@ static int ext4_da_writepages(struct add
if (unlikely(sbi->s_mount_flags & EXT4_MF_FS_ABORTED))
return -EROFS;
-+ if (wbc->nr_to_write < sbi->s_mb_small_req) {
++ if (wbc->nr_to_write < sbi->s_mb_small_req)
+ wbc->nr_to_write = sbi->s_mb_small_req;
-+ }
+
if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
range_whole = 1;
void ext4_block_bitmap_set(struct super_block *sb,
struct ext4_group_desc *bg, ext4_fsblk_t blk)
-@@ -386,6 +387,7 @@ void ext4_journal_abort_handle(const cha
-
- jbd2_journal_abort_handle(handle);
- }
-+EXPORT_SYMBOL(ext4_journal_abort_handle);
-
- static void __save_error_info(struct super_block *sb, const char *func,
- unsigned int line)
@@ -4280,6 +4282,7 @@ int ext4_force_commit(struct super_block
return ret;
static void ext4_write_super(struct super_block *sb)
{
-@@ -5210,6 +5213,12 @@ static void __exit ext4_exit_fs(void)
+@@ -5210,6 +5213,10 @@ static void __exit ext4_exit_fs(void)
ext4_exit_pageio();
}
-+EXPORT_SYMBOL(ext4_xattr_get);
-+EXPORT_SYMBOL(ext4_xattr_set_handle);
+EXPORT_SYMBOL(ext4_bread);
+EXPORT_SYMBOL(ext4_journal_start_sb);
+EXPORT_SYMBOL(__ext4_journal_stop);