aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-10-09 13:38:40 -0400
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:40:23 -0500
commita90714c150e3ce677c57a9dac3ab1ec342c75a95 (patch)
tree43e3e744d86122940c0db39ac1bfed0d434b3216 /fs
parent9e33d69f553aaf11377307e8d6f82deb3385e351 (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')
-rw-r--r--fs/ocfs2/alloc.c20
-rw-r--r--fs/ocfs2/aops.c16
-rw-r--r--fs/ocfs2/dir.c24
-rw-r--r--fs/ocfs2/file.c72
-rw-r--r--fs/ocfs2/inode.c10
-rw-r--r--fs/ocfs2/journal.h84
-rw-r--r--fs/ocfs2/namei.c44
-rw-r--r--fs/ocfs2/xattr.c14
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
6973out_commit: 6985out_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
6976out_unlock: 6992out_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;
1779out_quota:
1780 if (clusters_to_alloc)
1781 vfs_dq_free_space(inode,
1782 ocfs2_clusters_to_bytes(osb->sb, clusters_to_alloc));
1773out_commit: 1783out_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
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}
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
579restarted_transaction: 582restarted_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
648leave: 662leave:
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)
974bail_commit: 1030bail_commit:
975 ocfs2_commit_trans(osb, handle); 1031 ocfs2_commit_trans(osb, handle);
976bail_unlock: 1032bail_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);
978bail_unlock_rw: 1040bail_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
302static 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 */
314int ocfs2_calc_qdel_credits(struct super_block *sb, int type);
315/* Number of credits needed for initialization of new quota structure */
316int 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 \ 328static 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) 341static 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 \ 353static 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 */
369static 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 \ 377static 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 \ 390static 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
383static inline int ocfs2_calc_symlink_credits(struct super_block *sb) 435static 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
394static inline int ocfs2_calc_group_alloc_credits(struct super_block *sb, 446static 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;
401leave: 414leave:
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);
1730bail: 1761bail:
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);