@@ -1629,6 +1629,35 @@ static int ext4_delete_entry (handle_t *handle,
1629
1629
return - ENOENT ;
1630
1630
}
1631
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
+ */
1636
+ static 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
+ */
1653
+ static 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
+
1632
1661
static int ext4_add_nondir (handle_t * handle ,
1633
1662
struct dentry * dentry , struct inode * inode )
1634
1663
{
@@ -1725,7 +1754,7 @@ static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
1725
1754
struct ext4_dir_entry_2 * de ;
1726
1755
int err , retries = 0 ;
1727
1756
1728
- if (dir -> i_nlink >= EXT4_LINK_MAX )
1757
+ if (EXT4_DIR_LINK_MAX ( dir ) )
1729
1758
return - EMLINK ;
1730
1759
1731
1760
retry :
@@ -1748,7 +1777,7 @@ static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
1748
1777
inode -> i_size = EXT4_I (inode )-> i_disksize = inode -> i_sb -> s_blocksize ;
1749
1778
dir_block = ext4_bread (handle , inode , 0 , 1 , & err );
1750
1779
if (!dir_block ) {
1751
- drop_nlink ( inode ); /* is this nlink == 0? */
1780
+ ext4_dec_count ( handle , inode ); /* is this nlink == 0? */
1752
1781
ext4_mark_inode_dirty (handle , inode );
1753
1782
iput (inode );
1754
1783
goto out_stop ;
@@ -1780,7 +1809,7 @@ static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
1780
1809
iput (inode );
1781
1810
goto out_stop ;
1782
1811
}
1783
- inc_nlink ( dir );
1812
+ ext4_inc_count ( handle , dir );
1784
1813
ext4_update_dx_flag (dir );
1785
1814
ext4_mark_inode_dirty (handle , dir );
1786
1815
d_instantiate (dentry , inode );
@@ -2045,9 +2074,9 @@ static int ext4_rmdir (struct inode * dir, struct dentry *dentry)
2045
2074
retval = ext4_delete_entry (handle , dir , de , bh );
2046
2075
if (retval )
2047
2076
goto end_rmdir ;
2048
- if (inode -> i_nlink != 2 )
2077
+ if (! EXT4_DIR_LINK_EMPTY ( inode ) )
2049
2078
ext4_warning (inode -> i_sb , "ext4_rmdir" ,
2050
- "empty directory has nlink!=2 (%d)" ,
2079
+ "empty directory has too many links (%d)" ,
2051
2080
inode -> i_nlink );
2052
2081
inode -> i_version ++ ;
2053
2082
clear_nlink (inode );
@@ -2058,7 +2087,7 @@ static int ext4_rmdir (struct inode * dir, struct dentry *dentry)
2058
2087
ext4_orphan_add (handle , inode );
2059
2088
inode -> i_ctime = dir -> i_ctime = dir -> i_mtime = ext4_current_time (inode );
2060
2089
ext4_mark_inode_dirty (handle , inode );
2061
- drop_nlink ( dir );
2090
+ ext4_dec_count ( handle , dir );
2062
2091
ext4_update_dx_flag (dir );
2063
2092
ext4_mark_inode_dirty (handle , dir );
2064
2093
@@ -2109,7 +2138,7 @@ static int ext4_unlink(struct inode * dir, struct dentry *dentry)
2109
2138
dir -> i_ctime = dir -> i_mtime = ext4_current_time (dir );
2110
2139
ext4_update_dx_flag (dir );
2111
2140
ext4_mark_inode_dirty (handle , dir );
2112
- drop_nlink ( inode );
2141
+ ext4_dec_count ( handle , inode );
2113
2142
if (!inode -> i_nlink )
2114
2143
ext4_orphan_add (handle , inode );
2115
2144
inode -> i_ctime = ext4_current_time (inode );
@@ -2159,7 +2188,7 @@ static int ext4_symlink (struct inode * dir,
2159
2188
err = __page_symlink (inode , symname , l ,
2160
2189
mapping_gfp_mask (inode -> i_mapping ) & ~__GFP_FS );
2161
2190
if (err ) {
2162
- drop_nlink ( inode );
2191
+ ext4_dec_count ( handle , inode );
2163
2192
ext4_mark_inode_dirty (handle , inode );
2164
2193
iput (inode );
2165
2194
goto out_stop ;
@@ -2185,8 +2214,9 @@ static int ext4_link (struct dentry * old_dentry,
2185
2214
struct inode * inode = old_dentry -> d_inode ;
2186
2215
int err , retries = 0 ;
2187
2216
2188
- if (inode -> i_nlink >= EXT4_LINK_MAX )
2217
+ if (EXT4_DIR_LINK_MAX ( inode ) )
2189
2218
return - EMLINK ;
2219
+
2190
2220
/*
2191
2221
* Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing
2192
2222
* otherwise has the potential to corrupt the orphan inode list.
@@ -2204,7 +2234,7 @@ static int ext4_link (struct dentry * old_dentry,
2204
2234
handle -> h_sync = 1 ;
2205
2235
2206
2236
inode -> i_ctime = ext4_current_time (inode );
2207
- inc_nlink ( inode );
2237
+ ext4_inc_count ( handle , inode );
2208
2238
atomic_inc (& inode -> i_count );
2209
2239
2210
2240
err = ext4_add_nondir (handle , dentry , inode );
@@ -2337,7 +2367,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
2337
2367
}
2338
2368
2339
2369
if (new_inode ) {
2340
- drop_nlink ( new_inode );
2370
+ ext4_dec_count ( handle , new_inode );
2341
2371
new_inode -> i_ctime = ext4_current_time (new_inode );
2342
2372
}
2343
2373
old_dir -> i_ctime = old_dir -> i_mtime = ext4_current_time (old_dir );
@@ -2348,11 +2378,13 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
2348
2378
PARENT_INO (dir_bh -> b_data ) = cpu_to_le32 (new_dir -> i_ino );
2349
2379
BUFFER_TRACE (dir_bh , "call ext4_journal_dirty_metadata" );
2350
2380
ext4_journal_dirty_metadata (handle , dir_bh );
2351
- drop_nlink ( old_dir );
2381
+ ext4_dec_count ( handle , old_dir );
2352
2382
if (new_inode ) {
2353
- 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 ;
2354
2386
} else {
2355
- inc_nlink ( new_dir );
2387
+ ext4_inc_count ( handle , new_dir );
2356
2388
ext4_update_dx_flag (new_dir );
2357
2389
ext4_mark_inode_dirty (handle , new_dir );
2358
2390
}
0 commit comments