aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/dir.c')
-rw-r--r--fs/ocfs2/dir.c24
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
1382out_commit: 1390out_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
1385out_sem: 1396out_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;
1441bail: 1459bail:
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}