diff options
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r-- | fs/ext4/namei.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 114abe5d2c1d..42f81d285cd5 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -1518,8 +1518,12 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, | |||
1518 | return retval; | 1518 | return retval; |
1519 | 1519 | ||
1520 | if (blocks == 1 && !dx_fallback && | 1520 | if (blocks == 1 && !dx_fallback && |
1521 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) | 1521 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) { |
1522 | return make_indexed_dir(handle, dentry, inode, bh); | 1522 | retval = make_indexed_dir(handle, dentry, inode, bh); |
1523 | if (retval == -ENOSPC) | ||
1524 | brelse(bh); | ||
1525 | return retval; | ||
1526 | } | ||
1523 | brelse(bh); | 1527 | brelse(bh); |
1524 | } | 1528 | } |
1525 | bh = ext4_append(handle, dir, &block, &retval); | 1529 | bh = ext4_append(handle, dir, &block, &retval); |
@@ -1528,7 +1532,10 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, | |||
1528 | de = (struct ext4_dir_entry_2 *) bh->b_data; | 1532 | de = (struct ext4_dir_entry_2 *) bh->b_data; |
1529 | de->inode = 0; | 1533 | de->inode = 0; |
1530 | de->rec_len = ext4_rec_len_to_disk(blocksize, blocksize); | 1534 | de->rec_len = ext4_rec_len_to_disk(blocksize, blocksize); |
1531 | return add_dirent_to_buf(handle, dentry, inode, de, bh); | 1535 | retval = add_dirent_to_buf(handle, dentry, inode, de, bh); |
1536 | if (retval == -ENOSPC) | ||
1537 | brelse(bh); | ||
1538 | return retval; | ||
1532 | } | 1539 | } |
1533 | 1540 | ||
1534 | /* | 1541 | /* |
@@ -1590,9 +1597,9 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry, | |||
1590 | goto cleanup; | 1597 | goto cleanup; |
1591 | node2 = (struct dx_node *)(bh2->b_data); | 1598 | node2 = (struct dx_node *)(bh2->b_data); |
1592 | entries2 = node2->entries; | 1599 | entries2 = node2->entries; |
1600 | memset(&node2->fake, 0, sizeof(struct fake_dirent)); | ||
1593 | node2->fake.rec_len = ext4_rec_len_to_disk(sb->s_blocksize, | 1601 | node2->fake.rec_len = ext4_rec_len_to_disk(sb->s_blocksize, |
1594 | sb->s_blocksize); | 1602 | sb->s_blocksize); |
1595 | node2->fake.inode = 0; | ||
1596 | BUFFER_TRACE(frame->bh, "get_write_access"); | 1603 | BUFFER_TRACE(frame->bh, "get_write_access"); |
1597 | err = ext4_journal_get_write_access(handle, frame->bh); | 1604 | err = ext4_journal_get_write_access(handle, frame->bh); |
1598 | if (err) | 1605 | if (err) |
@@ -1657,7 +1664,8 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry, | |||
1657 | if (!de) | 1664 | if (!de) |
1658 | goto cleanup; | 1665 | goto cleanup; |
1659 | err = add_dirent_to_buf(handle, dentry, inode, de, bh); | 1666 | err = add_dirent_to_buf(handle, dentry, inode, de, bh); |
1660 | bh = NULL; | 1667 | if (err != -ENOSPC) |
1668 | bh = NULL; | ||
1661 | goto cleanup; | 1669 | goto cleanup; |
1662 | 1670 | ||
1663 | journal_error: | 1671 | journal_error: |
@@ -2310,7 +2318,7 @@ static int ext4_link(struct dentry *old_dentry, | |||
2310 | struct inode *inode = old_dentry->d_inode; | 2318 | struct inode *inode = old_dentry->d_inode; |
2311 | int err, retries = 0; | 2319 | int err, retries = 0; |
2312 | 2320 | ||
2313 | if (EXT4_DIR_LINK_MAX(inode)) | 2321 | if (inode->i_nlink >= EXT4_LINK_MAX) |
2314 | return -EMLINK; | 2322 | return -EMLINK; |
2315 | 2323 | ||
2316 | /* | 2324 | /* |
@@ -2413,7 +2421,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
2413 | goto end_rename; | 2421 | goto end_rename; |
2414 | retval = -EMLINK; | 2422 | retval = -EMLINK; |
2415 | if (!new_inode && new_dir != old_dir && | 2423 | if (!new_inode && new_dir != old_dir && |
2416 | new_dir->i_nlink >= EXT4_LINK_MAX) | 2424 | EXT4_DIR_LINK_MAX(new_dir)) |
2417 | goto end_rename; | 2425 | goto end_rename; |
2418 | } | 2426 | } |
2419 | if (!new_bh) { | 2427 | if (!new_bh) { |