diff options
author | Jan Kara <jack@suse.cz> | 2008-10-09 13:38:40 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2009-01-05 11:40:23 -0500 |
commit | a90714c150e3ce677c57a9dac3ab1ec342c75a95 (patch) | |
tree | 43e3e744d86122940c0db39ac1bfed0d434b3216 /fs/ocfs2/dir.c | |
parent | 9e33d69f553aaf11377307e8d6f82deb3385e351 (diff) |
ocfs2: Add quota calls for allocation and freeing of inodes and space
Add quota calls for allocation and freeing of inodes and space, also update
estimates on number of needed credits for a transaction. Move out inode
allocation from ocfs2_mknod_locked() because vfs_dq_init() must be called
outside of a transaction.
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/dir.c')
-rw-r--r-- | fs/ocfs2/dir.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index d83cff95759e..3708fe482e3e 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/types.h> | 40 | #include <linux/types.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/highmem.h> | 42 | #include <linux/highmem.h> |
43 | #include <linux/quotaops.h> | ||
43 | 44 | ||
44 | #define MLOG_MASK_PREFIX ML_NAMEI | 45 | #define MLOG_MASK_PREFIX ML_NAMEI |
45 | #include <cluster/masklog.h> | 46 | #include <cluster/masklog.h> |
@@ -1210,9 +1211,9 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh, | |||
1210 | unsigned int blocks_wanted, | 1211 | unsigned int blocks_wanted, |
1211 | struct buffer_head **first_block_bh) | 1212 | struct buffer_head **first_block_bh) |
1212 | { | 1213 | { |
1213 | int ret, credits = OCFS2_INLINE_TO_EXTENTS_CREDITS; | ||
1214 | u32 alloc, bit_off, len; | 1214 | u32 alloc, bit_off, len; |
1215 | struct super_block *sb = dir->i_sb; | 1215 | struct super_block *sb = dir->i_sb; |
1216 | int ret, credits = ocfs2_inline_to_extents_credits(sb); | ||
1216 | u64 blkno, bytes = blocks_wanted << sb->s_blocksize_bits; | 1217 | u64 blkno, bytes = blocks_wanted << sb->s_blocksize_bits; |
1217 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | 1218 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
1218 | struct ocfs2_inode_info *oi = OCFS2_I(dir); | 1219 | struct ocfs2_inode_info *oi = OCFS2_I(dir); |
@@ -1221,6 +1222,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh, | |||
1221 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | 1222 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; |
1222 | handle_t *handle; | 1223 | handle_t *handle; |
1223 | struct ocfs2_extent_tree et; | 1224 | struct ocfs2_extent_tree et; |
1225 | int did_quota = 0; | ||
1224 | 1226 | ||
1225 | ocfs2_init_dinode_extent_tree(&et, dir, di_bh); | 1227 | ocfs2_init_dinode_extent_tree(&et, dir, di_bh); |
1226 | 1228 | ||
@@ -1258,6 +1260,12 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh, | |||
1258 | goto out_sem; | 1260 | goto out_sem; |
1259 | } | 1261 | } |
1260 | 1262 | ||
1263 | if (vfs_dq_alloc_space_nodirty(dir, | ||
1264 | ocfs2_clusters_to_bytes(osb->sb, alloc))) { | ||
1265 | ret = -EDQUOT; | ||
1266 | goto out_commit; | ||
1267 | } | ||
1268 | did_quota = 1; | ||
1261 | /* | 1269 | /* |
1262 | * Try to claim as many clusters as the bitmap can give though | 1270 | * Try to claim as many clusters as the bitmap can give though |
1263 | * if we only get one now, that's enough to continue. The rest | 1271 | * if we only get one now, that's enough to continue. The rest |
@@ -1380,6 +1388,9 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh, | |||
1380 | dirdata_bh = NULL; | 1388 | dirdata_bh = NULL; |
1381 | 1389 | ||
1382 | out_commit: | 1390 | out_commit: |
1391 | if (ret < 0 && did_quota) | ||
1392 | vfs_dq_free_space_nodirty(dir, | ||
1393 | ocfs2_clusters_to_bytes(osb->sb, 2)); | ||
1383 | ocfs2_commit_trans(osb, handle); | 1394 | ocfs2_commit_trans(osb, handle); |
1384 | 1395 | ||
1385 | out_sem: | 1396 | out_sem: |
@@ -1404,7 +1415,7 @@ static int ocfs2_do_extend_dir(struct super_block *sb, | |||
1404 | struct buffer_head **new_bh) | 1415 | struct buffer_head **new_bh) |
1405 | { | 1416 | { |
1406 | int status; | 1417 | int status; |
1407 | int extend; | 1418 | int extend, did_quota = 0; |
1408 | u64 p_blkno, v_blkno; | 1419 | u64 p_blkno, v_blkno; |
1409 | 1420 | ||
1410 | spin_lock(&OCFS2_I(dir)->ip_lock); | 1421 | spin_lock(&OCFS2_I(dir)->ip_lock); |
@@ -1414,6 +1425,13 @@ static int ocfs2_do_extend_dir(struct super_block *sb, | |||
1414 | if (extend) { | 1425 | if (extend) { |
1415 | u32 offset = OCFS2_I(dir)->ip_clusters; | 1426 | u32 offset = OCFS2_I(dir)->ip_clusters; |
1416 | 1427 | ||
1428 | if (vfs_dq_alloc_space_nodirty(dir, | ||
1429 | ocfs2_clusters_to_bytes(sb, 1))) { | ||
1430 | status = -EDQUOT; | ||
1431 | goto bail; | ||
1432 | } | ||
1433 | did_quota = 1; | ||
1434 | |||
1417 | status = ocfs2_add_inode_data(OCFS2_SB(sb), dir, &offset, | 1435 | status = ocfs2_add_inode_data(OCFS2_SB(sb), dir, &offset, |
1418 | 1, 0, parent_fe_bh, handle, | 1436 | 1, 0, parent_fe_bh, handle, |
1419 | data_ac, meta_ac, NULL); | 1437 | data_ac, meta_ac, NULL); |
@@ -1439,6 +1457,8 @@ static int ocfs2_do_extend_dir(struct super_block *sb, | |||
1439 | } | 1457 | } |
1440 | status = 0; | 1458 | status = 0; |
1441 | bail: | 1459 | bail: |
1460 | if (did_quota && status < 0) | ||
1461 | vfs_dq_free_space_nodirty(dir, ocfs2_clusters_to_bytes(sb, 1)); | ||
1442 | mlog_exit(status); | 1462 | mlog_exit(status); |
1443 | return status; | 1463 | return status; |
1444 | } | 1464 | } |