aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r--fs/ext4/namei.c86
1 files changed, 64 insertions, 22 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 2811e5720ad0..da224974af78 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1017,6 +1017,11 @@ static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, str
1017 1017
1018 if (!inode) 1018 if (!inode)
1019 return ERR_PTR(-EACCES); 1019 return ERR_PTR(-EACCES);
1020
1021 if (is_bad_inode(inode)) {
1022 iput(inode);
1023 return ERR_PTR(-ENOENT);
1024 }
1020 } 1025 }
1021 return d_splice_alias(inode, dentry); 1026 return d_splice_alias(inode, dentry);
1022} 1027}
@@ -1052,6 +1057,11 @@ struct dentry *ext4_get_parent(struct dentry *child)
1052 if (!inode) 1057 if (!inode)
1053 return ERR_PTR(-EACCES); 1058 return ERR_PTR(-EACCES);
1054 1059
1060 if (is_bad_inode(inode)) {
1061 iput(inode);
1062 return ERR_PTR(-ENOENT);
1063 }
1064
1055 parent = d_alloc_anon(inode); 1065 parent = d_alloc_anon(inode);
1056 if (!parent) { 1066 if (!parent) {
1057 iput(inode); 1067 iput(inode);
@@ -1285,7 +1295,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
1285 * happen is that the times are slightly out of date 1295 * happen is that the times are slightly out of date
1286 * and/or different from the directory change time. 1296 * and/or different from the directory change time.
1287 */ 1297 */
1288 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 1298 dir->i_mtime = dir->i_ctime = ext4_current_time(dir);
1289 ext4_update_dx_flag(dir); 1299 ext4_update_dx_flag(dir);
1290 dir->i_version++; 1300 dir->i_version++;
1291 ext4_mark_inode_dirty(handle, dir); 1301 ext4_mark_inode_dirty(handle, dir);
@@ -1619,6 +1629,35 @@ static int ext4_delete_entry (handle_t *handle,
1619 return -ENOENT; 1629 return -ENOENT;
1620} 1630}
1621 1631
1632/*
1633 * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
1634 * since this indicates that nlinks count was previously 1.
1635 */
1636static void ext4_inc_count(handle_t *handle, struct inode *inode)
1637{
1638 inc_nlink(inode);
1639 if (is_dx(inode) && inode->i_nlink > 1) {
1640 /* limit is 16-bit i_links_count */
1641 if (inode->i_nlink >= EXT4_LINK_MAX || inode->i_nlink == 2) {
1642 inode->i_nlink = 1;
1643 EXT4_SET_RO_COMPAT_FEATURE(inode->i_sb,
1644 EXT4_FEATURE_RO_COMPAT_DIR_NLINK);
1645 }
1646 }
1647}
1648
1649/*
1650 * If a directory had nlink == 1, then we should let it be 1. This indicates
1651 * directory has >EXT4_LINK_MAX subdirs.
1652 */
1653static void ext4_dec_count(handle_t *handle, struct inode *inode)
1654{
1655 drop_nlink(inode);
1656 if (S_ISDIR(inode->i_mode) && inode->i_nlink == 0)
1657 inc_nlink(inode);
1658}
1659
1660
1622static int ext4_add_nondir(handle_t *handle, 1661static int ext4_add_nondir(handle_t *handle,
1623 struct dentry *dentry, struct inode *inode) 1662 struct dentry *dentry, struct inode *inode)
1624{ 1663{
@@ -1715,7 +1754,7 @@ static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
1715 struct ext4_dir_entry_2 * de; 1754 struct ext4_dir_entry_2 * de;
1716 int err, retries = 0; 1755 int err, retries = 0;
1717 1756
1718 if (dir->i_nlink >= EXT4_LINK_MAX) 1757 if (EXT4_DIR_LINK_MAX(dir))
1719 return -EMLINK; 1758 return -EMLINK;
1720 1759
1721retry: 1760retry:
@@ -1738,7 +1777,7 @@ retry:
1738 inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize; 1777 inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
1739 dir_block = ext4_bread (handle, inode, 0, 1, &err); 1778 dir_block = ext4_bread (handle, inode, 0, 1, &err);
1740 if (!dir_block) { 1779 if (!dir_block) {
1741 drop_nlink(inode); /* is this nlink == 0? */ 1780 ext4_dec_count(handle, inode); /* is this nlink == 0? */
1742 ext4_mark_inode_dirty(handle, inode); 1781 ext4_mark_inode_dirty(handle, inode);
1743 iput (inode); 1782 iput (inode);
1744 goto out_stop; 1783 goto out_stop;
@@ -1770,7 +1809,7 @@ retry:
1770 iput (inode); 1809 iput (inode);
1771 goto out_stop; 1810 goto out_stop;
1772 } 1811 }
1773 inc_nlink(dir); 1812 ext4_inc_count(handle, dir);
1774 ext4_update_dx_flag(dir); 1813 ext4_update_dx_flag(dir);
1775 ext4_mark_inode_dirty(handle, dir); 1814 ext4_mark_inode_dirty(handle, dir);
1776 d_instantiate(dentry, inode); 1815 d_instantiate(dentry, inode);
@@ -2035,9 +2074,9 @@ static int ext4_rmdir (struct inode * dir, struct dentry *dentry)
2035 retval = ext4_delete_entry(handle, dir, de, bh); 2074 retval = ext4_delete_entry(handle, dir, de, bh);
2036 if (retval) 2075 if (retval)
2037 goto end_rmdir; 2076 goto end_rmdir;
2038 if (inode->i_nlink != 2) 2077 if (!EXT4_DIR_LINK_EMPTY(inode))
2039 ext4_warning (inode->i_sb, "ext4_rmdir", 2078 ext4_warning (inode->i_sb, "ext4_rmdir",
2040 "empty directory has nlink!=2 (%d)", 2079 "empty directory has too many links (%d)",
2041 inode->i_nlink); 2080 inode->i_nlink);
2042 inode->i_version++; 2081 inode->i_version++;
2043 clear_nlink(inode); 2082 clear_nlink(inode);
@@ -2046,9 +2085,9 @@ static int ext4_rmdir (struct inode * dir, struct dentry *dentry)
2046 * recovery. */ 2085 * recovery. */
2047 inode->i_size = 0; 2086 inode->i_size = 0;
2048 ext4_orphan_add(handle, inode); 2087 ext4_orphan_add(handle, inode);
2049 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; 2088 inode->i_ctime = dir->i_ctime = dir->i_mtime = ext4_current_time(inode);
2050 ext4_mark_inode_dirty(handle, inode); 2089 ext4_mark_inode_dirty(handle, inode);
2051 drop_nlink(dir); 2090 ext4_dec_count(handle, dir);
2052 ext4_update_dx_flag(dir); 2091 ext4_update_dx_flag(dir);
2053 ext4_mark_inode_dirty(handle, dir); 2092 ext4_mark_inode_dirty(handle, dir);
2054 2093
@@ -2096,13 +2135,13 @@ static int ext4_unlink(struct inode * dir, struct dentry *dentry)
2096 retval = ext4_delete_entry(handle, dir, de, bh); 2135 retval = ext4_delete_entry(handle, dir, de, bh);
2097 if (retval) 2136 if (retval)
2098 goto end_unlink; 2137 goto end_unlink;
2099 dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; 2138 dir->i_ctime = dir->i_mtime = ext4_current_time(dir);
2100 ext4_update_dx_flag(dir); 2139 ext4_update_dx_flag(dir);
2101 ext4_mark_inode_dirty(handle, dir); 2140 ext4_mark_inode_dirty(handle, dir);
2102 drop_nlink(inode); 2141 ext4_dec_count(handle, inode);
2103 if (!inode->i_nlink) 2142 if (!inode->i_nlink)
2104 ext4_orphan_add(handle, inode); 2143 ext4_orphan_add(handle, inode);
2105 inode->i_ctime = dir->i_ctime; 2144 inode->i_ctime = ext4_current_time(inode);
2106 ext4_mark_inode_dirty(handle, inode); 2145 ext4_mark_inode_dirty(handle, inode);
2107 retval = 0; 2146 retval = 0;
2108 2147
@@ -2149,7 +2188,7 @@ retry:
2149 err = __page_symlink(inode, symname, l, 2188 err = __page_symlink(inode, symname, l,
2150 mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); 2189 mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
2151 if (err) { 2190 if (err) {
2152 drop_nlink(inode); 2191 ext4_dec_count(handle, inode);
2153 ext4_mark_inode_dirty(handle, inode); 2192 ext4_mark_inode_dirty(handle, inode);
2154 iput (inode); 2193 iput (inode);
2155 goto out_stop; 2194 goto out_stop;
@@ -2175,8 +2214,9 @@ static int ext4_link (struct dentry * old_dentry,
2175 struct inode *inode = old_dentry->d_inode; 2214 struct inode *inode = old_dentry->d_inode;
2176 int err, retries = 0; 2215 int err, retries = 0;
2177 2216
2178 if (inode->i_nlink >= EXT4_LINK_MAX) 2217 if (EXT4_DIR_LINK_MAX(inode))
2179 return -EMLINK; 2218 return -EMLINK;
2219
2180 /* 2220 /*
2181 * Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing 2221 * Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing
2182 * otherwise has the potential to corrupt the orphan inode list. 2222 * otherwise has the potential to corrupt the orphan inode list.
@@ -2193,8 +2233,8 @@ retry:
2193 if (IS_DIRSYNC(dir)) 2233 if (IS_DIRSYNC(dir))
2194 handle->h_sync = 1; 2234 handle->h_sync = 1;
2195 2235
2196 inode->i_ctime = CURRENT_TIME_SEC; 2236 inode->i_ctime = ext4_current_time(inode);
2197 inc_nlink(inode); 2237 ext4_inc_count(handle, inode);
2198 atomic_inc(&inode->i_count); 2238 atomic_inc(&inode->i_count);
2199 2239
2200 err = ext4_add_nondir(handle, dentry, inode); 2240 err = ext4_add_nondir(handle, dentry, inode);
@@ -2295,7 +2335,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
2295 * Like most other Unix systems, set the ctime for inodes on a 2335 * Like most other Unix systems, set the ctime for inodes on a
2296 * rename. 2336 * rename.
2297 */ 2337 */
2298 old_inode->i_ctime = CURRENT_TIME_SEC; 2338 old_inode->i_ctime = ext4_current_time(old_inode);
2299 ext4_mark_inode_dirty(handle, old_inode); 2339 ext4_mark_inode_dirty(handle, old_inode);
2300 2340
2301 /* 2341 /*
@@ -2327,10 +2367,10 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
2327 } 2367 }
2328 2368
2329 if (new_inode) { 2369 if (new_inode) {
2330 drop_nlink(new_inode); 2370 ext4_dec_count(handle, new_inode);
2331 new_inode->i_ctime = CURRENT_TIME_SEC; 2371 new_inode->i_ctime = ext4_current_time(new_inode);
2332 } 2372 }
2333 old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC; 2373 old_dir->i_ctime = old_dir->i_mtime = ext4_current_time(old_dir);
2334 ext4_update_dx_flag(old_dir); 2374 ext4_update_dx_flag(old_dir);
2335 if (dir_bh) { 2375 if (dir_bh) {
2336 BUFFER_TRACE(dir_bh, "get_write_access"); 2376 BUFFER_TRACE(dir_bh, "get_write_access");
@@ -2338,11 +2378,13 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
2338 PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino); 2378 PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino);
2339 BUFFER_TRACE(dir_bh, "call ext4_journal_dirty_metadata"); 2379 BUFFER_TRACE(dir_bh, "call ext4_journal_dirty_metadata");
2340 ext4_journal_dirty_metadata(handle, dir_bh); 2380 ext4_journal_dirty_metadata(handle, dir_bh);
2341 drop_nlink(old_dir); 2381 ext4_dec_count(handle, old_dir);
2342 if (new_inode) { 2382 if (new_inode) {
2343 drop_nlink(new_inode); 2383 /* checked empty_dir above, can't have another parent,
2384 * ext3_dec_count() won't work for many-linked dirs */
2385 new_inode->i_nlink = 0;
2344 } else { 2386 } else {
2345 inc_nlink(new_dir); 2387 ext4_inc_count(handle, new_dir);
2346 ext4_update_dx_flag(new_dir); 2388 ext4_update_dx_flag(new_dir);
2347 ext4_mark_inode_dirty(handle, new_dir); 2389 ext4_mark_inode_dirty(handle, new_dir);
2348 } 2390 }