hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/gfs2/bmap.c
....@@ -1,10 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
34 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
4
- *
5
- * This copyrighted material is made available to anyone wishing to use,
6
- * modify, copy, or redistribute it subject to the terms and conditions
7
- * of the GNU General Public License version 2.
85 */
96
107 #include <linux/spinlock.h>
....@@ -14,6 +11,7 @@
1411 #include <linux/gfs2_ondisk.h>
1512 #include <linux/crc32.h>
1613 #include <linux/iomap.h>
14
+#include <linux/ktime.h>
1715
1816 #include "gfs2.h"
1917 #include "incore.h"
....@@ -58,7 +56,6 @@
5856 u64 block, struct page *page)
5957 {
6058 struct inode *inode = &ip->i_inode;
61
- struct buffer_head *bh;
6259 int release = 0;
6360
6461 if (!page || page->index) {
....@@ -72,9 +69,6 @@
7269 void *kaddr = kmap(page);
7370 u64 dsize = i_size_read(inode);
7471
75
- if (dsize > gfs2_max_stuffed_size(ip))
76
- dsize = gfs2_max_stuffed_size(ip);
77
-
7872 memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
7973 memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
8074 kunmap(page);
....@@ -82,20 +76,21 @@
8276 SetPageUptodate(page);
8377 }
8478
85
- if (!page_has_buffers(page))
86
- create_empty_buffers(page, BIT(inode->i_blkbits),
87
- BIT(BH_Uptodate));
79
+ if (gfs2_is_jdata(ip)) {
80
+ struct buffer_head *bh;
8881
89
- bh = page_buffers(page);
82
+ if (!page_has_buffers(page))
83
+ create_empty_buffers(page, BIT(inode->i_blkbits),
84
+ BIT(BH_Uptodate));
9085
91
- if (!buffer_mapped(bh))
92
- map_bh(bh, inode->i_sb, block);
86
+ bh = page_buffers(page);
87
+ if (!buffer_mapped(bh))
88
+ map_bh(bh, inode->i_sb, block);
9389
94
- set_buffer_uptodate(bh);
95
- if (gfs2_is_jdata(ip))
90
+ set_buffer_uptodate(bh);
9691 gfs2_trans_add_data(ip->i_gl, bh);
97
- else {
98
- mark_buffer_dirty(bh);
92
+ } else {
93
+ set_page_dirty(page);
9994 gfs2_ordered_add_inode(ip);
10095 }
10196
....@@ -141,7 +136,7 @@
141136 if (error)
142137 goto out_brelse;
143138 if (isdir) {
144
- gfs2_trans_add_unrevoke(GFS2_SB(&ip->i_inode), block, 1);
139
+ gfs2_trans_remove_revoke(GFS2_SB(&ip->i_inode), block, 1);
145140 error = gfs2_dir_get_new_buffer(ip, block, &bh);
146141 if (error)
147142 goto out_brelse;
....@@ -637,7 +632,6 @@
637632 * gfs2_iomap_alloc - Build a metadata tree of the requested height
638633 * @inode: The GFS2 inode
639634 * @iomap: The iomap structure
640
- * @flags: iomap flags
641635 * @mp: The metapath, with proper height information calculated
642636 *
643637 * In this routine we may have to alloc:
....@@ -664,7 +658,7 @@
664658 */
665659
666660 static int gfs2_iomap_alloc(struct inode *inode, struct iomap *iomap,
667
- unsigned flags, struct metapath *mp)
661
+ struct metapath *mp)
668662 {
669663 struct gfs2_inode *ip = GFS2_I(inode);
670664 struct gfs2_sbd *sdp = GFS2_SB(inode);
....@@ -715,7 +709,7 @@
715709 goto out;
716710 alloced += n;
717711 if (state != ALLOC_DATA || gfs2_is_jdata(ip))
718
- gfs2_trans_add_unrevoke(sdp, bn, n);
712
+ gfs2_trans_remove_revoke(sdp, bn, n);
719713 switch (state) {
720714 /* Growing height of tree */
721715 case ALLOC_GROW_HEIGHT:
....@@ -749,7 +743,7 @@
749743 }
750744 if (n == 0)
751745 break;
752
- /* Branching from existing tree */
746
+ fallthrough; /* To branching from existing tree */
753747 case ALLOC_GROW_DEPTH:
754748 if (i > 1 && i < mp->mp_fheight)
755749 gfs2_trans_add_meta(ip->i_gl, mp->mp_bh[i-1]);
....@@ -760,7 +754,7 @@
760754 state = ALLOC_DATA;
761755 if (n == 0)
762756 break;
763
- /* Tree complete, adding data blocks */
757
+ fallthrough; /* To tree complete, adding data blocks */
764758 case ALLOC_DATA:
765759 BUG_ON(n > dblks);
766760 BUG_ON(mp->mp_bh[end_of_metadata] == NULL);
....@@ -964,6 +958,32 @@
964958 goto out;
965959 }
966960
961
+/**
962
+ * gfs2_lblk_to_dblk - convert logical block to disk block
963
+ * @inode: the inode of the file we're mapping
964
+ * @lblock: the block relative to the start of the file
965
+ * @dblock: the returned dblock, if no error
966
+ *
967
+ * This function maps a single block from a file logical block (relative to
968
+ * the start of the file) to a file system absolute block using iomap.
969
+ *
970
+ * Returns: the absolute file system block, or an error
971
+ */
972
+int gfs2_lblk_to_dblk(struct inode *inode, u32 lblock, u64 *dblock)
973
+{
974
+ struct iomap iomap = { };
975
+ struct metapath mp = { .mp_aheight = 1, };
976
+ loff_t pos = (loff_t)lblock << inode->i_blkbits;
977
+ int ret;
978
+
979
+ ret = gfs2_iomap_get(inode, pos, i_blocksize(inode), 0, &iomap, &mp);
980
+ release_metapath(&mp);
981
+ if (ret == 0)
982
+ *dblock = iomap.addr >> inode->i_blkbits;
983
+
984
+ return ret;
985
+}
986
+
967987 static int gfs2_write_lock(struct inode *inode)
968988 {
969989 struct gfs2_inode *ip = GFS2_I(inode);
....@@ -1004,14 +1024,38 @@
10041024 gfs2_glock_dq_uninit(&ip->i_gh);
10051025 }
10061026
1007
-static void gfs2_iomap_journaled_page_done(struct inode *inode, loff_t pos,
1008
- unsigned copied, struct page *page,
1009
- struct iomap *iomap)
1027
+static int gfs2_iomap_page_prepare(struct inode *inode, loff_t pos,
1028
+ unsigned len, struct iomap *iomap)
10101029 {
1011
- struct gfs2_inode *ip = GFS2_I(inode);
1030
+ unsigned int blockmask = i_blocksize(inode) - 1;
1031
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
1032
+ unsigned int blocks;
10121033
1013
- gfs2_page_add_databufs(ip, page, offset_in_page(pos), copied);
1034
+ blocks = ((pos & blockmask) + len + blockmask) >> inode->i_blkbits;
1035
+ return gfs2_trans_begin(sdp, RES_DINODE + blocks, 0);
10141036 }
1037
+
1038
+static void gfs2_iomap_page_done(struct inode *inode, loff_t pos,
1039
+ unsigned copied, struct page *page,
1040
+ struct iomap *iomap)
1041
+{
1042
+ struct gfs2_trans *tr = current->journal_info;
1043
+ struct gfs2_inode *ip = GFS2_I(inode);
1044
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
1045
+
1046
+ if (page && !gfs2_is_stuffed(ip))
1047
+ gfs2_page_add_databufs(ip, page, offset_in_page(pos), copied);
1048
+
1049
+ if (tr->tr_num_buf_new)
1050
+ __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
1051
+
1052
+ gfs2_trans_end(sdp);
1053
+}
1054
+
1055
+static const struct iomap_page_ops gfs2_iomap_page_ops = {
1056
+ .page_prepare = gfs2_iomap_page_prepare,
1057
+ .page_done = gfs2_iomap_page_done,
1058
+};
10151059
10161060 static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos,
10171061 loff_t length, unsigned flags,
....@@ -1020,120 +1064,138 @@
10201064 {
10211065 struct gfs2_inode *ip = GFS2_I(inode);
10221066 struct gfs2_sbd *sdp = GFS2_SB(inode);
1023
- unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
1024
- bool unstuff, alloc_required;
1067
+ bool unstuff;
10251068 int ret;
1026
-
1027
- ret = gfs2_write_lock(inode);
1028
- if (ret)
1029
- return ret;
10301069
10311070 unstuff = gfs2_is_stuffed(ip) &&
10321071 pos + length > gfs2_max_stuffed_size(ip);
10331072
1034
- ret = gfs2_iomap_get(inode, pos, length, flags, iomap, mp);
1035
- if (ret)
1036
- goto out_unlock;
1073
+ if (unstuff || iomap->type == IOMAP_HOLE) {
1074
+ unsigned int data_blocks, ind_blocks;
1075
+ struct gfs2_alloc_parms ap = {};
1076
+ unsigned int rblocks;
1077
+ struct gfs2_trans *tr;
10371078
1038
- alloc_required = unstuff || iomap->type == IOMAP_HOLE;
1039
-
1040
- if (alloc_required || gfs2_is_jdata(ip))
10411079 gfs2_write_calc_reserv(ip, iomap->length, &data_blocks,
10421080 &ind_blocks);
1043
-
1044
- if (alloc_required) {
1045
- struct gfs2_alloc_parms ap = {
1046
- .target = data_blocks + ind_blocks
1047
- };
1048
-
1081
+ ap.target = data_blocks + ind_blocks;
10491082 ret = gfs2_quota_lock_check(ip, &ap);
10501083 if (ret)
1051
- goto out_unlock;
1084
+ return ret;
10521085
10531086 ret = gfs2_inplace_reserve(ip, &ap);
10541087 if (ret)
10551088 goto out_qunlock;
1056
- }
10571089
1058
- rblocks = RES_DINODE + ind_blocks;
1059
- if (gfs2_is_jdata(ip))
1060
- rblocks += data_blocks;
1061
- if (ind_blocks || data_blocks)
1062
- rblocks += RES_STATFS + RES_QUOTA;
1063
- if (inode == sdp->sd_rindex)
1064
- rblocks += 2 * RES_STATFS;
1065
- if (alloc_required)
1090
+ rblocks = RES_DINODE + ind_blocks;
1091
+ if (gfs2_is_jdata(ip))
1092
+ rblocks += data_blocks;
1093
+ if (ind_blocks || data_blocks)
1094
+ rblocks += RES_STATFS + RES_QUOTA;
1095
+ if (inode == sdp->sd_rindex)
1096
+ rblocks += 2 * RES_STATFS;
10661097 rblocks += gfs2_rg_blocks(ip, data_blocks + ind_blocks);
10671098
1068
- ret = gfs2_trans_begin(sdp, rblocks, iomap->length >> inode->i_blkbits);
1069
- if (ret)
1070
- goto out_trans_fail;
1071
-
1072
- if (unstuff) {
1073
- ret = gfs2_unstuff_dinode(ip, NULL);
1099
+ ret = gfs2_trans_begin(sdp, rblocks,
1100
+ iomap->length >> inode->i_blkbits);
10741101 if (ret)
1075
- goto out_trans_end;
1076
- release_metapath(mp);
1077
- ret = gfs2_iomap_get(inode, iomap->offset, iomap->length,
1078
- flags, iomap, mp);
1079
- if (ret)
1080
- goto out_trans_end;
1081
- }
1102
+ goto out_trans_fail;
10821103
1083
- if (iomap->type == IOMAP_HOLE) {
1084
- ret = gfs2_iomap_alloc(inode, iomap, flags, mp);
1085
- if (ret) {
1086
- gfs2_trans_end(sdp);
1087
- gfs2_inplace_release(ip);
1088
- punch_hole(ip, iomap->offset, iomap->length);
1089
- goto out_qunlock;
1104
+ if (unstuff) {
1105
+ ret = gfs2_unstuff_dinode(ip, NULL);
1106
+ if (ret)
1107
+ goto out_trans_end;
1108
+ release_metapath(mp);
1109
+ ret = gfs2_iomap_get(inode, iomap->offset,
1110
+ iomap->length, flags, iomap, mp);
1111
+ if (ret)
1112
+ goto out_trans_end;
10901113 }
1114
+
1115
+ if (iomap->type == IOMAP_HOLE) {
1116
+ ret = gfs2_iomap_alloc(inode, iomap, mp);
1117
+ if (ret) {
1118
+ gfs2_trans_end(sdp);
1119
+ gfs2_inplace_release(ip);
1120
+ punch_hole(ip, iomap->offset, iomap->length);
1121
+ goto out_qunlock;
1122
+ }
1123
+ }
1124
+
1125
+ tr = current->journal_info;
1126
+ if (tr->tr_num_buf_new)
1127
+ __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
1128
+
1129
+ gfs2_trans_end(sdp);
10911130 }
1092
- if (!gfs2_is_stuffed(ip) && gfs2_is_jdata(ip))
1093
- iomap->page_done = gfs2_iomap_journaled_page_done;
1131
+
1132
+ if (gfs2_is_stuffed(ip) || gfs2_is_jdata(ip))
1133
+ iomap->page_ops = &gfs2_iomap_page_ops;
10941134 return 0;
10951135
10961136 out_trans_end:
10971137 gfs2_trans_end(sdp);
10981138 out_trans_fail:
1099
- if (alloc_required)
1100
- gfs2_inplace_release(ip);
1139
+ gfs2_inplace_release(ip);
11011140 out_qunlock:
1102
- if (alloc_required)
1103
- gfs2_quota_unlock(ip);
1104
-out_unlock:
1105
- gfs2_write_unlock(inode);
1141
+ gfs2_quota_unlock(ip);
11061142 return ret;
11071143 }
11081144
1145
+static inline bool gfs2_iomap_need_write_lock(unsigned flags)
1146
+{
1147
+ return (flags & IOMAP_WRITE) && !(flags & IOMAP_DIRECT);
1148
+}
1149
+
11091150 static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
1110
- unsigned flags, struct iomap *iomap)
1151
+ unsigned flags, struct iomap *iomap,
1152
+ struct iomap *srcmap)
11111153 {
11121154 struct gfs2_inode *ip = GFS2_I(inode);
11131155 struct metapath mp = { .mp_aheight = 1, };
11141156 int ret;
11151157
1116
- iomap->flags |= IOMAP_F_BUFFER_HEAD;
1158
+ if (gfs2_is_jdata(ip))
1159
+ iomap->flags |= IOMAP_F_BUFFER_HEAD;
11171160
11181161 trace_gfs2_iomap_start(ip, pos, length, flags);
1119
- if ((flags & IOMAP_WRITE) && !(flags & IOMAP_DIRECT)) {
1120
- ret = gfs2_iomap_begin_write(inode, pos, length, flags, iomap, &mp);
1121
- } else {
1122
- ret = gfs2_iomap_get(inode, pos, length, flags, iomap, &mp);
1162
+ if (gfs2_iomap_need_write_lock(flags)) {
1163
+ ret = gfs2_write_lock(inode);
1164
+ if (ret)
1165
+ goto out;
1166
+ }
11231167
1124
- /*
1125
- * Silently fall back to buffered I/O for stuffed files or if
1126
- * we've hot a hole (see gfs2_file_direct_write).
1127
- */
1128
- if ((flags & IOMAP_WRITE) && (flags & IOMAP_DIRECT) &&
1129
- iomap->type != IOMAP_MAPPED)
1130
- ret = -ENOTBLK;
1168
+ ret = gfs2_iomap_get(inode, pos, length, flags, iomap, &mp);
1169
+ if (ret)
1170
+ goto out_unlock;
1171
+
1172
+ switch(flags & (IOMAP_WRITE | IOMAP_ZERO)) {
1173
+ case IOMAP_WRITE:
1174
+ if (flags & IOMAP_DIRECT) {
1175
+ /*
1176
+ * Silently fall back to buffered I/O for stuffed files
1177
+ * or if we've got a hole (see gfs2_file_direct_write).
1178
+ */
1179
+ if (iomap->type != IOMAP_MAPPED)
1180
+ ret = -ENOTBLK;
1181
+ goto out_unlock;
1182
+ }
1183
+ break;
1184
+ case IOMAP_ZERO:
1185
+ if (iomap->type == IOMAP_HOLE)
1186
+ goto out_unlock;
1187
+ break;
1188
+ default:
1189
+ goto out_unlock;
11311190 }
1132
- if (!ret) {
1133
- get_bh(mp.mp_bh[0]);
1134
- iomap->private = mp.mp_bh[0];
1135
- }
1191
+
1192
+ ret = gfs2_iomap_begin_write(inode, pos, length, flags, iomap, &mp);
1193
+
1194
+out_unlock:
1195
+ if (ret && gfs2_iomap_need_write_lock(flags))
1196
+ gfs2_write_unlock(inode);
11361197 release_metapath(&mp);
1198
+out:
11371199 trace_gfs2_iomap_end(ip, iomap, ret);
11381200 return ret;
11391201 }
....@@ -1143,48 +1205,52 @@
11431205 {
11441206 struct gfs2_inode *ip = GFS2_I(inode);
11451207 struct gfs2_sbd *sdp = GFS2_SB(inode);
1146
- struct gfs2_trans *tr = current->journal_info;
1147
- struct buffer_head *dibh = iomap->private;
11481208
1149
- if ((flags & (IOMAP_WRITE | IOMAP_DIRECT)) != IOMAP_WRITE)
1150
- goto out;
1209
+ switch (flags & (IOMAP_WRITE | IOMAP_ZERO)) {
1210
+ case IOMAP_WRITE:
1211
+ if (flags & IOMAP_DIRECT)
1212
+ return 0;
1213
+ break;
1214
+ case IOMAP_ZERO:
1215
+ if (iomap->type == IOMAP_HOLE)
1216
+ return 0;
1217
+ break;
1218
+ default:
1219
+ return 0;
1220
+ }
11511221
1152
- if (iomap->type != IOMAP_INLINE) {
1222
+ if (!gfs2_is_stuffed(ip))
11531223 gfs2_ordered_add_inode(ip);
11541224
1155
- if (tr->tr_num_buf_new)
1156
- __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
1157
- else
1158
- gfs2_trans_add_meta(ip->i_gl, dibh);
1159
- }
1160
-
1161
- if (inode == sdp->sd_rindex) {
1225
+ if (inode == sdp->sd_rindex)
11621226 adjust_fs_space(inode);
1163
- sdp->sd_rindex_uptodate = 0;
1164
- }
11651227
1166
- gfs2_trans_end(sdp);
11671228 gfs2_inplace_release(ip);
1168
-
1169
- if (length != written && (iomap->flags & IOMAP_F_NEW)) {
1170
- /* Deallocate blocks that were just allocated. */
1171
- loff_t blockmask = i_blocksize(inode) - 1;
1172
- loff_t end = (pos + length) & ~blockmask;
1173
-
1174
- pos = (pos + written + blockmask) & ~blockmask;
1175
- if (pos < end) {
1176
- truncate_pagecache_range(inode, pos, end - 1);
1177
- punch_hole(ip, pos, end - pos);
1178
- }
1179
- }
11801229
11811230 if (ip->i_qadata && ip->i_qadata->qa_qd_num)
11821231 gfs2_quota_unlock(ip);
1183
- gfs2_write_unlock(inode);
11841232
1185
-out:
1186
- if (dibh)
1187
- brelse(dibh);
1233
+ if (length != written && (iomap->flags & IOMAP_F_NEW)) {
1234
+ /* Deallocate blocks that were just allocated. */
1235
+ loff_t hstart = round_up(pos + written, i_blocksize(inode));
1236
+ loff_t hend = iomap->offset + iomap->length;
1237
+
1238
+ if (hstart < hend) {
1239
+ truncate_pagecache_range(inode, hstart, hend - 1);
1240
+ punch_hole(ip, hstart, hend - hstart);
1241
+ }
1242
+ }
1243
+
1244
+ if (unlikely(!written))
1245
+ goto out_unlock;
1246
+
1247
+ if (iomap->flags & IOMAP_F_SIZE_CHANGED)
1248
+ mark_inode_dirty(inode);
1249
+ set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
1250
+
1251
+out_unlock:
1252
+ if (gfs2_iomap_need_write_lock(flags))
1253
+ gfs2_write_unlock(inode);
11881254 return 0;
11891255 }
11901256
....@@ -1222,6 +1288,7 @@
12221288 loff_t length = bh_map->b_size;
12231289 struct metapath mp = { .mp_aheight = 1, };
12241290 struct iomap iomap = { };
1291
+ int flags = create ? IOMAP_WRITE : 0;
12251292 int ret;
12261293
12271294 clear_buffer_mapped(bh_map);
....@@ -1229,15 +1296,10 @@
12291296 clear_buffer_boundary(bh_map);
12301297 trace_gfs2_bmap(ip, bh_map, lblock, create, 1);
12311298
1232
- if (create) {
1233
- ret = gfs2_iomap_get(inode, pos, length, IOMAP_WRITE, &iomap, &mp);
1234
- if (!ret && iomap.type == IOMAP_HOLE)
1235
- ret = gfs2_iomap_alloc(inode, &iomap, IOMAP_WRITE, &mp);
1236
- release_metapath(&mp);
1237
- } else {
1238
- ret = gfs2_iomap_get(inode, pos, length, 0, &iomap, &mp);
1239
- release_metapath(&mp);
1240
- }
1299
+ ret = gfs2_iomap_get(inode, pos, length, flags, &iomap, &mp);
1300
+ if (create && !ret && iomap.type == IOMAP_HOLE)
1301
+ ret = gfs2_iomap_alloc(inode, &iomap, &mp);
1302
+ release_metapath(&mp);
12411303 if (ret)
12421304 goto out;
12431305
....@@ -1282,76 +1344,16 @@
12821344 return ret;
12831345 }
12841346
1285
-/**
1286
- * gfs2_block_zero_range - Deal with zeroing out data
1287
- *
1288
- * This is partly borrowed from ext3.
1347
+/*
1348
+ * NOTE: Never call gfs2_block_zero_range with an open transaction because it
1349
+ * uses iomap write to perform its actions, which begin their own transactions
1350
+ * (iomap_begin, page_prepare, etc.)
12891351 */
12901352 static int gfs2_block_zero_range(struct inode *inode, loff_t from,
12911353 unsigned int length)
12921354 {
1293
- struct address_space *mapping = inode->i_mapping;
1294
- struct gfs2_inode *ip = GFS2_I(inode);
1295
- unsigned long index = from >> PAGE_SHIFT;
1296
- unsigned offset = from & (PAGE_SIZE-1);
1297
- unsigned blocksize, iblock, pos;
1298
- struct buffer_head *bh;
1299
- struct page *page;
1300
- int err;
1301
-
1302
- page = find_or_create_page(mapping, index, GFP_NOFS);
1303
- if (!page)
1304
- return 0;
1305
-
1306
- blocksize = inode->i_sb->s_blocksize;
1307
- iblock = index << (PAGE_SHIFT - inode->i_sb->s_blocksize_bits);
1308
-
1309
- if (!page_has_buffers(page))
1310
- create_empty_buffers(page, blocksize, 0);
1311
-
1312
- /* Find the buffer that contains "offset" */
1313
- bh = page_buffers(page);
1314
- pos = blocksize;
1315
- while (offset >= pos) {
1316
- bh = bh->b_this_page;
1317
- iblock++;
1318
- pos += blocksize;
1319
- }
1320
-
1321
- err = 0;
1322
-
1323
- if (!buffer_mapped(bh)) {
1324
- gfs2_block_map(inode, iblock, bh, 0);
1325
- /* unmapped? It's a hole - nothing to do */
1326
- if (!buffer_mapped(bh))
1327
- goto unlock;
1328
- }
1329
-
1330
- /* Ok, it's mapped. Make sure it's up-to-date */
1331
- if (PageUptodate(page))
1332
- set_buffer_uptodate(bh);
1333
-
1334
- if (!buffer_uptodate(bh)) {
1335
- err = -EIO;
1336
- ll_rw_block(REQ_OP_READ, 0, 1, &bh);
1337
- wait_on_buffer(bh);
1338
- /* Uhhuh. Read error. Complain and punt. */
1339
- if (!buffer_uptodate(bh))
1340
- goto unlock;
1341
- err = 0;
1342
- }
1343
-
1344
- if (gfs2_is_jdata(ip))
1345
- gfs2_trans_add_data(ip->i_gl, bh);
1346
- else
1347
- gfs2_ordered_add_inode(ip);
1348
-
1349
- zero_user(page, offset, length);
1350
- mark_buffer_dirty(bh);
1351
-unlock:
1352
- unlock_page(page);
1353
- put_page(page);
1354
- return err;
1355
+ BUG_ON(current->journal_info);
1356
+ return iomap_zero_range(inode, from, length, NULL, &gfs2_iomap_ops);
13551357 }
13561358
13571359 #define GFS2_JTRUNC_REVOKES 8192
....@@ -1411,6 +1413,16 @@
14111413 u64 oldsize = inode->i_size;
14121414 int error;
14131415
1416
+ if (!gfs2_is_stuffed(ip)) {
1417
+ unsigned int blocksize = i_blocksize(inode);
1418
+ unsigned int offs = newsize & (blocksize - 1);
1419
+ if (offs) {
1420
+ error = gfs2_block_zero_range(inode, newsize,
1421
+ blocksize - offs);
1422
+ if (error)
1423
+ return error;
1424
+ }
1425
+ }
14141426 if (journaled)
14151427 error = gfs2_trans_begin(sdp, RES_DINODE + RES_JDATA, GFS2_JTRUNC_REVOKES);
14161428 else
....@@ -1424,19 +1436,10 @@
14241436
14251437 gfs2_trans_add_meta(ip->i_gl, dibh);
14261438
1427
- if (gfs2_is_stuffed(ip)) {
1439
+ if (gfs2_is_stuffed(ip))
14281440 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + newsize);
1429
- } else {
1430
- unsigned int blocksize = i_blocksize(inode);
1431
- unsigned int offs = newsize & (blocksize - 1);
1432
- if (offs) {
1433
- error = gfs2_block_zero_range(inode, newsize,
1434
- blocksize - offs);
1435
- if (error)
1436
- goto out;
1437
- }
1441
+ else
14381442 ip->i_diskflags |= GFS2_DIF_TRUNC_IN_PROG;
1439
- }
14401443
14411444 i_size_write(inode, newsize);
14421445 ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode);
....@@ -1462,7 +1465,7 @@
14621465
14631466 ret = gfs2_iomap_get(inode, pos, length, IOMAP_WRITE, iomap, &mp);
14641467 if (!ret && iomap->type == IOMAP_HOLE)
1465
- ret = gfs2_iomap_alloc(inode, iomap, IOMAP_WRITE, &mp);
1468
+ ret = gfs2_iomap_alloc(inode, iomap, &mp);
14661469 release_metapath(&mp);
14671470 return ret;
14681471 }
....@@ -1600,7 +1603,7 @@
16001603 continue;
16011604 }
16021605 if (bstart) {
1603
- __gfs2_free_blocks(ip, bstart, (u32)blen, meta);
1606
+ __gfs2_free_blocks(ip, rgd, bstart, (u32)blen, meta);
16041607 (*btotal) += blen;
16051608 gfs2_add_inode_blocks(&ip->i_inode, -blen);
16061609 }
....@@ -1608,7 +1611,7 @@
16081611 blen = 1;
16091612 }
16101613 if (bstart) {
1611
- __gfs2_free_blocks(ip, bstart, (u32)blen, meta);
1614
+ __gfs2_free_blocks(ip, rgd, bstart, (u32)blen, meta);
16121615 (*btotal) += blen;
16131616 gfs2_add_inode_blocks(&ip->i_inode, -blen);
16141617 }
....@@ -1758,7 +1761,7 @@
17581761 u64 lblock = (offset + (1 << bsize_shift) - 1) >> bsize_shift;
17591762 __u16 start_list[GFS2_MAX_META_HEIGHT];
17601763 __u16 __end_list[GFS2_MAX_META_HEIGHT], *end_list = NULL;
1761
- unsigned int start_aligned, uninitialized_var(end_aligned);
1764
+ unsigned int start_aligned, end_aligned;
17621765 unsigned int strip_h = ip->i_height - 1;
17631766 u32 btotal = 0;
17641767 int ret, state;
....@@ -1863,9 +1866,8 @@
18631866 gfs2_assert_withdraw(sdp, bh);
18641867 if (gfs2_assert_withdraw(sdp,
18651868 prev_bnr != bh->b_blocknr)) {
1866
- printk(KERN_EMERG "GFS2: fsid=%s:inode %llu, "
1867
- "block:%llu, i_h:%u, s_h:%u, mp_h:%u\n",
1868
- sdp->sd_fsname,
1869
+ fs_emerg(sdp, "inode %llu, block:%llu, i_h:%u,"
1870
+ "s_h:%u, mp_h:%u\n",
18691871 (unsigned long long)ip->i_no_addr,
18701872 prev_bnr, ip->i_height, strip_h, mp_h);
18711873 }
....@@ -2141,7 +2143,7 @@
21412143 if (error)
21422144 goto do_end_trans;
21432145
2144
- i_size_write(inode, size);
2146
+ truncate_setsize(inode, size);
21452147 ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode);
21462148 gfs2_trans_add_meta(ip->i_gl, dibh);
21472149 gfs2_dinode_out(ip, dibh->b_data);
....@@ -2183,7 +2185,7 @@
21832185
21842186 inode_dio_wait(inode);
21852187
2186
- ret = gfs2_rsqa_alloc(ip);
2188
+ ret = gfs2_qa_get(ip);
21872189 if (ret)
21882190 goto out;
21892191
....@@ -2194,7 +2196,8 @@
21942196
21952197 ret = do_shrink(inode, newsize);
21962198 out:
2197
- gfs2_rsqa_delete(ip, NULL);
2199
+ gfs2_rs_delete(ip);
2200
+ gfs2_qa_put(ip);
21982201 return ret;
21992202 }
22002203
....@@ -2223,7 +2226,7 @@
22232226 struct gfs2_journal_extent *jext;
22242227
22252228 while(!list_empty(&jd->extent_list)) {
2226
- jext = list_entry(jd->extent_list.next, struct gfs2_journal_extent, list);
2229
+ jext = list_first_entry(&jd->extent_list, struct gfs2_journal_extent, list);
22272230 list_del(&jext->list);
22282231 kfree(jext);
22292232 }
....@@ -2244,7 +2247,7 @@
22442247 struct gfs2_journal_extent *jext;
22452248
22462249 if (!list_empty(&jd->extent_list)) {
2247
- jext = list_entry(jd->extent_list.prev, struct gfs2_journal_extent, list);
2250
+ jext = list_last_entry(&jd->extent_list, struct gfs2_journal_extent, list);
22482251 if ((jext->dblock + jext->blocks) == dblock) {
22492252 jext->blocks += blocks;
22502253 return 0;
....@@ -2291,7 +2294,9 @@
22912294 unsigned int shift = sdp->sd_sb.sb_bsize_shift;
22922295 u64 size;
22932296 int rc;
2297
+ ktime_t start, end;
22942298
2299
+ start = ktime_get();
22952300 lblock_stop = i_size_read(jd->jd_inode) >> shift;
22962301 size = (lblock_stop - lblock) << shift;
22972302 jd->nr_extents = 0;
....@@ -2311,8 +2316,9 @@
23112316 lblock += (bh.b_size >> ip->i_inode.i_blkbits);
23122317 } while(size > 0);
23132318
2314
- fs_info(sdp, "journal %d mapped with %u extents\n", jd->jd_jid,
2315
- jd->nr_extents);
2319
+ end = ktime_get();
2320
+ fs_info(sdp, "journal %d mapped with %u extents in %lldms\n", jd->jd_jid,
2321
+ jd->nr_extents, ktime_ms_delta(end, start));
23162322 return 0;
23172323
23182324 fail:
....@@ -2438,24 +2444,13 @@
24382444 struct inode *inode = file_inode(file);
24392445 struct gfs2_inode *ip = GFS2_I(inode);
24402446 struct gfs2_sbd *sdp = GFS2_SB(inode);
2447
+ unsigned int blocksize = i_blocksize(inode);
2448
+ loff_t start, end;
24412449 int error;
24422450
2443
- if (gfs2_is_jdata(ip))
2444
- error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_JDATA,
2445
- GFS2_JTRUNC_REVOKES);
2446
- else
2447
- error = gfs2_trans_begin(sdp, RES_DINODE, 0);
2448
- if (error)
2449
- return error;
2451
+ if (!gfs2_is_stuffed(ip)) {
2452
+ unsigned int start_off, end_len;
24502453
2451
- if (gfs2_is_stuffed(ip)) {
2452
- error = stuffed_zero_range(inode, offset, length);
2453
- if (error)
2454
- goto out;
2455
- } else {
2456
- unsigned int start_off, end_len, blocksize;
2457
-
2458
- blocksize = i_blocksize(inode);
24592454 start_off = offset & (blocksize - 1);
24602455 end_len = (offset + length) & (blocksize - 1);
24612456 if (start_off) {
....@@ -2474,6 +2469,26 @@
24742469 if (error)
24752470 goto out;
24762471 }
2472
+ }
2473
+
2474
+ start = round_down(offset, blocksize);
2475
+ end = round_up(offset + length, blocksize) - 1;
2476
+ error = filemap_write_and_wait_range(inode->i_mapping, start, end);
2477
+ if (error)
2478
+ return error;
2479
+
2480
+ if (gfs2_is_jdata(ip))
2481
+ error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_JDATA,
2482
+ GFS2_JTRUNC_REVOKES);
2483
+ else
2484
+ error = gfs2_trans_begin(sdp, RES_DINODE, 0);
2485
+ if (error)
2486
+ return error;
2487
+
2488
+ if (gfs2_is_stuffed(ip)) {
2489
+ error = stuffed_zero_range(inode, offset, length);
2490
+ if (error)
2491
+ goto out;
24772492 }
24782493
24792494 if (gfs2_is_jdata(ip)) {
....@@ -2496,3 +2511,26 @@
24962511 gfs2_trans_end(sdp);
24972512 return error;
24982513 }
2514
+
2515
+static int gfs2_map_blocks(struct iomap_writepage_ctx *wpc, struct inode *inode,
2516
+ loff_t offset)
2517
+{
2518
+ struct metapath mp = { .mp_aheight = 1, };
2519
+ int ret;
2520
+
2521
+ if (WARN_ON_ONCE(gfs2_is_stuffed(GFS2_I(inode))))
2522
+ return -EIO;
2523
+
2524
+ if (offset >= wpc->iomap.offset &&
2525
+ offset < wpc->iomap.offset + wpc->iomap.length)
2526
+ return 0;
2527
+
2528
+ memset(&wpc->iomap, 0, sizeof(wpc->iomap));
2529
+ ret = gfs2_iomap_get(inode, offset, INT_MAX, 0, &wpc->iomap, &mp);
2530
+ release_metapath(&mp);
2531
+ return ret;
2532
+}
2533
+
2534
+const struct iomap_writeback_ops gfs2_writeback_ops = {
2535
+ .map_blocks = gfs2_map_blocks,
2536
+};