diff options
-rw-r--r-- | fs/ocfs2/alloc.c | 20 | ||||
-rw-r--r-- | fs/ocfs2/aops.c | 16 | ||||
-rw-r--r-- | fs/ocfs2/dir.c | 24 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 72 | ||||
-rw-r--r-- | fs/ocfs2/inode.c | 10 | ||||
-rw-r--r-- | fs/ocfs2/journal.h | 84 | ||||
-rw-r--r-- | fs/ocfs2/namei.c | 44 | ||||
-rw-r--r-- | fs/ocfs2/xattr.c | 14 |
8 files changed, 245 insertions, 39 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 69d67ab069bb..84a7bd4db5da 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/highmem.h> | 29 | #include <linux/highmem.h> |
30 | #include <linux/swap.h> | 30 | #include <linux/swap.h> |
31 | #include <linux/quotaops.h> | ||
31 | 32 | ||
32 | #define MLOG_MASK_PREFIX ML_DISK_ALLOC | 33 | #define MLOG_MASK_PREFIX ML_DISK_ALLOC |
33 | #include <cluster/masklog.h> | 34 | #include <cluster/masklog.h> |
@@ -5322,7 +5323,7 @@ int ocfs2_remove_btree_range(struct inode *inode, | |||
5322 | } | 5323 | } |
5323 | } | 5324 | } |
5324 | 5325 | ||
5325 | handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS); | 5326 | handle = ocfs2_start_trans(osb, ocfs2_remove_extent_credits(osb->sb)); |
5326 | if (IS_ERR(handle)) { | 5327 | if (IS_ERR(handle)) { |
5327 | ret = PTR_ERR(handle); | 5328 | ret = PTR_ERR(handle); |
5328 | mlog_errno(ret); | 5329 | mlog_errno(ret); |
@@ -6552,6 +6553,8 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb, | |||
6552 | goto bail; | 6553 | goto bail; |
6553 | } | 6554 | } |
6554 | 6555 | ||
6556 | vfs_dq_free_space_nodirty(inode, | ||
6557 | ocfs2_clusters_to_bytes(osb->sb, clusters_to_del)); | ||
6555 | spin_lock(&OCFS2_I(inode)->ip_lock); | 6558 | spin_lock(&OCFS2_I(inode)->ip_lock); |
6556 | OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters) - | 6559 | OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters) - |
6557 | clusters_to_del; | 6560 | clusters_to_del; |
@@ -6860,6 +6863,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
6860 | struct page **pages = NULL; | 6863 | struct page **pages = NULL; |
6861 | loff_t end = osb->s_clustersize; | 6864 | loff_t end = osb->s_clustersize; |
6862 | struct ocfs2_extent_tree et; | 6865 | struct ocfs2_extent_tree et; |
6866 | int did_quota = 0; | ||
6863 | 6867 | ||
6864 | has_data = i_size_read(inode) ? 1 : 0; | 6868 | has_data = i_size_read(inode) ? 1 : 0; |
6865 | 6869 | ||
@@ -6879,7 +6883,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
6879 | } | 6883 | } |
6880 | } | 6884 | } |
6881 | 6885 | ||
6882 | handle = ocfs2_start_trans(osb, OCFS2_INLINE_TO_EXTENTS_CREDITS); | 6886 | handle = ocfs2_start_trans(osb, |
6887 | ocfs2_inline_to_extents_credits(osb->sb)); | ||
6883 | if (IS_ERR(handle)) { | 6888 | if (IS_ERR(handle)) { |
6884 | ret = PTR_ERR(handle); | 6889 | ret = PTR_ERR(handle); |
6885 | mlog_errno(ret); | 6890 | mlog_errno(ret); |
@@ -6898,6 +6903,13 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
6898 | unsigned int page_end; | 6903 | unsigned int page_end; |
6899 | u64 phys; | 6904 | u64 phys; |
6900 | 6905 | ||
6906 | if (vfs_dq_alloc_space_nodirty(inode, | ||
6907 | ocfs2_clusters_to_bytes(osb->sb, 1))) { | ||
6908 | ret = -EDQUOT; | ||
6909 | goto out_commit; | ||
6910 | } | ||
6911 | did_quota = 1; | ||
6912 | |||
6901 | ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off, | 6913 | ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off, |
6902 | &num); | 6914 | &num); |
6903 | if (ret) { | 6915 | if (ret) { |
@@ -6971,6 +6983,10 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
6971 | } | 6983 | } |
6972 | 6984 | ||
6973 | out_commit: | 6985 | out_commit: |
6986 | if (ret < 0 && did_quota) | ||
6987 | vfs_dq_free_space_nodirty(inode, | ||
6988 | ocfs2_clusters_to_bytes(osb->sb, 1)); | ||
6989 | |||
6974 | ocfs2_commit_trans(osb, handle); | 6990 | ocfs2_commit_trans(osb, handle); |
6975 | 6991 | ||
6976 | out_unlock: | 6992 | out_unlock: |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 6af79adb2eca..6b647ec87bb3 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/swap.h> | 27 | #include <linux/swap.h> |
28 | #include <linux/pipe_fs_i.h> | 28 | #include <linux/pipe_fs_i.h> |
29 | #include <linux/mpage.h> | 29 | #include <linux/mpage.h> |
30 | #include <linux/quotaops.h> | ||
30 | 31 | ||
31 | #define MLOG_MASK_PREFIX ML_FILE_IO | 32 | #define MLOG_MASK_PREFIX ML_FILE_IO |
32 | #include <cluster/masklog.h> | 33 | #include <cluster/masklog.h> |
@@ -1730,6 +1731,11 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
1730 | 1731 | ||
1731 | wc->w_handle = handle; | 1732 | wc->w_handle = handle; |
1732 | 1733 | ||
1734 | if (clusters_to_alloc && vfs_dq_alloc_space_nodirty(inode, | ||
1735 | ocfs2_clusters_to_bytes(osb->sb, clusters_to_alloc))) { | ||
1736 | ret = -EDQUOT; | ||
1737 | goto out_commit; | ||
1738 | } | ||
1733 | /* | 1739 | /* |
1734 | * We don't want this to fail in ocfs2_write_end(), so do it | 1740 | * We don't want this to fail in ocfs2_write_end(), so do it |
1735 | * here. | 1741 | * here. |
@@ -1738,7 +1744,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
1738 | OCFS2_JOURNAL_ACCESS_WRITE); | 1744 | OCFS2_JOURNAL_ACCESS_WRITE); |
1739 | if (ret) { | 1745 | if (ret) { |
1740 | mlog_errno(ret); | 1746 | mlog_errno(ret); |
1741 | goto out_commit; | 1747 | goto out_quota; |
1742 | } | 1748 | } |
1743 | 1749 | ||
1744 | /* | 1750 | /* |
@@ -1751,14 +1757,14 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
1751 | mmap_page); | 1757 | mmap_page); |
1752 | if (ret) { | 1758 | if (ret) { |
1753 | mlog_errno(ret); | 1759 | mlog_errno(ret); |
1754 | goto out_commit; | 1760 | goto out_quota; |
1755 | } | 1761 | } |
1756 | 1762 | ||
1757 | ret = ocfs2_write_cluster_by_desc(mapping, data_ac, meta_ac, wc, pos, | 1763 | ret = ocfs2_write_cluster_by_desc(mapping, data_ac, meta_ac, wc, pos, |
1758 | len); | 1764 | len); |
1759 | if (ret) { | 1765 | if (ret) { |
1760 | mlog_errno(ret); | 1766 | mlog_errno(ret); |
1761 | goto out_commit; | 1767 | goto out_quota; |
1762 | } | 1768 | } |
1763 | 1769 | ||
1764 | if (data_ac) | 1770 | if (data_ac) |
@@ -1770,6 +1776,10 @@ success: | |||
1770 | *pagep = wc->w_target_page; | 1776 | *pagep = wc->w_target_page; |
1771 | *fsdata = wc; | 1777 | *fsdata = wc; |
1772 | return 0; | 1778 | return 0; |
1779 | out_quota: | ||
1780 | if (clusters_to_alloc) | ||
1781 | vfs_dq_free_space(inode, | ||
1782 | ocfs2_clusters_to_bytes(osb->sb, clusters_to_alloc)); | ||
1773 | out_commit: | 1783 | out_commit: |
1774 | ocfs2_commit_trans(osb, handle); | 1784 | ocfs2_commit_trans(osb, handle); |
1775 | 1785 | ||
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 | } |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 372d96505a79..9374d374a264 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/mount.h> | 35 | #include <linux/mount.h> |
36 | #include <linux/writeback.h> | 36 | #include <linux/writeback.h> |
37 | #include <linux/falloc.h> | 37 | #include <linux/falloc.h> |
38 | #include <linux/quotaops.h> | ||
38 | 39 | ||
39 | #define MLOG_MASK_PREFIX ML_INODE | 40 | #define MLOG_MASK_PREFIX ML_INODE |
40 | #include <cluster/masklog.h> | 41 | #include <cluster/masklog.h> |
@@ -57,6 +58,7 @@ | |||
57 | #include "super.h" | 58 | #include "super.h" |
58 | #include "xattr.h" | 59 | #include "xattr.h" |
59 | #include "acl.h" | 60 | #include "acl.h" |
61 | #include "quota.h" | ||
60 | 62 | ||
61 | #include "buffer_head_io.h" | 63 | #include "buffer_head_io.h" |
62 | 64 | ||
@@ -534,6 +536,7 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, | |||
534 | enum ocfs2_alloc_restarted why; | 536 | enum ocfs2_alloc_restarted why; |
535 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 537 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
536 | struct ocfs2_extent_tree et; | 538 | struct ocfs2_extent_tree et; |
539 | int did_quota = 0; | ||
537 | 540 | ||
538 | mlog_entry("(clusters_to_add = %u)\n", clusters_to_add); | 541 | mlog_entry("(clusters_to_add = %u)\n", clusters_to_add); |
539 | 542 | ||
@@ -577,6 +580,13 @@ restart_all: | |||
577 | } | 580 | } |
578 | 581 | ||
579 | restarted_transaction: | 582 | restarted_transaction: |
583 | if (vfs_dq_alloc_space_nodirty(inode, ocfs2_clusters_to_bytes(osb->sb, | ||
584 | clusters_to_add))) { | ||
585 | status = -EDQUOT; | ||
586 | goto leave; | ||
587 | } | ||
588 | did_quota = 1; | ||
589 | |||
580 | /* reserve a write to the file entry early on - that we if we | 590 | /* reserve a write to the file entry early on - that we if we |
581 | * run out of credits in the allocation path, we can still | 591 | * run out of credits in the allocation path, we can still |
582 | * update i_size. */ | 592 | * update i_size. */ |
@@ -614,6 +624,10 @@ restarted_transaction: | |||
614 | spin_lock(&OCFS2_I(inode)->ip_lock); | 624 | spin_lock(&OCFS2_I(inode)->ip_lock); |
615 | clusters_to_add -= (OCFS2_I(inode)->ip_clusters - prev_clusters); | 625 | clusters_to_add -= (OCFS2_I(inode)->ip_clusters - prev_clusters); |
616 | spin_unlock(&OCFS2_I(inode)->ip_lock); | 626 | spin_unlock(&OCFS2_I(inode)->ip_lock); |
627 | /* Release unused quota reservation */ | ||
628 | vfs_dq_free_space(inode, | ||
629 | ocfs2_clusters_to_bytes(osb->sb, clusters_to_add)); | ||
630 | did_quota = 0; | ||
617 | 631 | ||
618 | if (why != RESTART_NONE && clusters_to_add) { | 632 | if (why != RESTART_NONE && clusters_to_add) { |
619 | if (why == RESTART_META) { | 633 | if (why == RESTART_META) { |
@@ -646,6 +660,9 @@ restarted_transaction: | |||
646 | OCFS2_I(inode)->ip_clusters, (long long)i_size_read(inode)); | 660 | OCFS2_I(inode)->ip_clusters, (long long)i_size_read(inode)); |
647 | 661 | ||
648 | leave: | 662 | leave: |
663 | if (status < 0 && did_quota) | ||
664 | vfs_dq_free_space(inode, | ||
665 | ocfs2_clusters_to_bytes(osb->sb, clusters_to_add)); | ||
649 | if (handle) { | 666 | if (handle) { |
650 | ocfs2_commit_trans(osb, handle); | 667 | ocfs2_commit_trans(osb, handle); |
651 | handle = NULL; | 668 | handle = NULL; |
@@ -877,6 +894,9 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
877 | struct ocfs2_super *osb = OCFS2_SB(sb); | 894 | struct ocfs2_super *osb = OCFS2_SB(sb); |
878 | struct buffer_head *bh = NULL; | 895 | struct buffer_head *bh = NULL; |
879 | handle_t *handle = NULL; | 896 | handle_t *handle = NULL; |
897 | int locked[MAXQUOTAS] = {0, 0}; | ||
898 | int credits, qtype; | ||
899 | struct ocfs2_mem_dqinfo *oinfo; | ||
880 | 900 | ||
881 | mlog_entry("(0x%p, '%.*s')\n", dentry, | 901 | mlog_entry("(0x%p, '%.*s')\n", dentry, |
882 | dentry->d_name.len, dentry->d_name.name); | 902 | dentry->d_name.len, dentry->d_name.name); |
@@ -947,11 +967,47 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
947 | } | 967 | } |
948 | } | 968 | } |
949 | 969 | ||
950 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | 970 | if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || |
951 | if (IS_ERR(handle)) { | 971 | (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { |
952 | status = PTR_ERR(handle); | 972 | credits = OCFS2_INODE_UPDATE_CREDITS; |
953 | mlog_errno(status); | 973 | if (attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid |
954 | goto bail_unlock; | 974 | && OCFS2_HAS_RO_COMPAT_FEATURE(sb, |
975 | OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { | ||
976 | oinfo = sb_dqinfo(sb, USRQUOTA)->dqi_priv; | ||
977 | status = ocfs2_lock_global_qf(oinfo, 1); | ||
978 | if (status < 0) | ||
979 | goto bail_unlock; | ||
980 | credits += ocfs2_calc_qinit_credits(sb, USRQUOTA) + | ||
981 | ocfs2_calc_qdel_credits(sb, USRQUOTA); | ||
982 | locked[USRQUOTA] = 1; | ||
983 | } | ||
984 | if (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid | ||
985 | && OCFS2_HAS_RO_COMPAT_FEATURE(sb, | ||
986 | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { | ||
987 | oinfo = sb_dqinfo(sb, GRPQUOTA)->dqi_priv; | ||
988 | status = ocfs2_lock_global_qf(oinfo, 1); | ||
989 | if (status < 0) | ||
990 | goto bail_unlock; | ||
991 | credits += ocfs2_calc_qinit_credits(sb, GRPQUOTA) + | ||
992 | ocfs2_calc_qdel_credits(sb, GRPQUOTA); | ||
993 | locked[GRPQUOTA] = 1; | ||
994 | } | ||
995 | handle = ocfs2_start_trans(osb, credits); | ||
996 | if (IS_ERR(handle)) { | ||
997 | status = PTR_ERR(handle); | ||
998 | mlog_errno(status); | ||
999 | goto bail_unlock; | ||
1000 | } | ||
1001 | status = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; | ||
1002 | if (status < 0) | ||
1003 | goto bail_commit; | ||
1004 | } else { | ||
1005 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | ||
1006 | if (IS_ERR(handle)) { | ||
1007 | status = PTR_ERR(handle); | ||
1008 | mlog_errno(status); | ||
1009 | goto bail_unlock; | ||
1010 | } | ||
955 | } | 1011 | } |
956 | 1012 | ||
957 | /* | 1013 | /* |
@@ -974,6 +1030,12 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
974 | bail_commit: | 1030 | bail_commit: |
975 | ocfs2_commit_trans(osb, handle); | 1031 | ocfs2_commit_trans(osb, handle); |
976 | bail_unlock: | 1032 | bail_unlock: |
1033 | for (qtype = 0; qtype < MAXQUOTAS; qtype++) { | ||
1034 | if (!locked[qtype]) | ||
1035 | continue; | ||
1036 | oinfo = sb_dqinfo(sb, qtype)->dqi_priv; | ||
1037 | ocfs2_unlock_global_qf(oinfo, 1); | ||
1038 | } | ||
977 | ocfs2_inode_unlock(inode, 1); | 1039 | ocfs2_inode_unlock(inode, 1); |
978 | bail_unlock_rw: | 1040 | bail_unlock_rw: |
979 | if (size_change) | 1041 | if (size_change) |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 50dbc486ef71..288512c9dbc2 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/highmem.h> | 29 | #include <linux/highmem.h> |
30 | #include <linux/pagemap.h> | 30 | #include <linux/pagemap.h> |
31 | #include <linux/quotaops.h> | ||
31 | 32 | ||
32 | #include <asm/byteorder.h> | 33 | #include <asm/byteorder.h> |
33 | 34 | ||
@@ -603,7 +604,8 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
603 | goto bail; | 604 | goto bail; |
604 | } | 605 | } |
605 | 606 | ||
606 | handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS); | 607 | handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS + |
608 | ocfs2_quota_trans_credits(inode->i_sb)); | ||
607 | if (IS_ERR(handle)) { | 609 | if (IS_ERR(handle)) { |
608 | status = PTR_ERR(handle); | 610 | status = PTR_ERR(handle); |
609 | mlog_errno(status); | 611 | mlog_errno(status); |
@@ -635,6 +637,7 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
635 | } | 637 | } |
636 | 638 | ||
637 | ocfs2_remove_from_cache(inode, di_bh); | 639 | ocfs2_remove_from_cache(inode, di_bh); |
640 | vfs_dq_free_inode(inode); | ||
638 | 641 | ||
639 | status = ocfs2_free_dinode(handle, inode_alloc_inode, | 642 | status = ocfs2_free_dinode(handle, inode_alloc_inode, |
640 | inode_alloc_bh, di); | 643 | inode_alloc_bh, di); |
@@ -917,7 +920,10 @@ void ocfs2_delete_inode(struct inode *inode) | |||
917 | 920 | ||
918 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); | 921 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); |
919 | 922 | ||
920 | if (is_bad_inode(inode)) { | 923 | /* When we fail in read_inode() we mark inode as bad. The second test |
924 | * catches the case when inode allocation fails before allocating | ||
925 | * a block for inode. */ | ||
926 | if (is_bad_inode(inode) || !OCFS2_I(inode)->ip_blkno) { | ||
921 | mlog(0, "Skipping delete of bad inode\n"); | 927 | mlog(0, "Skipping delete of bad inode\n"); |
922 | goto bail; | 928 | goto bail; |
923 | } | 929 | } |
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h index 8203980fefed..ee08e9c1fc12 100644 --- a/fs/ocfs2/journal.h +++ b/fs/ocfs2/journal.h | |||
@@ -284,6 +284,37 @@ int ocfs2_journal_dirty(handle_t *handle, | |||
284 | /* extended attribute block update */ | 284 | /* extended attribute block update */ |
285 | #define OCFS2_XATTR_BLOCK_UPDATE_CREDITS 1 | 285 | #define OCFS2_XATTR_BLOCK_UPDATE_CREDITS 1 |
286 | 286 | ||
287 | /* global quotafile inode update, data block */ | ||
288 | #define OCFS2_QINFO_WRITE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1) | ||
289 | |||
290 | /* | ||
291 | * The two writes below can accidentally see global info dirty due | ||
292 | * to set_info() quotactl so make them prepared for the writes. | ||
293 | */ | ||
294 | /* quota data block, global info */ | ||
295 | /* Write to local quota file */ | ||
296 | #define OCFS2_QWRITE_CREDITS (OCFS2_QINFO_WRITE_CREDITS + 1) | ||
297 | |||
298 | /* global quota data block, local quota data block, global quota inode, | ||
299 | * global quota info */ | ||
300 | #define OCFS2_QSYNC_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 3) | ||
301 | |||
302 | static inline int ocfs2_quota_trans_credits(struct super_block *sb) | ||
303 | { | ||
304 | int credits = 0; | ||
305 | |||
306 | if (OCFS2_HAS_RO_COMPAT_FEATURE(sb, OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) | ||
307 | credits += OCFS2_QWRITE_CREDITS; | ||
308 | if (OCFS2_HAS_RO_COMPAT_FEATURE(sb, OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) | ||
309 | credits += OCFS2_QWRITE_CREDITS; | ||
310 | return credits; | ||
311 | } | ||
312 | |||
313 | /* Number of credits needed for removing quota structure from file */ | ||
314 | int ocfs2_calc_qdel_credits(struct super_block *sb, int type); | ||
315 | /* Number of credits needed for initialization of new quota structure */ | ||
316 | int ocfs2_calc_qinit_credits(struct super_block *sb, int type); | ||
317 | |||
287 | /* group extend. inode update and last group update. */ | 318 | /* group extend. inode update and last group update. */ |
288 | #define OCFS2_GROUP_EXTEND_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1) | 319 | #define OCFS2_GROUP_EXTEND_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1) |
289 | 320 | ||
@@ -294,8 +325,11 @@ int ocfs2_journal_dirty(handle_t *handle, | |||
294 | * prev. group desc. if we relink. */ | 325 | * prev. group desc. if we relink. */ |
295 | #define OCFS2_SUBALLOC_ALLOC (3) | 326 | #define OCFS2_SUBALLOC_ALLOC (3) |
296 | 327 | ||
297 | #define OCFS2_INLINE_TO_EXTENTS_CREDITS (OCFS2_SUBALLOC_ALLOC \ | 328 | static inline int ocfs2_inline_to_extents_credits(struct super_block *sb) |
298 | + OCFS2_INODE_UPDATE_CREDITS) | 329 | { |
330 | return OCFS2_SUBALLOC_ALLOC + OCFS2_INODE_UPDATE_CREDITS + | ||
331 | ocfs2_quota_trans_credits(sb); | ||
332 | } | ||
299 | 333 | ||
300 | /* dinode + group descriptor update. We don't relink on free yet. */ | 334 | /* dinode + group descriptor update. We don't relink on free yet. */ |
301 | #define OCFS2_SUBALLOC_FREE (2) | 335 | #define OCFS2_SUBALLOC_FREE (2) |
@@ -304,16 +338,23 @@ int ocfs2_journal_dirty(handle_t *handle, | |||
304 | #define OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC (OCFS2_SUBALLOC_FREE \ | 338 | #define OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC (OCFS2_SUBALLOC_FREE \ |
305 | + OCFS2_TRUNCATE_LOG_UPDATE) | 339 | + OCFS2_TRUNCATE_LOG_UPDATE) |
306 | 340 | ||
307 | #define OCFS2_REMOVE_EXTENT_CREDITS (OCFS2_TRUNCATE_LOG_UPDATE + OCFS2_INODE_UPDATE_CREDITS) | 341 | static inline int ocfs2_remove_extent_credits(struct super_block *sb) |
342 | { | ||
343 | return OCFS2_TRUNCATE_LOG_UPDATE + OCFS2_INODE_UPDATE_CREDITS + | ||
344 | ocfs2_quota_trans_credits(sb); | ||
345 | } | ||
308 | 346 | ||
309 | /* data block for new dir/symlink, 2 for bitmap updates (bitmap fe + | 347 | /* data block for new dir/symlink, 2 for bitmap updates (bitmap fe + |
310 | * bitmap block for the new bit) */ | 348 | * bitmap block for the new bit) */ |
311 | #define OCFS2_DIR_LINK_ADDITIONAL_CREDITS (1 + 2) | 349 | #define OCFS2_DIR_LINK_ADDITIONAL_CREDITS (1 + 2) |
312 | 350 | ||
313 | /* parent fe, parent block, new file entry, inode alloc fe, inode alloc | 351 | /* parent fe, parent block, new file entry, inode alloc fe, inode alloc |
314 | * group descriptor + mkdir/symlink blocks */ | 352 | * group descriptor + mkdir/symlink blocks + quota update */ |
315 | #define OCFS2_MKNOD_CREDITS (3 + OCFS2_SUBALLOC_ALLOC \ | 353 | static inline int ocfs2_mknod_credits(struct super_block *sb) |
316 | + OCFS2_DIR_LINK_ADDITIONAL_CREDITS) | 354 | { |
355 | return 3 + OCFS2_SUBALLOC_ALLOC + OCFS2_DIR_LINK_ADDITIONAL_CREDITS + | ||
356 | ocfs2_quota_trans_credits(sb); | ||
357 | } | ||
317 | 358 | ||
318 | /* local alloc metadata change + main bitmap updates */ | 359 | /* local alloc metadata change + main bitmap updates */ |
319 | #define OCFS2_WINDOW_MOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS \ | 360 | #define OCFS2_WINDOW_MOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS \ |
@@ -323,13 +364,21 @@ int ocfs2_journal_dirty(handle_t *handle, | |||
323 | * for the dinode, one for the new block. */ | 364 | * for the dinode, one for the new block. */ |
324 | #define OCFS2_SIMPLE_DIR_EXTEND_CREDITS (2) | 365 | #define OCFS2_SIMPLE_DIR_EXTEND_CREDITS (2) |
325 | 366 | ||
326 | /* file update (nlink, etc) + directory mtime/ctime + dir entry block */ | 367 | /* file update (nlink, etc) + directory mtime/ctime + dir entry block + quota |
327 | #define OCFS2_LINK_CREDITS (2*OCFS2_INODE_UPDATE_CREDITS + 1) | 368 | * update on dir */ |
369 | static inline int ocfs2_link_credits(struct super_block *sb) | ||
370 | { | ||
371 | return 2*OCFS2_INODE_UPDATE_CREDITS + 1 + | ||
372 | ocfs2_quota_trans_credits(sb); | ||
373 | } | ||
328 | 374 | ||
329 | /* inode + dir inode (if we unlink a dir), + dir entry block + orphan | 375 | /* inode + dir inode (if we unlink a dir), + dir entry block + orphan |
330 | * dir inode link */ | 376 | * dir inode link */ |
331 | #define OCFS2_UNLINK_CREDITS (2 * OCFS2_INODE_UPDATE_CREDITS + 1 \ | 377 | static inline int ocfs2_unlink_credits(struct super_block *sb) |
332 | + OCFS2_LINK_CREDITS) | 378 | { |
379 | /* The quota update from ocfs2_link_credits is unused here... */ | ||
380 | return 2 * OCFS2_INODE_UPDATE_CREDITS + 1 + ocfs2_link_credits(sb); | ||
381 | } | ||
333 | 382 | ||
334 | /* dinode + orphan dir dinode + inode alloc dinode + orphan dir entry + | 383 | /* dinode + orphan dir dinode + inode alloc dinode + orphan dir entry + |
335 | * inode alloc group descriptor */ | 384 | * inode alloc group descriptor */ |
@@ -338,8 +387,10 @@ int ocfs2_journal_dirty(handle_t *handle, | |||
338 | /* dinode update, old dir dinode update, new dir dinode update, old | 387 | /* dinode update, old dir dinode update, new dir dinode update, old |
339 | * dir dir entry, new dir dir entry, dir entry update for renaming | 388 | * dir dir entry, new dir dir entry, dir entry update for renaming |
340 | * directory + target unlink */ | 389 | * directory + target unlink */ |
341 | #define OCFS2_RENAME_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 3 \ | 390 | static inline int ocfs2_rename_credits(struct super_block *sb) |
342 | + OCFS2_UNLINK_CREDITS) | 391 | { |
392 | return 3 * OCFS2_INODE_UPDATE_CREDITS + 3 + ocfs2_unlink_credits(sb); | ||
393 | } | ||
343 | 394 | ||
344 | /* global bitmap dinode, group desc., relinked group, | 395 | /* global bitmap dinode, group desc., relinked group, |
345 | * suballocator dinode, group desc., relinked group, | 396 | * suballocator dinode, group desc., relinked group, |
@@ -377,18 +428,19 @@ static inline int ocfs2_calc_extend_credits(struct super_block *sb, | |||
377 | * credit for the dinode there. */ | 428 | * credit for the dinode there. */ |
378 | extent_blocks = 1 + 1 + le16_to_cpu(root_el->l_tree_depth); | 429 | extent_blocks = 1 + 1 + le16_to_cpu(root_el->l_tree_depth); |
379 | 430 | ||
380 | return bitmap_blocks + sysfile_bitmap_blocks + extent_blocks; | 431 | return bitmap_blocks + sysfile_bitmap_blocks + extent_blocks + |
432 | ocfs2_quota_trans_credits(sb); | ||
381 | } | 433 | } |
382 | 434 | ||
383 | static inline int ocfs2_calc_symlink_credits(struct super_block *sb) | 435 | static inline int ocfs2_calc_symlink_credits(struct super_block *sb) |
384 | { | 436 | { |
385 | int blocks = OCFS2_MKNOD_CREDITS; | 437 | int blocks = ocfs2_mknod_credits(sb); |
386 | 438 | ||
387 | /* links can be longer than one block so we may update many | 439 | /* links can be longer than one block so we may update many |
388 | * within our single allocated extent. */ | 440 | * within our single allocated extent. */ |
389 | blocks += ocfs2_clusters_to_blocks(sb, 1); | 441 | blocks += ocfs2_clusters_to_blocks(sb, 1); |
390 | 442 | ||
391 | return blocks; | 443 | return blocks + ocfs2_quota_trans_credits(sb); |
392 | } | 444 | } |
393 | 445 | ||
394 | static inline int ocfs2_calc_group_alloc_credits(struct super_block *sb, | 446 | static inline int ocfs2_calc_group_alloc_credits(struct super_block *sb, |
@@ -425,6 +477,8 @@ static inline int ocfs2_calc_tree_trunc_credits(struct super_block *sb, | |||
425 | /* update to the truncate log. */ | 477 | /* update to the truncate log. */ |
426 | credits += OCFS2_TRUNCATE_LOG_UPDATE; | 478 | credits += OCFS2_TRUNCATE_LOG_UPDATE; |
427 | 479 | ||
480 | credits += ocfs2_quota_trans_credits(sb); | ||
481 | |||
428 | return credits; | 482 | return credits; |
429 | } | 483 | } |
430 | 484 | ||
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 0134bafdab9e..6173807ba23b 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.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> |
@@ -212,6 +213,7 @@ static struct inode *ocfs2_get_init_inode(struct inode *dir, int mode) | |||
212 | } else | 213 | } else |
213 | inode->i_gid = current_fsgid(); | 214 | inode->i_gid = current_fsgid(); |
214 | inode->i_mode = mode; | 215 | inode->i_mode = mode; |
216 | vfs_dq_init(inode); | ||
215 | return inode; | 217 | return inode; |
216 | } | 218 | } |
217 | 219 | ||
@@ -236,6 +238,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
236 | struct ocfs2_security_xattr_info si = { | 238 | struct ocfs2_security_xattr_info si = { |
237 | .enable = 1, | 239 | .enable = 1, |
238 | }; | 240 | }; |
241 | int did_quota_inode = 0; | ||
239 | 242 | ||
240 | mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode, | 243 | mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode, |
241 | (unsigned long)dev, dentry->d_name.len, | 244 | (unsigned long)dev, dentry->d_name.len, |
@@ -323,7 +326,8 @@ static int ocfs2_mknod(struct inode *dir, | |||
323 | goto leave; | 326 | goto leave; |
324 | } | 327 | } |
325 | 328 | ||
326 | handle = ocfs2_start_trans(osb, OCFS2_MKNOD_CREDITS + xattr_credits); | 329 | handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb) + |
330 | xattr_credits); | ||
327 | if (IS_ERR(handle)) { | 331 | if (IS_ERR(handle)) { |
328 | status = PTR_ERR(handle); | 332 | status = PTR_ERR(handle); |
329 | handle = NULL; | 333 | handle = NULL; |
@@ -331,6 +335,15 @@ static int ocfs2_mknod(struct inode *dir, | |||
331 | goto leave; | 335 | goto leave; |
332 | } | 336 | } |
333 | 337 | ||
338 | /* We don't use standard VFS wrapper because we don't want vfs_dq_init | ||
339 | * to be called. */ | ||
340 | if (sb_any_quota_active(osb->sb) && | ||
341 | osb->sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) { | ||
342 | status = -EDQUOT; | ||
343 | goto leave; | ||
344 | } | ||
345 | did_quota_inode = 1; | ||
346 | |||
334 | /* do the real work now. */ | 347 | /* do the real work now. */ |
335 | status = ocfs2_mknod_locked(osb, dir, inode, dentry, dev, | 348 | status = ocfs2_mknod_locked(osb, dir, inode, dentry, dev, |
336 | &new_fe_bh, parent_fe_bh, handle, | 349 | &new_fe_bh, parent_fe_bh, handle, |
@@ -399,6 +412,8 @@ static int ocfs2_mknod(struct inode *dir, | |||
399 | d_instantiate(dentry, inode); | 412 | d_instantiate(dentry, inode); |
400 | status = 0; | 413 | status = 0; |
401 | leave: | 414 | leave: |
415 | if (status < 0 && did_quota_inode) | ||
416 | vfs_dq_free_inode(inode); | ||
402 | if (handle) | 417 | if (handle) |
403 | ocfs2_commit_trans(osb, handle); | 418 | ocfs2_commit_trans(osb, handle); |
404 | 419 | ||
@@ -641,7 +656,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
641 | goto out_unlock_inode; | 656 | goto out_unlock_inode; |
642 | } | 657 | } |
643 | 658 | ||
644 | handle = ocfs2_start_trans(osb, OCFS2_LINK_CREDITS); | 659 | handle = ocfs2_start_trans(osb, ocfs2_link_credits(osb->sb)); |
645 | if (IS_ERR(handle)) { | 660 | if (IS_ERR(handle)) { |
646 | err = PTR_ERR(handle); | 661 | err = PTR_ERR(handle); |
647 | handle = NULL; | 662 | handle = NULL; |
@@ -828,7 +843,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
828 | } | 843 | } |
829 | } | 844 | } |
830 | 845 | ||
831 | handle = ocfs2_start_trans(osb, OCFS2_UNLINK_CREDITS); | 846 | handle = ocfs2_start_trans(osb, ocfs2_unlink_credits(osb->sb)); |
832 | if (IS_ERR(handle)) { | 847 | if (IS_ERR(handle)) { |
833 | status = PTR_ERR(handle); | 848 | status = PTR_ERR(handle); |
834 | handle = NULL; | 849 | handle = NULL; |
@@ -1234,7 +1249,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1234 | } | 1249 | } |
1235 | } | 1250 | } |
1236 | 1251 | ||
1237 | handle = ocfs2_start_trans(osb, OCFS2_RENAME_CREDITS); | 1252 | handle = ocfs2_start_trans(osb, ocfs2_rename_credits(osb->sb)); |
1238 | if (IS_ERR(handle)) { | 1253 | if (IS_ERR(handle)) { |
1239 | status = PTR_ERR(handle); | 1254 | status = PTR_ERR(handle); |
1240 | handle = NULL; | 1255 | handle = NULL; |
@@ -1555,6 +1570,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1555 | struct ocfs2_security_xattr_info si = { | 1570 | struct ocfs2_security_xattr_info si = { |
1556 | .enable = 1, | 1571 | .enable = 1, |
1557 | }; | 1572 | }; |
1573 | int did_quota = 0, did_quota_inode = 0; | ||
1558 | 1574 | ||
1559 | mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir, | 1575 | mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir, |
1560 | dentry, symname, dentry->d_name.len, dentry->d_name.name); | 1576 | dentry, symname, dentry->d_name.len, dentry->d_name.name); |
@@ -1648,6 +1664,15 @@ static int ocfs2_symlink(struct inode *dir, | |||
1648 | goto bail; | 1664 | goto bail; |
1649 | } | 1665 | } |
1650 | 1666 | ||
1667 | /* We don't use standard VFS wrapper because we don't want vfs_dq_init | ||
1668 | * to be called. */ | ||
1669 | if (sb_any_quota_active(osb->sb) && | ||
1670 | osb->sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) { | ||
1671 | status = -EDQUOT; | ||
1672 | goto bail; | ||
1673 | } | ||
1674 | did_quota_inode = 1; | ||
1675 | |||
1651 | status = ocfs2_mknod_locked(osb, dir, inode, dentry, | 1676 | status = ocfs2_mknod_locked(osb, dir, inode, dentry, |
1652 | 0, &new_fe_bh, parent_fe_bh, handle, | 1677 | 0, &new_fe_bh, parent_fe_bh, handle, |
1653 | inode_ac); | 1678 | inode_ac); |
@@ -1663,6 +1688,12 @@ static int ocfs2_symlink(struct inode *dir, | |||
1663 | u32 offset = 0; | 1688 | u32 offset = 0; |
1664 | 1689 | ||
1665 | inode->i_op = &ocfs2_symlink_inode_operations; | 1690 | inode->i_op = &ocfs2_symlink_inode_operations; |
1691 | if (vfs_dq_alloc_space_nodirty(inode, | ||
1692 | ocfs2_clusters_to_bytes(osb->sb, 1))) { | ||
1693 | status = -EDQUOT; | ||
1694 | goto bail; | ||
1695 | } | ||
1696 | did_quota = 1; | ||
1666 | status = ocfs2_add_inode_data(osb, inode, &offset, 1, 0, | 1697 | status = ocfs2_add_inode_data(osb, inode, &offset, 1, 0, |
1667 | new_fe_bh, | 1698 | new_fe_bh, |
1668 | handle, data_ac, NULL, | 1699 | handle, data_ac, NULL, |
@@ -1728,6 +1759,11 @@ static int ocfs2_symlink(struct inode *dir, | |||
1728 | dentry->d_op = &ocfs2_dentry_ops; | 1759 | dentry->d_op = &ocfs2_dentry_ops; |
1729 | d_instantiate(dentry, inode); | 1760 | d_instantiate(dentry, inode); |
1730 | bail: | 1761 | bail: |
1762 | if (status < 0 && did_quota) | ||
1763 | vfs_dq_free_space_nodirty(inode, | ||
1764 | ocfs2_clusters_to_bytes(osb->sb, 1)); | ||
1765 | if (status < 0 && did_quota_inode) | ||
1766 | vfs_dq_free_inode(inode); | ||
1731 | if (handle) | 1767 | if (handle) |
1732 | ocfs2_commit_trans(osb, handle); | 1768 | ocfs2_commit_trans(osb, handle); |
1733 | 1769 | ||
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 9cb71e1c7c60..3b9634c7d296 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -1665,7 +1665,8 @@ static int ocfs2_remove_value_outside(struct inode*inode, | |||
1665 | 1665 | ||
1666 | ocfs2_init_dealloc_ctxt(&ctxt.dealloc); | 1666 | ocfs2_init_dealloc_ctxt(&ctxt.dealloc); |
1667 | 1667 | ||
1668 | ctxt.handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS); | 1668 | ctxt.handle = ocfs2_start_trans(osb, |
1669 | ocfs2_remove_extent_credits(osb->sb)); | ||
1669 | if (IS_ERR(ctxt.handle)) { | 1670 | if (IS_ERR(ctxt.handle)) { |
1670 | ret = PTR_ERR(ctxt.handle); | 1671 | ret = PTR_ERR(ctxt.handle); |
1671 | mlog_errno(ret); | 1672 | mlog_errno(ret); |
@@ -2233,7 +2234,7 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode, | |||
2233 | */ | 2234 | */ |
2234 | if (!xi->value) { | 2235 | if (!xi->value) { |
2235 | if (!ocfs2_xattr_is_local(xe)) | 2236 | if (!ocfs2_xattr_is_local(xe)) |
2236 | credits += OCFS2_REMOVE_EXTENT_CREDITS; | 2237 | credits += ocfs2_remove_extent_credits(inode->i_sb); |
2237 | 2238 | ||
2238 | goto out; | 2239 | goto out; |
2239 | } | 2240 | } |
@@ -2250,7 +2251,7 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode, | |||
2250 | */ | 2251 | */ |
2251 | if (ocfs2_xattr_can_be_in_inode(inode, xi, xis)) { | 2252 | if (ocfs2_xattr_can_be_in_inode(inode, xi, xis)) { |
2252 | clusters_add += new_clusters; | 2253 | clusters_add += new_clusters; |
2253 | credits += OCFS2_REMOVE_EXTENT_CREDITS + | 2254 | credits += ocfs2_remove_extent_credits(inode->i_sb) + |
2254 | OCFS2_INODE_UPDATE_CREDITS; | 2255 | OCFS2_INODE_UPDATE_CREDITS; |
2255 | if (!ocfs2_xattr_is_local(xe)) | 2256 | if (!ocfs2_xattr_is_local(xe)) |
2256 | credits += ocfs2_calc_extend_credits( | 2257 | credits += ocfs2_calc_extend_credits( |
@@ -2275,7 +2276,7 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode, | |||
2275 | xv = &def_xv.xv; | 2276 | xv = &def_xv.xv; |
2276 | 2277 | ||
2277 | if (old_clusters >= new_clusters) { | 2278 | if (old_clusters >= new_clusters) { |
2278 | credits += OCFS2_REMOVE_EXTENT_CREDITS; | 2279 | credits += ocfs2_remove_extent_credits(inode->i_sb); |
2279 | goto out; | 2280 | goto out; |
2280 | } else { | 2281 | } else { |
2281 | meta_add += ocfs2_extend_meta_needed(&xv->xr_list); | 2282 | meta_add += ocfs2_extend_meta_needed(&xv->xr_list); |
@@ -4750,7 +4751,7 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode, | |||
4750 | } | 4751 | } |
4751 | } | 4752 | } |
4752 | 4753 | ||
4753 | handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS); | 4754 | handle = ocfs2_start_trans(osb, ocfs2_remove_extent_credits(osb->sb)); |
4754 | if (IS_ERR(handle)) { | 4755 | if (IS_ERR(handle)) { |
4755 | ret = -ENOMEM; | 4756 | ret = -ENOMEM; |
4756 | mlog_errno(ret); | 4757 | mlog_errno(ret); |
@@ -5109,7 +5110,8 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode, | |||
5109 | 5110 | ||
5110 | ocfs2_init_dealloc_ctxt(&ctxt.dealloc); | 5111 | ocfs2_init_dealloc_ctxt(&ctxt.dealloc); |
5111 | 5112 | ||
5112 | ctxt.handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS); | 5113 | ctxt.handle = ocfs2_start_trans(osb, |
5114 | ocfs2_remove_extent_credits(osb->sb)); | ||
5113 | if (IS_ERR(ctxt.handle)) { | 5115 | if (IS_ERR(ctxt.handle)) { |
5114 | ret = PTR_ERR(ctxt.handle); | 5116 | ret = PTR_ERR(ctxt.handle); |
5115 | mlog_errno(ret); | 5117 | mlog_errno(ret); |