aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/stree.c
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2013-08-08 17:34:47 -0400
committerJeff Mahoney <jeffm@suse.de>2013-08-08 17:34:47 -0400
commitd2d0395fd1778d4bf714adc5bfd23a5d748d7802 (patch)
tree7205eff1242051818b57423142394690620c2731 /fs/reiserfs/stree.c
parent278f6679f454bf185a07d9a4ca355b153482d17a (diff)
reiserfs: locking, release lock around quota operations
Previous commits released the write lock across quota operations but missed several places. In particular, the free operations can also call into the file system code and take the write lock, causing deadlocks. This patch introduces some more helpers and uses them for quota call sites. Without this patch applied, reiserfs + quotas runs into deadlocks under anything more than trivial load. Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Diffstat (limited to 'fs/reiserfs/stree.c')
-rw-r--r--fs/reiserfs/stree.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index 4d7d476d7bff..b14706a05d52 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -1186,6 +1186,7 @@ int reiserfs_delete_item(struct reiserfs_transaction_handle *th,
1186 struct item_head *q_ih; 1186 struct item_head *q_ih;
1187 int quota_cut_bytes; 1187 int quota_cut_bytes;
1188 int ret_value, del_size, removed; 1188 int ret_value, del_size, removed;
1189 int depth;
1189 1190
1190#ifdef CONFIG_REISERFS_CHECK 1191#ifdef CONFIG_REISERFS_CHECK
1191 char mode; 1192 char mode;
@@ -1295,7 +1296,9 @@ int reiserfs_delete_item(struct reiserfs_transaction_handle *th,
1295 "reiserquota delete_item(): freeing %u, id=%u type=%c", 1296 "reiserquota delete_item(): freeing %u, id=%u type=%c",
1296 quota_cut_bytes, inode->i_uid, head2type(&s_ih)); 1297 quota_cut_bytes, inode->i_uid, head2type(&s_ih));
1297#endif 1298#endif
1299 depth = reiserfs_write_unlock_nested(inode->i_sb);
1298 dquot_free_space_nodirty(inode, quota_cut_bytes); 1300 dquot_free_space_nodirty(inode, quota_cut_bytes);
1301 reiserfs_write_lock_nested(inode->i_sb, depth);
1299 1302
1300 /* Return deleted body length */ 1303 /* Return deleted body length */
1301 return ret_value; 1304 return ret_value;
@@ -1321,6 +1324,7 @@ int reiserfs_delete_item(struct reiserfs_transaction_handle *th,
1321void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th, 1324void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th,
1322 struct inode *inode, struct reiserfs_key *key) 1325 struct inode *inode, struct reiserfs_key *key)
1323{ 1326{
1327 struct super_block *sb = th->t_super;
1324 struct tree_balance tb; 1328 struct tree_balance tb;
1325 INITIALIZE_PATH(path); 1329 INITIALIZE_PATH(path);
1326 int item_len = 0; 1330 int item_len = 0;
@@ -1373,14 +1377,17 @@ void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th,
1373 if (retval == CARRY_ON) { 1377 if (retval == CARRY_ON) {
1374 do_balance(&tb, NULL, NULL, M_DELETE); 1378 do_balance(&tb, NULL, NULL, M_DELETE);
1375 if (inode) { /* Should we count quota for item? (we don't count quotas for save-links) */ 1379 if (inode) { /* Should we count quota for item? (we don't count quotas for save-links) */
1380 int depth;
1376#ifdef REISERQUOTA_DEBUG 1381#ifdef REISERQUOTA_DEBUG
1377 reiserfs_debug(th->t_super, REISERFS_DEBUG_CODE, 1382 reiserfs_debug(th->t_super, REISERFS_DEBUG_CODE,
1378 "reiserquota delete_solid_item(): freeing %u id=%u type=%c", 1383 "reiserquota delete_solid_item(): freeing %u id=%u type=%c",
1379 quota_cut_bytes, inode->i_uid, 1384 quota_cut_bytes, inode->i_uid,
1380 key2type(key)); 1385 key2type(key));
1381#endif 1386#endif
1387 depth = reiserfs_write_unlock_nested(sb);
1382 dquot_free_space_nodirty(inode, 1388 dquot_free_space_nodirty(inode,
1383 quota_cut_bytes); 1389 quota_cut_bytes);
1390 reiserfs_write_lock_nested(sb, depth);
1384 } 1391 }
1385 break; 1392 break;
1386 } 1393 }
@@ -1557,6 +1564,7 @@ int reiserfs_cut_from_item(struct reiserfs_transaction_handle *th,
1557 int retval2 = -1; 1564 int retval2 = -1;
1558 int quota_cut_bytes; 1565 int quota_cut_bytes;
1559 loff_t tail_pos = 0; 1566 loff_t tail_pos = 0;
1567 int depth;
1560 1568
1561 BUG_ON(!th->t_trans_id); 1569 BUG_ON(!th->t_trans_id);
1562 1570
@@ -1729,7 +1737,9 @@ int reiserfs_cut_from_item(struct reiserfs_transaction_handle *th,
1729 "reiserquota cut_from_item(): freeing %u id=%u type=%c", 1737 "reiserquota cut_from_item(): freeing %u id=%u type=%c",
1730 quota_cut_bytes, inode->i_uid, '?'); 1738 quota_cut_bytes, inode->i_uid, '?');
1731#endif 1739#endif
1740 depth = reiserfs_write_unlock_nested(sb);
1732 dquot_free_space_nodirty(inode, quota_cut_bytes); 1741 dquot_free_space_nodirty(inode, quota_cut_bytes);
1742 reiserfs_write_lock_nested(sb, depth);
1733 return ret_value; 1743 return ret_value;
1734} 1744}
1735 1745
@@ -1949,9 +1959,11 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree
1949 const char *body, /* Pointer to the bytes to paste. */ 1959 const char *body, /* Pointer to the bytes to paste. */
1950 int pasted_size) 1960 int pasted_size)
1951{ /* Size of pasted bytes. */ 1961{ /* Size of pasted bytes. */
1962 struct super_block *sb = inode->i_sb;
1952 struct tree_balance s_paste_balance; 1963 struct tree_balance s_paste_balance;
1953 int retval; 1964 int retval;
1954 int fs_gen; 1965 int fs_gen;
1966 int depth;
1955 1967
1956 BUG_ON(!th->t_trans_id); 1968 BUG_ON(!th->t_trans_id);
1957 1969
@@ -1964,9 +1976,9 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree
1964 key2type(&(key->on_disk_key))); 1976 key2type(&(key->on_disk_key)));
1965#endif 1977#endif
1966 1978
1967 reiserfs_write_unlock(inode->i_sb); 1979 depth = reiserfs_write_unlock_nested(sb);
1968 retval = dquot_alloc_space_nodirty(inode, pasted_size); 1980 retval = dquot_alloc_space_nodirty(inode, pasted_size);
1969 reiserfs_write_lock(inode->i_sb); 1981 reiserfs_write_lock_nested(sb, depth);
1970 if (retval) { 1982 if (retval) {
1971 pathrelse(search_path); 1983 pathrelse(search_path);
1972 return retval; 1984 return retval;
@@ -2023,7 +2035,9 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree
2023 pasted_size, inode->i_uid, 2035 pasted_size, inode->i_uid,
2024 key2type(&(key->on_disk_key))); 2036 key2type(&(key->on_disk_key)));
2025#endif 2037#endif
2038 depth = reiserfs_write_unlock_nested(sb);
2026 dquot_free_space_nodirty(inode, pasted_size); 2039 dquot_free_space_nodirty(inode, pasted_size);
2040 reiserfs_write_lock_nested(sb, depth);
2027 return retval; 2041 return retval;
2028} 2042}
2029 2043
@@ -2046,6 +2060,7 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th,
2046 BUG_ON(!th->t_trans_id); 2060 BUG_ON(!th->t_trans_id);
2047 2061
2048 if (inode) { /* Do we count quotas for item? */ 2062 if (inode) { /* Do we count quotas for item? */
2063 int depth;
2049 fs_gen = get_generation(inode->i_sb); 2064 fs_gen = get_generation(inode->i_sb);
2050 quota_bytes = ih_item_len(ih); 2065 quota_bytes = ih_item_len(ih);
2051 2066
@@ -2059,11 +2074,11 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th,
2059 "reiserquota insert_item(): allocating %u id=%u type=%c", 2074 "reiserquota insert_item(): allocating %u id=%u type=%c",
2060 quota_bytes, inode->i_uid, head2type(ih)); 2075 quota_bytes, inode->i_uid, head2type(ih));
2061#endif 2076#endif
2062 reiserfs_write_unlock(inode->i_sb);
2063 /* We can't dirty inode here. It would be immediately written but 2077 /* We can't dirty inode here. It would be immediately written but
2064 * appropriate stat item isn't inserted yet... */ 2078 * appropriate stat item isn't inserted yet... */
2079 depth = reiserfs_write_unlock_nested(inode->i_sb);
2065 retval = dquot_alloc_space_nodirty(inode, quota_bytes); 2080 retval = dquot_alloc_space_nodirty(inode, quota_bytes);
2066 reiserfs_write_lock(inode->i_sb); 2081 reiserfs_write_lock_nested(inode->i_sb, depth);
2067 if (retval) { 2082 if (retval) {
2068 pathrelse(path); 2083 pathrelse(path);
2069 return retval; 2084 return retval;
@@ -2114,7 +2129,10 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th,
2114 "reiserquota insert_item(): freeing %u id=%u type=%c", 2129 "reiserquota insert_item(): freeing %u id=%u type=%c",
2115 quota_bytes, inode->i_uid, head2type(ih)); 2130 quota_bytes, inode->i_uid, head2type(ih));
2116#endif 2131#endif
2117 if (inode) 2132 if (inode) {
2133 int depth = reiserfs_write_unlock_nested(inode->i_sb);
2118 dquot_free_space_nodirty(inode, quota_bytes); 2134 dquot_free_space_nodirty(inode, quota_bytes);
2135 reiserfs_write_lock_nested(inode->i_sb, depth);
2136 }
2119 return retval; 2137 return retval;
2120} 2138}