diff options
Diffstat (limited to 'fs/ext3/namei.c')
-rw-r--r-- | fs/ext3/namei.c | 237 |
1 files changed, 153 insertions, 84 deletions
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 2b35ddb70d65..34b6d9bfc48a 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -858,6 +858,7 @@ static struct buffer_head *ext3_find_entry(struct inode *dir, | |||
858 | struct buffer_head * bh_use[NAMEI_RA_SIZE]; | 858 | struct buffer_head * bh_use[NAMEI_RA_SIZE]; |
859 | struct buffer_head * bh, *ret = NULL; | 859 | struct buffer_head * bh, *ret = NULL; |
860 | unsigned long start, block, b; | 860 | unsigned long start, block, b; |
861 | const u8 *name = entry->name; | ||
861 | int ra_max = 0; /* Number of bh's in the readahead | 862 | int ra_max = 0; /* Number of bh's in the readahead |
862 | buffer, bh_use[] */ | 863 | buffer, bh_use[] */ |
863 | int ra_ptr = 0; /* Current index into readahead | 864 | int ra_ptr = 0; /* Current index into readahead |
@@ -871,6 +872,16 @@ static struct buffer_head *ext3_find_entry(struct inode *dir, | |||
871 | namelen = entry->len; | 872 | namelen = entry->len; |
872 | if (namelen > EXT3_NAME_LEN) | 873 | if (namelen > EXT3_NAME_LEN) |
873 | return NULL; | 874 | return NULL; |
875 | if ((namelen <= 2) && (name[0] == '.') && | ||
876 | (name[1] == '.' || name[1] == 0)) { | ||
877 | /* | ||
878 | * "." or ".." will only be in the first block | ||
879 | * NFS may look up ".."; "." should be handled by the VFS | ||
880 | */ | ||
881 | block = start = 0; | ||
882 | nblocks = 1; | ||
883 | goto restart; | ||
884 | } | ||
874 | if (is_dx(dir)) { | 885 | if (is_dx(dir)) { |
875 | bh = ext3_dx_find_entry(dir, entry, res_dir, &err); | 886 | bh = ext3_dx_find_entry(dir, entry, res_dir, &err); |
876 | /* | 887 | /* |
@@ -961,55 +972,35 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir, | |||
961 | struct qstr *entry, struct ext3_dir_entry_2 **res_dir, | 972 | struct qstr *entry, struct ext3_dir_entry_2 **res_dir, |
962 | int *err) | 973 | int *err) |
963 | { | 974 | { |
964 | struct super_block * sb; | 975 | struct super_block *sb = dir->i_sb; |
965 | struct dx_hash_info hinfo; | 976 | struct dx_hash_info hinfo; |
966 | u32 hash; | ||
967 | struct dx_frame frames[2], *frame; | 977 | struct dx_frame frames[2], *frame; |
968 | struct ext3_dir_entry_2 *de, *top; | ||
969 | struct buffer_head *bh; | 978 | struct buffer_head *bh; |
970 | unsigned long block; | 979 | unsigned long block; |
971 | int retval; | 980 | int retval; |
972 | int namelen = entry->len; | ||
973 | const u8 *name = entry->name; | ||
974 | 981 | ||
975 | sb = dir->i_sb; | 982 | if (!(frame = dx_probe(entry, dir, &hinfo, frames, err))) |
976 | /* NFS may look up ".." - look at dx_root directory block */ | 983 | return NULL; |
977 | if (namelen > 2 || name[0] != '.'|| (namelen == 2 && name[1] != '.')) { | ||
978 | if (!(frame = dx_probe(entry, dir, &hinfo, frames, err))) | ||
979 | return NULL; | ||
980 | } else { | ||
981 | frame = frames; | ||
982 | frame->bh = NULL; /* for dx_release() */ | ||
983 | frame->at = (struct dx_entry *)frames; /* hack for zero entry*/ | ||
984 | dx_set_block(frame->at, 0); /* dx_root block is 0 */ | ||
985 | } | ||
986 | hash = hinfo.hash; | ||
987 | do { | 984 | do { |
988 | block = dx_get_block(frame->at); | 985 | block = dx_get_block(frame->at); |
989 | if (!(bh = ext3_bread (NULL,dir, block, 0, err))) | 986 | if (!(bh = ext3_bread (NULL,dir, block, 0, err))) |
990 | goto errout; | 987 | goto errout; |
991 | de = (struct ext3_dir_entry_2 *) bh->b_data; | ||
992 | top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize - | ||
993 | EXT3_DIR_REC_LEN(0)); | ||
994 | for (; de < top; de = ext3_next_entry(de)) { | ||
995 | int off = (block << EXT3_BLOCK_SIZE_BITS(sb)) | ||
996 | + ((char *) de - bh->b_data); | ||
997 | |||
998 | if (!ext3_check_dir_entry(__func__, dir, de, bh, off)) { | ||
999 | brelse(bh); | ||
1000 | *err = ERR_BAD_DX_DIR; | ||
1001 | goto errout; | ||
1002 | } | ||
1003 | 988 | ||
1004 | if (ext3_match(namelen, name, de)) { | 989 | retval = search_dirblock(bh, dir, entry, |
1005 | *res_dir = de; | 990 | block << EXT3_BLOCK_SIZE_BITS(sb), |
1006 | dx_release(frames); | 991 | res_dir); |
1007 | return bh; | 992 | if (retval == 1) { |
1008 | } | 993 | dx_release(frames); |
994 | return bh; | ||
1009 | } | 995 | } |
1010 | brelse (bh); | 996 | brelse(bh); |
997 | if (retval == -1) { | ||
998 | *err = ERR_BAD_DX_DIR; | ||
999 | goto errout; | ||
1000 | } | ||
1001 | |||
1011 | /* Check to see if we should continue to search */ | 1002 | /* Check to see if we should continue to search */ |
1012 | retval = ext3_htree_next_block(dir, hash, frame, | 1003 | retval = ext3_htree_next_block(dir, hinfo.hash, frame, |
1013 | frames, NULL); | 1004 | frames, NULL); |
1014 | if (retval < 0) { | 1005 | if (retval < 0) { |
1015 | ext3_warning(sb, __func__, | 1006 | ext3_warning(sb, __func__, |
@@ -1047,7 +1038,7 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str | |||
1047 | return ERR_PTR(-EIO); | 1038 | return ERR_PTR(-EIO); |
1048 | } | 1039 | } |
1049 | inode = ext3_iget(dir->i_sb, ino); | 1040 | inode = ext3_iget(dir->i_sb, ino); |
1050 | if (unlikely(IS_ERR(inode))) { | 1041 | if (IS_ERR(inode)) { |
1051 | if (PTR_ERR(inode) == -ESTALE) { | 1042 | if (PTR_ERR(inode) == -ESTALE) { |
1052 | ext3_error(dir->i_sb, __func__, | 1043 | ext3_error(dir->i_sb, __func__, |
1053 | "deleted inode referenced: %lu", | 1044 | "deleted inode referenced: %lu", |
@@ -1425,10 +1416,19 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, | |||
1425 | frame->at = entries; | 1416 | frame->at = entries; |
1426 | frame->bh = bh; | 1417 | frame->bh = bh; |
1427 | bh = bh2; | 1418 | bh = bh2; |
1419 | /* | ||
1420 | * Mark buffers dirty here so that if do_split() fails we write a | ||
1421 | * consistent set of buffers to disk. | ||
1422 | */ | ||
1423 | ext3_journal_dirty_metadata(handle, frame->bh); | ||
1424 | ext3_journal_dirty_metadata(handle, bh); | ||
1428 | de = do_split(handle,dir, &bh, frame, &hinfo, &retval); | 1425 | de = do_split(handle,dir, &bh, frame, &hinfo, &retval); |
1429 | dx_release (frames); | 1426 | if (!de) { |
1430 | if (!(de)) | 1427 | ext3_mark_inode_dirty(handle, dir); |
1428 | dx_release(frames); | ||
1431 | return retval; | 1429 | return retval; |
1430 | } | ||
1431 | dx_release(frames); | ||
1432 | 1432 | ||
1433 | return add_dirent_to_buf(handle, dentry, inode, de, bh); | 1433 | return add_dirent_to_buf(handle, dentry, inode, de, bh); |
1434 | } | 1434 | } |
@@ -1549,8 +1549,8 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, | |||
1549 | goto cleanup; | 1549 | goto cleanup; |
1550 | node2 = (struct dx_node *)(bh2->b_data); | 1550 | node2 = (struct dx_node *)(bh2->b_data); |
1551 | entries2 = node2->entries; | 1551 | entries2 = node2->entries; |
1552 | memset(&node2->fake, 0, sizeof(struct fake_dirent)); | ||
1552 | node2->fake.rec_len = ext3_rec_len_to_disk(sb->s_blocksize); | 1553 | node2->fake.rec_len = ext3_rec_len_to_disk(sb->s_blocksize); |
1553 | node2->fake.inode = 0; | ||
1554 | BUFFER_TRACE(frame->bh, "get_write_access"); | 1554 | BUFFER_TRACE(frame->bh, "get_write_access"); |
1555 | err = ext3_journal_get_write_access(handle, frame->bh); | 1555 | err = ext3_journal_get_write_access(handle, frame->bh); |
1556 | if (err) | 1556 | if (err) |
@@ -1607,7 +1607,9 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, | |||
1607 | if (err) | 1607 | if (err) |
1608 | goto journal_error; | 1608 | goto journal_error; |
1609 | } | 1609 | } |
1610 | ext3_journal_dirty_metadata(handle, frames[0].bh); | 1610 | err = ext3_journal_dirty_metadata(handle, frames[0].bh); |
1611 | if (err) | ||
1612 | goto journal_error; | ||
1611 | } | 1613 | } |
1612 | de = do_split(handle, dir, &bh, frame, &hinfo, &err); | 1614 | de = do_split(handle, dir, &bh, frame, &hinfo, &err); |
1613 | if (!de) | 1615 | if (!de) |
@@ -1644,8 +1646,13 @@ static int ext3_delete_entry (handle_t *handle, | |||
1644 | if (!ext3_check_dir_entry("ext3_delete_entry", dir, de, bh, i)) | 1646 | if (!ext3_check_dir_entry("ext3_delete_entry", dir, de, bh, i)) |
1645 | return -EIO; | 1647 | return -EIO; |
1646 | if (de == de_del) { | 1648 | if (de == de_del) { |
1649 | int err; | ||
1650 | |||
1647 | BUFFER_TRACE(bh, "get_write_access"); | 1651 | BUFFER_TRACE(bh, "get_write_access"); |
1648 | ext3_journal_get_write_access(handle, bh); | 1652 | err = ext3_journal_get_write_access(handle, bh); |
1653 | if (err) | ||
1654 | goto journal_error; | ||
1655 | |||
1649 | if (pde) | 1656 | if (pde) |
1650 | pde->rec_len = ext3_rec_len_to_disk( | 1657 | pde->rec_len = ext3_rec_len_to_disk( |
1651 | ext3_rec_len_from_disk(pde->rec_len) + | 1658 | ext3_rec_len_from_disk(pde->rec_len) + |
@@ -1654,7 +1661,12 @@ static int ext3_delete_entry (handle_t *handle, | |||
1654 | de->inode = 0; | 1661 | de->inode = 0; |
1655 | dir->i_version++; | 1662 | dir->i_version++; |
1656 | BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); | 1663 | BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); |
1657 | ext3_journal_dirty_metadata(handle, bh); | 1664 | err = ext3_journal_dirty_metadata(handle, bh); |
1665 | if (err) { | ||
1666 | journal_error: | ||
1667 | ext3_std_error(dir->i_sb, err); | ||
1668 | return err; | ||
1669 | } | ||
1658 | return 0; | 1670 | return 0; |
1659 | } | 1671 | } |
1660 | i += ext3_rec_len_from_disk(de->rec_len); | 1672 | i += ext3_rec_len_from_disk(de->rec_len); |
@@ -1707,7 +1719,7 @@ retry: | |||
1707 | if (IS_DIRSYNC(dir)) | 1719 | if (IS_DIRSYNC(dir)) |
1708 | handle->h_sync = 1; | 1720 | handle->h_sync = 1; |
1709 | 1721 | ||
1710 | inode = ext3_new_inode (handle, dir, mode); | 1722 | inode = ext3_new_inode (handle, dir, &dentry->d_name, mode); |
1711 | err = PTR_ERR(inode); | 1723 | err = PTR_ERR(inode); |
1712 | if (!IS_ERR(inode)) { | 1724 | if (!IS_ERR(inode)) { |
1713 | inode->i_op = &ext3_file_inode_operations; | 1725 | inode->i_op = &ext3_file_inode_operations; |
@@ -1743,7 +1755,7 @@ retry: | |||
1743 | if (IS_DIRSYNC(dir)) | 1755 | if (IS_DIRSYNC(dir)) |
1744 | handle->h_sync = 1; | 1756 | handle->h_sync = 1; |
1745 | 1757 | ||
1746 | inode = ext3_new_inode (handle, dir, mode); | 1758 | inode = ext3_new_inode (handle, dir, &dentry->d_name, mode); |
1747 | err = PTR_ERR(inode); | 1759 | err = PTR_ERR(inode); |
1748 | if (!IS_ERR(inode)) { | 1760 | if (!IS_ERR(inode)) { |
1749 | init_special_inode(inode, inode->i_mode, rdev); | 1761 | init_special_inode(inode, inode->i_mode, rdev); |
@@ -1762,7 +1774,7 @@ static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
1762 | { | 1774 | { |
1763 | handle_t *handle; | 1775 | handle_t *handle; |
1764 | struct inode * inode; | 1776 | struct inode * inode; |
1765 | struct buffer_head * dir_block; | 1777 | struct buffer_head * dir_block = NULL; |
1766 | struct ext3_dir_entry_2 * de; | 1778 | struct ext3_dir_entry_2 * de; |
1767 | int err, retries = 0; | 1779 | int err, retries = 0; |
1768 | 1780 | ||
@@ -1781,7 +1793,7 @@ retry: | |||
1781 | if (IS_DIRSYNC(dir)) | 1793 | if (IS_DIRSYNC(dir)) |
1782 | handle->h_sync = 1; | 1794 | handle->h_sync = 1; |
1783 | 1795 | ||
1784 | inode = ext3_new_inode (handle, dir, S_IFDIR | mode); | 1796 | inode = ext3_new_inode (handle, dir, &dentry->d_name, S_IFDIR | mode); |
1785 | err = PTR_ERR(inode); | 1797 | err = PTR_ERR(inode); |
1786 | if (IS_ERR(inode)) | 1798 | if (IS_ERR(inode)) |
1787 | goto out_stop; | 1799 | goto out_stop; |
@@ -1790,15 +1802,14 @@ retry: | |||
1790 | inode->i_fop = &ext3_dir_operations; | 1802 | inode->i_fop = &ext3_dir_operations; |
1791 | inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; | 1803 | inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; |
1792 | dir_block = ext3_bread (handle, inode, 0, 1, &err); | 1804 | dir_block = ext3_bread (handle, inode, 0, 1, &err); |
1793 | if (!dir_block) { | 1805 | if (!dir_block) |
1794 | drop_nlink(inode); /* is this nlink == 0? */ | 1806 | goto out_clear_inode; |
1795 | unlock_new_inode(inode); | 1807 | |
1796 | ext3_mark_inode_dirty(handle, inode); | ||
1797 | iput (inode); | ||
1798 | goto out_stop; | ||
1799 | } | ||
1800 | BUFFER_TRACE(dir_block, "get_write_access"); | 1808 | BUFFER_TRACE(dir_block, "get_write_access"); |
1801 | ext3_journal_get_write_access(handle, dir_block); | 1809 | err = ext3_journal_get_write_access(handle, dir_block); |
1810 | if (err) | ||
1811 | goto out_clear_inode; | ||
1812 | |||
1802 | de = (struct ext3_dir_entry_2 *) dir_block->b_data; | 1813 | de = (struct ext3_dir_entry_2 *) dir_block->b_data; |
1803 | de->inode = cpu_to_le32(inode->i_ino); | 1814 | de->inode = cpu_to_le32(inode->i_ino); |
1804 | de->name_len = 1; | 1815 | de->name_len = 1; |
@@ -1814,11 +1825,16 @@ retry: | |||
1814 | ext3_set_de_type(dir->i_sb, de, S_IFDIR); | 1825 | ext3_set_de_type(dir->i_sb, de, S_IFDIR); |
1815 | inode->i_nlink = 2; | 1826 | inode->i_nlink = 2; |
1816 | BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata"); | 1827 | BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata"); |
1817 | ext3_journal_dirty_metadata(handle, dir_block); | 1828 | err = ext3_journal_dirty_metadata(handle, dir_block); |
1818 | brelse (dir_block); | 1829 | if (err) |
1819 | ext3_mark_inode_dirty(handle, inode); | 1830 | goto out_clear_inode; |
1820 | err = ext3_add_entry (handle, dentry, inode); | 1831 | |
1832 | err = ext3_mark_inode_dirty(handle, inode); | ||
1833 | if (!err) | ||
1834 | err = ext3_add_entry (handle, dentry, inode); | ||
1835 | |||
1821 | if (err) { | 1836 | if (err) { |
1837 | out_clear_inode: | ||
1822 | inode->i_nlink = 0; | 1838 | inode->i_nlink = 0; |
1823 | unlock_new_inode(inode); | 1839 | unlock_new_inode(inode); |
1824 | ext3_mark_inode_dirty(handle, inode); | 1840 | ext3_mark_inode_dirty(handle, inode); |
@@ -1827,10 +1843,14 @@ retry: | |||
1827 | } | 1843 | } |
1828 | inc_nlink(dir); | 1844 | inc_nlink(dir); |
1829 | ext3_update_dx_flag(dir); | 1845 | ext3_update_dx_flag(dir); |
1830 | ext3_mark_inode_dirty(handle, dir); | 1846 | err = ext3_mark_inode_dirty(handle, dir); |
1847 | if (err) | ||
1848 | goto out_clear_inode; | ||
1849 | |||
1831 | d_instantiate(dentry, inode); | 1850 | d_instantiate(dentry, inode); |
1832 | unlock_new_inode(inode); | 1851 | unlock_new_inode(inode); |
1833 | out_stop: | 1852 | out_stop: |
1853 | brelse(dir_block); | ||
1834 | ext3_journal_stop(handle); | 1854 | ext3_journal_stop(handle); |
1835 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) | 1855 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) |
1836 | goto retry; | 1856 | goto retry; |
@@ -2178,6 +2198,7 @@ static int ext3_symlink (struct inode * dir, | |||
2178 | handle_t *handle; | 2198 | handle_t *handle; |
2179 | struct inode * inode; | 2199 | struct inode * inode; |
2180 | int l, err, retries = 0; | 2200 | int l, err, retries = 0; |
2201 | int credits; | ||
2181 | 2202 | ||
2182 | l = strlen(symname)+1; | 2203 | l = strlen(symname)+1; |
2183 | if (l > dir->i_sb->s_blocksize) | 2204 | if (l > dir->i_sb->s_blocksize) |
@@ -2185,36 +2206,76 @@ static int ext3_symlink (struct inode * dir, | |||
2185 | 2206 | ||
2186 | dquot_initialize(dir); | 2207 | dquot_initialize(dir); |
2187 | 2208 | ||
2209 | if (l > EXT3_N_BLOCKS * 4) { | ||
2210 | /* | ||
2211 | * For non-fast symlinks, we just allocate inode and put it on | ||
2212 | * orphan list in the first transaction => we need bitmap, | ||
2213 | * group descriptor, sb, inode block, quota blocks. | ||
2214 | */ | ||
2215 | credits = 4 + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); | ||
2216 | } else { | ||
2217 | /* | ||
2218 | * Fast symlink. We have to add entry to directory | ||
2219 | * (EXT3_DATA_TRANS_BLOCKS + EXT3_INDEX_EXTRA_TRANS_BLOCKS), | ||
2220 | * allocate new inode (bitmap, group descriptor, inode block, | ||
2221 | * quota blocks, sb is already counted in previous macros). | ||
2222 | */ | ||
2223 | credits = EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + | ||
2224 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + | ||
2225 | EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); | ||
2226 | } | ||
2188 | retry: | 2227 | retry: |
2189 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + | 2228 | handle = ext3_journal_start(dir, credits); |
2190 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 + | ||
2191 | EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb)); | ||
2192 | if (IS_ERR(handle)) | 2229 | if (IS_ERR(handle)) |
2193 | return PTR_ERR(handle); | 2230 | return PTR_ERR(handle); |
2194 | 2231 | ||
2195 | if (IS_DIRSYNC(dir)) | 2232 | if (IS_DIRSYNC(dir)) |
2196 | handle->h_sync = 1; | 2233 | handle->h_sync = 1; |
2197 | 2234 | ||
2198 | inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO); | 2235 | inode = ext3_new_inode (handle, dir, &dentry->d_name, S_IFLNK|S_IRWXUGO); |
2199 | err = PTR_ERR(inode); | 2236 | err = PTR_ERR(inode); |
2200 | if (IS_ERR(inode)) | 2237 | if (IS_ERR(inode)) |
2201 | goto out_stop; | 2238 | goto out_stop; |
2202 | 2239 | ||
2203 | if (l > sizeof (EXT3_I(inode)->i_data)) { | 2240 | if (l > EXT3_N_BLOCKS * 4) { |
2204 | inode->i_op = &ext3_symlink_inode_operations; | 2241 | inode->i_op = &ext3_symlink_inode_operations; |
2205 | ext3_set_aops(inode); | 2242 | ext3_set_aops(inode); |
2206 | /* | 2243 | /* |
2207 | * page_symlink() calls into ext3_prepare/commit_write. | 2244 | * We cannot call page_symlink() with transaction started |
2208 | * We have a transaction open. All is sweetness. It also sets | 2245 | * because it calls into ext3_write_begin() which acquires page |
2209 | * i_size in generic_commit_write(). | 2246 | * lock which ranks below transaction start (and it can also |
2247 | * wait for journal commit if we are running out of space). So | ||
2248 | * we have to stop transaction now and restart it when symlink | ||
2249 | * contents is written. | ||
2250 | * | ||
2251 | * To keep fs consistent in case of crash, we have to put inode | ||
2252 | * to orphan list in the mean time. | ||
2210 | */ | 2253 | */ |
2254 | drop_nlink(inode); | ||
2255 | err = ext3_orphan_add(handle, inode); | ||
2256 | ext3_journal_stop(handle); | ||
2257 | if (err) | ||
2258 | goto err_drop_inode; | ||
2211 | err = __page_symlink(inode, symname, l, 1); | 2259 | err = __page_symlink(inode, symname, l, 1); |
2260 | if (err) | ||
2261 | goto err_drop_inode; | ||
2262 | /* | ||
2263 | * Now inode is being linked into dir (EXT3_DATA_TRANS_BLOCKS | ||
2264 | * + EXT3_INDEX_EXTRA_TRANS_BLOCKS), inode is also modified | ||
2265 | */ | ||
2266 | handle = ext3_journal_start(dir, | ||
2267 | EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + | ||
2268 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 1); | ||
2269 | if (IS_ERR(handle)) { | ||
2270 | err = PTR_ERR(handle); | ||
2271 | goto err_drop_inode; | ||
2272 | } | ||
2273 | inc_nlink(inode); | ||
2274 | err = ext3_orphan_del(handle, inode); | ||
2212 | if (err) { | 2275 | if (err) { |
2276 | ext3_journal_stop(handle); | ||
2213 | drop_nlink(inode); | 2277 | drop_nlink(inode); |
2214 | unlock_new_inode(inode); | 2278 | goto err_drop_inode; |
2215 | ext3_mark_inode_dirty(handle, inode); | ||
2216 | iput (inode); | ||
2217 | goto out_stop; | ||
2218 | } | 2279 | } |
2219 | } else { | 2280 | } else { |
2220 | inode->i_op = &ext3_fast_symlink_inode_operations; | 2281 | inode->i_op = &ext3_fast_symlink_inode_operations; |
@@ -2228,6 +2289,10 @@ out_stop: | |||
2228 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) | 2289 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) |
2229 | goto retry; | 2290 | goto retry; |
2230 | return err; | 2291 | return err; |
2292 | err_drop_inode: | ||
2293 | unlock_new_inode(inode); | ||
2294 | iput(inode); | ||
2295 | return err; | ||
2231 | } | 2296 | } |
2232 | 2297 | ||
2233 | static int ext3_link (struct dentry * old_dentry, | 2298 | static int ext3_link (struct dentry * old_dentry, |
@@ -2242,13 +2307,6 @@ static int ext3_link (struct dentry * old_dentry, | |||
2242 | 2307 | ||
2243 | dquot_initialize(dir); | 2308 | dquot_initialize(dir); |
2244 | 2309 | ||
2245 | /* | ||
2246 | * Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing | ||
2247 | * otherwise has the potential to corrupt the orphan inode list. | ||
2248 | */ | ||
2249 | if (inode->i_nlink == 0) | ||
2250 | return -ENOENT; | ||
2251 | |||
2252 | retry: | 2310 | retry: |
2253 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + | 2311 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + |
2254 | EXT3_INDEX_EXTRA_TRANS_BLOCKS); | 2312 | EXT3_INDEX_EXTRA_TRANS_BLOCKS); |
@@ -2260,7 +2318,7 @@ retry: | |||
2260 | 2318 | ||
2261 | inode->i_ctime = CURRENT_TIME_SEC; | 2319 | inode->i_ctime = CURRENT_TIME_SEC; |
2262 | inc_nlink(inode); | 2320 | inc_nlink(inode); |
2263 | atomic_inc(&inode->i_count); | 2321 | ihold(inode); |
2264 | 2322 | ||
2265 | err = ext3_add_entry(handle, dentry, inode); | 2323 | err = ext3_add_entry(handle, dentry, inode); |
2266 | if (!err) { | 2324 | if (!err) { |
@@ -2353,7 +2411,9 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
2353 | goto end_rename; | 2411 | goto end_rename; |
2354 | } else { | 2412 | } else { |
2355 | BUFFER_TRACE(new_bh, "get write access"); | 2413 | BUFFER_TRACE(new_bh, "get write access"); |
2356 | ext3_journal_get_write_access(handle, new_bh); | 2414 | retval = ext3_journal_get_write_access(handle, new_bh); |
2415 | if (retval) | ||
2416 | goto journal_error; | ||
2357 | new_de->inode = cpu_to_le32(old_inode->i_ino); | 2417 | new_de->inode = cpu_to_le32(old_inode->i_ino); |
2358 | if (EXT3_HAS_INCOMPAT_FEATURE(new_dir->i_sb, | 2418 | if (EXT3_HAS_INCOMPAT_FEATURE(new_dir->i_sb, |
2359 | EXT3_FEATURE_INCOMPAT_FILETYPE)) | 2419 | EXT3_FEATURE_INCOMPAT_FILETYPE)) |
@@ -2362,7 +2422,9 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
2362 | new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME_SEC; | 2422 | new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME_SEC; |
2363 | ext3_mark_inode_dirty(handle, new_dir); | 2423 | ext3_mark_inode_dirty(handle, new_dir); |
2364 | BUFFER_TRACE(new_bh, "call ext3_journal_dirty_metadata"); | 2424 | BUFFER_TRACE(new_bh, "call ext3_journal_dirty_metadata"); |
2365 | ext3_journal_dirty_metadata(handle, new_bh); | 2425 | retval = ext3_journal_dirty_metadata(handle, new_bh); |
2426 | if (retval) | ||
2427 | goto journal_error; | ||
2366 | brelse(new_bh); | 2428 | brelse(new_bh); |
2367 | new_bh = NULL; | 2429 | new_bh = NULL; |
2368 | } | 2430 | } |
@@ -2411,10 +2473,17 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
2411 | ext3_update_dx_flag(old_dir); | 2473 | ext3_update_dx_flag(old_dir); |
2412 | if (dir_bh) { | 2474 | if (dir_bh) { |
2413 | BUFFER_TRACE(dir_bh, "get_write_access"); | 2475 | BUFFER_TRACE(dir_bh, "get_write_access"); |
2414 | ext3_journal_get_write_access(handle, dir_bh); | 2476 | retval = ext3_journal_get_write_access(handle, dir_bh); |
2477 | if (retval) | ||
2478 | goto journal_error; | ||
2415 | PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino); | 2479 | PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino); |
2416 | BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata"); | 2480 | BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata"); |
2417 | ext3_journal_dirty_metadata(handle, dir_bh); | 2481 | retval = ext3_journal_dirty_metadata(handle, dir_bh); |
2482 | if (retval) { | ||
2483 | journal_error: | ||
2484 | ext3_std_error(new_dir->i_sb, retval); | ||
2485 | goto end_rename; | ||
2486 | } | ||
2418 | drop_nlink(old_dir); | 2487 | drop_nlink(old_dir); |
2419 | if (new_inode) { | 2488 | if (new_inode) { |
2420 | drop_nlink(new_inode); | 2489 | drop_nlink(new_inode); |