diff options
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 | } |