aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/quota_local.c98
1 files changed, 83 insertions, 15 deletions
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index b624f9bc9281..9d2993de1082 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -941,7 +941,7 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
941 struct ocfs2_local_disk_chunk *dchunk; 941 struct ocfs2_local_disk_chunk *dchunk;
942 int status; 942 int status;
943 handle_t *handle; 943 handle_t *handle;
944 struct buffer_head *bh = NULL; 944 struct buffer_head *bh = NULL, *dbh = NULL;
945 u64 p_blkno; 945 u64 p_blkno;
946 946
947 /* We are protected by dqio_sem so no locking needed */ 947 /* We are protected by dqio_sem so no locking needed */
@@ -965,34 +965,32 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
965 mlog_errno(status); 965 mlog_errno(status);
966 goto out; 966 goto out;
967 } 967 }
968 handle = ocfs2_start_trans(OCFS2_SB(sb), 3);
969 if (IS_ERR(handle)) {
970 status = PTR_ERR(handle);
971 mlog_errno(status);
972 goto out;
973 }
968 974
975 /* Initialize chunk header */
969 down_read(&OCFS2_I(lqinode)->ip_alloc_sem); 976 down_read(&OCFS2_I(lqinode)->ip_alloc_sem);
970 status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks, 977 status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks,
971 &p_blkno, NULL, NULL); 978 &p_blkno, NULL, NULL);
972 up_read(&OCFS2_I(lqinode)->ip_alloc_sem); 979 up_read(&OCFS2_I(lqinode)->ip_alloc_sem);
973 if (status < 0) { 980 if (status < 0) {
974 mlog_errno(status); 981 mlog_errno(status);
975 goto out; 982 goto out_trans;
976 } 983 }
977 bh = sb_getblk(sb, p_blkno); 984 bh = sb_getblk(sb, p_blkno);
978 if (!bh) { 985 if (!bh) {
979 status = -ENOMEM; 986 status = -ENOMEM;
980 mlog_errno(status); 987 mlog_errno(status);
981 goto out; 988 goto out_trans;
982 } 989 }
983 ocfs2_set_new_buffer_uptodate(lqinode, bh);
984
985 dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data; 990 dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data;
986 991 ocfs2_set_new_buffer_uptodate(lqinode, bh);
987 handle = ocfs2_start_trans(OCFS2_SB(sb), 2);
988 if (IS_ERR(handle)) {
989 status = PTR_ERR(handle);
990 mlog_errno(status);
991 goto out;
992 }
993
994 status = ocfs2_journal_access_dq(handle, lqinode, bh, 992 status = ocfs2_journal_access_dq(handle, lqinode, bh,
995 OCFS2_JOURNAL_ACCESS_WRITE); 993 OCFS2_JOURNAL_ACCESS_CREATE);
996 if (status < 0) { 994 if (status < 0) {
997 mlog_errno(status); 995 mlog_errno(status);
998 goto out_trans; 996 goto out_trans;
@@ -1009,6 +1007,38 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
1009 goto out_trans; 1007 goto out_trans;
1010 } 1008 }
1011 1009
1010 /* Initialize new block with structures */
1011 down_read(&OCFS2_I(lqinode)->ip_alloc_sem);
1012 status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks + 1,
1013 &p_blkno, NULL, NULL);
1014 up_read(&OCFS2_I(lqinode)->ip_alloc_sem);
1015 if (status < 0) {
1016 mlog_errno(status);
1017 goto out_trans;
1018 }
1019 dbh = sb_getblk(sb, p_blkno);
1020 if (!dbh) {
1021 status = -ENOMEM;
1022 mlog_errno(status);
1023 goto out_trans;
1024 }
1025 ocfs2_set_new_buffer_uptodate(lqinode, dbh);
1026 status = ocfs2_journal_access_dq(handle, lqinode, dbh,
1027 OCFS2_JOURNAL_ACCESS_CREATE);
1028 if (status < 0) {
1029 mlog_errno(status);
1030 goto out_trans;
1031 }
1032 lock_buffer(dbh);
1033 memset(dbh->b_data, 0, sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE);
1034 unlock_buffer(dbh);
1035 status = ocfs2_journal_dirty(handle, dbh);
1036 if (status < 0) {
1037 mlog_errno(status);
1038 goto out_trans;
1039 }
1040
1041 /* Update local quotafile info */
1012 oinfo->dqi_blocks += 2; 1042 oinfo->dqi_blocks += 2;
1013 oinfo->dqi_chunks++; 1043 oinfo->dqi_chunks++;
1014 status = ocfs2_local_write_info(sb, type); 1044 status = ocfs2_local_write_info(sb, type);
@@ -1033,6 +1063,7 @@ out_trans:
1033 ocfs2_commit_trans(OCFS2_SB(sb), handle); 1063 ocfs2_commit_trans(OCFS2_SB(sb), handle);
1034out: 1064out:
1035 brelse(bh); 1065 brelse(bh);
1066 brelse(dbh);
1036 kmem_cache_free(ocfs2_qf_chunk_cachep, chunk); 1067 kmem_cache_free(ocfs2_qf_chunk_cachep, chunk);
1037 return ERR_PTR(status); 1068 return ERR_PTR(status);
1038} 1069}
@@ -1050,6 +1081,8 @@ static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file(
1050 struct ocfs2_local_disk_chunk *dchunk; 1081 struct ocfs2_local_disk_chunk *dchunk;
1051 int epb = ol_quota_entries_per_block(sb); 1082 int epb = ol_quota_entries_per_block(sb);
1052 unsigned int chunk_blocks; 1083 unsigned int chunk_blocks;
1084 struct buffer_head *bh;
1085 u64 p_blkno;
1053 int status; 1086 int status;
1054 handle_t *handle; 1087 handle_t *handle;
1055 1088
@@ -1077,12 +1110,46 @@ static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file(
1077 mlog_errno(status); 1110 mlog_errno(status);
1078 goto out; 1111 goto out;
1079 } 1112 }
1080 handle = ocfs2_start_trans(OCFS2_SB(sb), 2); 1113
1114 /* Get buffer from the just added block */
1115 down_read(&OCFS2_I(lqinode)->ip_alloc_sem);
1116 status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks,
1117 &p_blkno, NULL, NULL);
1118 up_read(&OCFS2_I(lqinode)->ip_alloc_sem);
1119 if (status < 0) {
1120 mlog_errno(status);
1121 goto out;
1122 }
1123 bh = sb_getblk(sb, p_blkno);
1124 if (!bh) {
1125 status = -ENOMEM;
1126 mlog_errno(status);
1127 goto out;
1128 }
1129 ocfs2_set_new_buffer_uptodate(lqinode, bh);
1130
1131 handle = ocfs2_start_trans(OCFS2_SB(sb), 3);
1081 if (IS_ERR(handle)) { 1132 if (IS_ERR(handle)) {
1082 status = PTR_ERR(handle); 1133 status = PTR_ERR(handle);
1083 mlog_errno(status); 1134 mlog_errno(status);
1084 goto out; 1135 goto out;
1085 } 1136 }
1137 /* Zero created block */
1138 status = ocfs2_journal_access_dq(handle, lqinode, bh,
1139 OCFS2_JOURNAL_ACCESS_CREATE);
1140 if (status < 0) {
1141 mlog_errno(status);
1142 goto out_trans;
1143 }
1144 lock_buffer(bh);
1145 memset(bh->b_data, 0, sb->s_blocksize);
1146 unlock_buffer(bh);
1147 status = ocfs2_journal_dirty(handle, bh);
1148 if (status < 0) {
1149 mlog_errno(status);
1150 goto out_trans;
1151 }
1152 /* Update chunk header */
1086 status = ocfs2_journal_access_dq(handle, lqinode, chunk->qc_headerbh, 1153 status = ocfs2_journal_access_dq(handle, lqinode, chunk->qc_headerbh,
1087 OCFS2_JOURNAL_ACCESS_WRITE); 1154 OCFS2_JOURNAL_ACCESS_WRITE);
1088 if (status < 0) { 1155 if (status < 0) {
@@ -1099,6 +1166,7 @@ static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file(
1099 mlog_errno(status); 1166 mlog_errno(status);
1100 goto out_trans; 1167 goto out_trans;
1101 } 1168 }
1169 /* Update file header */
1102 oinfo->dqi_blocks++; 1170 oinfo->dqi_blocks++;
1103 status = ocfs2_local_write_info(sb, type); 1171 status = ocfs2_local_write_info(sb, type);
1104 if (status < 0) { 1172 if (status < 0) {