diff options
Diffstat (limited to 'fs/ext3/namei.c')
-rw-r--r-- | fs/ext3/namei.c | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 3e5edc92aa0b..4db4ffa1edad 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -74,10 +74,6 @@ static struct buffer_head *ext3_append(handle_t *handle, | |||
74 | #define assert(test) J_ASSERT(test) | 74 | #define assert(test) J_ASSERT(test) |
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | #ifndef swap | ||
78 | #define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0) | ||
79 | #endif | ||
80 | |||
81 | #ifdef DX_DEBUG | 77 | #ifdef DX_DEBUG |
82 | #define dxtrace(command) command | 78 | #define dxtrace(command) command |
83 | #else | 79 | #else |
@@ -368,6 +364,8 @@ dx_probe(struct qstr *entry, struct inode *dir, | |||
368 | goto fail; | 364 | goto fail; |
369 | } | 365 | } |
370 | hinfo->hash_version = root->info.hash_version; | 366 | hinfo->hash_version = root->info.hash_version; |
367 | if (hinfo->hash_version <= DX_HASH_TEA) | ||
368 | hinfo->hash_version += EXT3_SB(dir->i_sb)->s_hash_unsigned; | ||
371 | hinfo->seed = EXT3_SB(dir->i_sb)->s_hash_seed; | 369 | hinfo->seed = EXT3_SB(dir->i_sb)->s_hash_seed; |
372 | if (entry) | 370 | if (entry) |
373 | ext3fs_dirhash(entry->name, entry->len, hinfo); | 371 | ext3fs_dirhash(entry->name, entry->len, hinfo); |
@@ -636,6 +634,9 @@ int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, | |||
636 | dir = dir_file->f_path.dentry->d_inode; | 634 | dir = dir_file->f_path.dentry->d_inode; |
637 | if (!(EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) { | 635 | if (!(EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) { |
638 | hinfo.hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version; | 636 | hinfo.hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version; |
637 | if (hinfo.hash_version <= DX_HASH_TEA) | ||
638 | hinfo.hash_version += | ||
639 | EXT3_SB(dir->i_sb)->s_hash_unsigned; | ||
639 | hinfo.seed = EXT3_SB(dir->i_sb)->s_hash_seed; | 640 | hinfo.seed = EXT3_SB(dir->i_sb)->s_hash_seed; |
640 | count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo, | 641 | count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo, |
641 | start_hash, start_minor_hash); | 642 | start_hash, start_minor_hash); |
@@ -1156,9 +1157,9 @@ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, | |||
1156 | u32 hash2; | 1157 | u32 hash2; |
1157 | struct dx_map_entry *map; | 1158 | struct dx_map_entry *map; |
1158 | char *data1 = (*bh)->b_data, *data2; | 1159 | char *data1 = (*bh)->b_data, *data2; |
1159 | unsigned split, move, size, i; | 1160 | unsigned split, move, size; |
1160 | struct ext3_dir_entry_2 *de = NULL, *de2; | 1161 | struct ext3_dir_entry_2 *de = NULL, *de2; |
1161 | int err = 0; | 1162 | int err = 0, i; |
1162 | 1163 | ||
1163 | bh2 = ext3_append (handle, dir, &newblock, &err); | 1164 | bh2 = ext3_append (handle, dir, &newblock, &err); |
1164 | if (!(bh2)) { | 1165 | if (!(bh2)) { |
@@ -1357,7 +1358,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, | |||
1357 | struct fake_dirent *fde; | 1358 | struct fake_dirent *fde; |
1358 | 1359 | ||
1359 | blocksize = dir->i_sb->s_blocksize; | 1360 | blocksize = dir->i_sb->s_blocksize; |
1360 | dxtrace(printk("Creating index\n")); | 1361 | dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino)); |
1361 | retval = ext3_journal_get_write_access(handle, bh); | 1362 | retval = ext3_journal_get_write_access(handle, bh); |
1362 | if (retval) { | 1363 | if (retval) { |
1363 | ext3_std_error(dir->i_sb, retval); | 1364 | ext3_std_error(dir->i_sb, retval); |
@@ -1366,6 +1367,19 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, | |||
1366 | } | 1367 | } |
1367 | root = (struct dx_root *) bh->b_data; | 1368 | root = (struct dx_root *) bh->b_data; |
1368 | 1369 | ||
1370 | /* The 0th block becomes the root, move the dirents out */ | ||
1371 | fde = &root->dotdot; | ||
1372 | de = (struct ext3_dir_entry_2 *)((char *)fde + | ||
1373 | ext3_rec_len_from_disk(fde->rec_len)); | ||
1374 | if ((char *) de >= (((char *) root) + blocksize)) { | ||
1375 | ext3_error(dir->i_sb, __func__, | ||
1376 | "invalid rec_len for '..' in inode %lu", | ||
1377 | dir->i_ino); | ||
1378 | brelse(bh); | ||
1379 | return -EIO; | ||
1380 | } | ||
1381 | len = ((char *) root) + blocksize - (char *) de; | ||
1382 | |||
1369 | bh2 = ext3_append (handle, dir, &block, &retval); | 1383 | bh2 = ext3_append (handle, dir, &block, &retval); |
1370 | if (!(bh2)) { | 1384 | if (!(bh2)) { |
1371 | brelse(bh); | 1385 | brelse(bh); |
@@ -1374,11 +1388,6 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, | |||
1374 | EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; | 1388 | EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; |
1375 | data1 = bh2->b_data; | 1389 | data1 = bh2->b_data; |
1376 | 1390 | ||
1377 | /* The 0th block becomes the root, move the dirents out */ | ||
1378 | fde = &root->dotdot; | ||
1379 | de = (struct ext3_dir_entry_2 *)((char *)fde + | ||
1380 | ext3_rec_len_from_disk(fde->rec_len)); | ||
1381 | len = ((char *) root) + blocksize - (char *) de; | ||
1382 | memcpy (data1, de, len); | 1391 | memcpy (data1, de, len); |
1383 | de = (struct ext3_dir_entry_2 *) data1; | 1392 | de = (struct ext3_dir_entry_2 *) data1; |
1384 | top = data1 + len; | 1393 | top = data1 + len; |
@@ -1398,6 +1407,8 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, | |||
1398 | 1407 | ||
1399 | /* Initialize as for dx_probe */ | 1408 | /* Initialize as for dx_probe */ |
1400 | hinfo.hash_version = root->info.hash_version; | 1409 | hinfo.hash_version = root->info.hash_version; |
1410 | if (hinfo.hash_version <= DX_HASH_TEA) | ||
1411 | hinfo.hash_version += EXT3_SB(dir->i_sb)->s_hash_unsigned; | ||
1401 | hinfo.seed = EXT3_SB(dir->i_sb)->s_hash_seed; | 1412 | hinfo.seed = EXT3_SB(dir->i_sb)->s_hash_seed; |
1402 | ext3fs_dirhash(name, namelen, &hinfo); | 1413 | ext3fs_dirhash(name, namelen, &hinfo); |
1403 | frame = frames; | 1414 | frame = frames; |
@@ -1652,9 +1663,11 @@ static int ext3_add_nondir(handle_t *handle, | |||
1652 | if (!err) { | 1663 | if (!err) { |
1653 | ext3_mark_inode_dirty(handle, inode); | 1664 | ext3_mark_inode_dirty(handle, inode); |
1654 | d_instantiate(dentry, inode); | 1665 | d_instantiate(dentry, inode); |
1666 | unlock_new_inode(inode); | ||
1655 | return 0; | 1667 | return 0; |
1656 | } | 1668 | } |
1657 | drop_nlink(inode); | 1669 | drop_nlink(inode); |
1670 | unlock_new_inode(inode); | ||
1658 | iput(inode); | 1671 | iput(inode); |
1659 | return err; | 1672 | return err; |
1660 | } | 1673 | } |
@@ -1765,6 +1778,7 @@ retry: | |||
1765 | dir_block = ext3_bread (handle, inode, 0, 1, &err); | 1778 | dir_block = ext3_bread (handle, inode, 0, 1, &err); |
1766 | if (!dir_block) { | 1779 | if (!dir_block) { |
1767 | drop_nlink(inode); /* is this nlink == 0? */ | 1780 | drop_nlink(inode); /* is this nlink == 0? */ |
1781 | unlock_new_inode(inode); | ||
1768 | ext3_mark_inode_dirty(handle, inode); | 1782 | ext3_mark_inode_dirty(handle, inode); |
1769 | iput (inode); | 1783 | iput (inode); |
1770 | goto out_stop; | 1784 | goto out_stop; |
@@ -1792,6 +1806,7 @@ retry: | |||
1792 | err = ext3_add_entry (handle, dentry, inode); | 1806 | err = ext3_add_entry (handle, dentry, inode); |
1793 | if (err) { | 1807 | if (err) { |
1794 | inode->i_nlink = 0; | 1808 | inode->i_nlink = 0; |
1809 | unlock_new_inode(inode); | ||
1795 | ext3_mark_inode_dirty(handle, inode); | 1810 | ext3_mark_inode_dirty(handle, inode); |
1796 | iput (inode); | 1811 | iput (inode); |
1797 | goto out_stop; | 1812 | goto out_stop; |
@@ -1800,6 +1815,7 @@ retry: | |||
1800 | ext3_update_dx_flag(dir); | 1815 | ext3_update_dx_flag(dir); |
1801 | ext3_mark_inode_dirty(handle, dir); | 1816 | ext3_mark_inode_dirty(handle, dir); |
1802 | d_instantiate(dentry, inode); | 1817 | d_instantiate(dentry, inode); |
1818 | unlock_new_inode(inode); | ||
1803 | out_stop: | 1819 | out_stop: |
1804 | ext3_journal_stop(handle); | 1820 | ext3_journal_stop(handle); |
1805 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) | 1821 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) |
@@ -2170,10 +2186,10 @@ retry: | |||
2170 | * We have a transaction open. All is sweetness. It also sets | 2186 | * We have a transaction open. All is sweetness. It also sets |
2171 | * i_size in generic_commit_write(). | 2187 | * i_size in generic_commit_write(). |
2172 | */ | 2188 | */ |
2173 | err = __page_symlink(inode, symname, l, | 2189 | err = __page_symlink(inode, symname, l, 1); |
2174 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | ||
2175 | if (err) { | 2190 | if (err) { |
2176 | drop_nlink(inode); | 2191 | drop_nlink(inode); |
2192 | unlock_new_inode(inode); | ||
2177 | ext3_mark_inode_dirty(handle, inode); | 2193 | ext3_mark_inode_dirty(handle, inode); |
2178 | iput (inode); | 2194 | iput (inode); |
2179 | goto out_stop; | 2195 | goto out_stop; |
@@ -2221,7 +2237,14 @@ retry: | |||
2221 | inc_nlink(inode); | 2237 | inc_nlink(inode); |
2222 | atomic_inc(&inode->i_count); | 2238 | atomic_inc(&inode->i_count); |
2223 | 2239 | ||
2224 | err = ext3_add_nondir(handle, dentry, inode); | 2240 | err = ext3_add_entry(handle, dentry, inode); |
2241 | if (!err) { | ||
2242 | ext3_mark_inode_dirty(handle, inode); | ||
2243 | d_instantiate(dentry, inode); | ||
2244 | } else { | ||
2245 | drop_nlink(inode); | ||
2246 | iput(inode); | ||
2247 | } | ||
2225 | ext3_journal_stop(handle); | 2248 | ext3_journal_stop(handle); |
2226 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) | 2249 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) |
2227 | goto retry; | 2250 | goto retry; |