aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/quota_local.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2009-07-22 07:17:17 -0400
committerJoel Becker <joel.becker@oracle.com>2009-07-23 13:59:11 -0400
commit0e7f387bf386c99e8ee322649fe4fc23b9cccc6c (patch)
tree9e970c95fe96be086e4741fb02560e1afe433103 /fs/ocfs2/quota_local.c
parent4b3fa1904c0d192461ebba692e4940a334b74353 (diff)
ocfs2: Initialize blocks allocated to local quota file
When we extend local quota file, we should initialize data in newly allocated block. Firstly because on recovery we could parse bogus data, secondly so that block checksums are properly computed. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/quota_local.c')
-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) {