aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_aops.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-12-10 03:42:20 -0500
committerAlex Elder <aelder@sgi.com>2010-12-16 17:05:51 -0500
commita206c817c864583c44e2f418db8e6c7a000fbc38 (patch)
tree71c7327482299de93b4183c23d118939e8bd30fc /fs/xfs/linux-2.6/xfs_aops.c
parent405f80429436d38ab4e6b4c0d99861a1f00648fd (diff)
xfs: kill xfs_iomap
Opencode the xfs_iomap code in it's two callers. The overlap of passed flags already was minimal and will be further reduced in the next patch. As a side effect the BMAPI_* flags for xfs_bmapi and the IO_* flags for I/O end processing are merged into a single set of flags, which should be a bit more descriptive of the operation we perform. Also improve the tracing by giving each caller it's own type set of tracepoints. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_aops.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c211
1 files changed, 151 insertions, 60 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 1ace78bfbea7..365040f61d89 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -38,15 +38,6 @@
38#include <linux/pagevec.h> 38#include <linux/pagevec.h>
39#include <linux/writeback.h> 39#include <linux/writeback.h>
40 40
41/*
42 * Types of I/O for bmap clustering and I/O completion tracking.
43 */
44enum {
45 IO_READ, /* mapping for a read */
46 IO_DELAY, /* mapping covers delalloc region */
47 IO_UNWRITTEN, /* mapping covers allocated but uninitialized data */
48 IO_NEW /* just allocated */
49};
50 41
51/* 42/*
52 * Prime number of hash buckets since address is used as the key. 43 * Prime number of hash buckets since address is used as the key.
@@ -182,9 +173,6 @@ xfs_setfilesize(
182 xfs_inode_t *ip = XFS_I(ioend->io_inode); 173 xfs_inode_t *ip = XFS_I(ioend->io_inode);
183 xfs_fsize_t isize; 174 xfs_fsize_t isize;
184 175
185 ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
186 ASSERT(ioend->io_type != IO_READ);
187
188 if (unlikely(ioend->io_error)) 176 if (unlikely(ioend->io_error))
189 return 0; 177 return 0;
190 178
@@ -244,10 +232,8 @@ xfs_end_io(
244 * We might have to update the on-disk file size after extending 232 * We might have to update the on-disk file size after extending
245 * writes. 233 * writes.
246 */ 234 */
247 if (ioend->io_type != IO_READ) { 235 error = xfs_setfilesize(ioend);
248 error = xfs_setfilesize(ioend); 236 ASSERT(!error || error == EAGAIN);
249 ASSERT(!error || error == EAGAIN);
250 }
251 237
252 /* 238 /*
253 * If we didn't complete processing of the ioend, requeue it to the 239 * If we didn't complete processing of the ioend, requeue it to the
@@ -320,12 +306,88 @@ xfs_map_blocks(
320 loff_t offset, 306 loff_t offset,
321 ssize_t count, 307 ssize_t count,
322 struct xfs_bmbt_irec *imap, 308 struct xfs_bmbt_irec *imap,
323 int flags) 309 int type,
310 int nonblocking)
324{ 311{
325 int nmaps = 1; 312 struct xfs_inode *ip = XFS_I(inode);
326 int new = 0; 313 struct xfs_mount *mp = ip->i_mount;
314 xfs_fileoff_t offset_fsb, end_fsb;
315 int error = 0;
316 int lockmode = 0;
317 int bmapi_flags = XFS_BMAPI_ENTIRE;
318 int nimaps = 1;
319
320 if (XFS_FORCED_SHUTDOWN(mp))
321 return -XFS_ERROR(EIO);
322
323 switch (type) {
324 case IO_OVERWRITE:
325 lockmode = xfs_ilock_map_shared(ip);
326 break;
327 case IO_UNWRITTEN:
328 lockmode = XFS_ILOCK_EXCL;
329 bmapi_flags |= XFS_BMAPI_IGSTATE;
330 xfs_ilock(ip, lockmode);
331 break;
332 case IO_DELALLOC:
333 lockmode = XFS_ILOCK_SHARED;
334
335 if (!xfs_ilock_nowait(ip, lockmode)) {
336 if (nonblocking)
337 return -XFS_ERROR(EAGAIN);
338 xfs_ilock(ip, lockmode);
339 }
340 break;
341 }
342
343 ASSERT(offset <= mp->m_maxioffset);
344 if (offset + count > mp->m_maxioffset)
345 count = mp->m_maxioffset - offset;
346 end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
347 offset_fsb = XFS_B_TO_FSBT(mp, offset);
348
349 error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb,
350 bmapi_flags, NULL, 0, imap, &nimaps, NULL);
351 if (error)
352 goto out;
353
354 switch (type) {
355 case IO_UNWRITTEN:
356 /* If we found an extent, return it */
357 if (nimaps &&
358 (imap->br_startblock != HOLESTARTBLOCK) &&
359 (imap->br_startblock != DELAYSTARTBLOCK)) {
360 trace_xfs_map_blocks_found(ip, offset, count, type, imap);
361 break;
362 }
363
364 error = xfs_iomap_write_delay(ip, offset, count, imap);
365 if (!error)
366 trace_xfs_map_blocks_alloc(ip, offset, count, type, imap);
367 break;
368 case IO_DELALLOC:
369 /* If we found an extent, return it */
370 xfs_iunlock(ip, lockmode);
371 lockmode = 0;
372
373 if (nimaps && !isnullstartblock(imap->br_startblock)) {
374 trace_xfs_map_blocks_found(ip, offset, count, type, imap);
375 break;
376 }
377
378 error = xfs_iomap_write_allocate(ip, offset, count, imap);
379 if (!error)
380 trace_xfs_map_blocks_alloc(ip, offset, count, type, imap);
381 break;
382 default:
383 if (nimaps)
384 trace_xfs_map_blocks_found(ip, offset, count, type, imap);
385 }
327 386
328 return -xfs_iomap(XFS_I(inode), offset, count, flags, imap, &nmaps, &new); 387out:
388 if (lockmode)
389 xfs_iunlock(ip, lockmode);
390 return -XFS_ERROR(error);
329} 391}
330 392
331STATIC int 393STATIC int
@@ -722,9 +784,9 @@ xfs_is_delayed_page(
722 if (buffer_unwritten(bh)) 784 if (buffer_unwritten(bh))
723 acceptable = (type == IO_UNWRITTEN); 785 acceptable = (type == IO_UNWRITTEN);
724 else if (buffer_delay(bh)) 786 else if (buffer_delay(bh))
725 acceptable = (type == IO_DELAY); 787 acceptable = (type == IO_DELALLOC);
726 else if (buffer_dirty(bh) && buffer_mapped(bh)) 788 else if (buffer_dirty(bh) && buffer_mapped(bh))
727 acceptable = (type == IO_NEW); 789 acceptable = (type == IO_OVERWRITE);
728 else 790 else
729 break; 791 break;
730 } while ((bh = bh->b_this_page) != head); 792 } while ((bh = bh->b_this_page) != head);
@@ -809,7 +871,7 @@ xfs_convert_page(
809 if (buffer_unwritten(bh)) 871 if (buffer_unwritten(bh))
810 type = IO_UNWRITTEN; 872 type = IO_UNWRITTEN;
811 else 873 else
812 type = IO_DELAY; 874 type = IO_DELALLOC;
813 875
814 if (!xfs_imap_valid(inode, imap, offset)) { 876 if (!xfs_imap_valid(inode, imap, offset)) {
815 done = 1; 877 done = 1;
@@ -826,7 +888,7 @@ xfs_convert_page(
826 page_dirty--; 888 page_dirty--;
827 count++; 889 count++;
828 } else { 890 } else {
829 type = IO_NEW; 891 type = IO_OVERWRITE;
830 if (buffer_mapped(bh) && all_bh) { 892 if (buffer_mapped(bh) && all_bh) {
831 lock_buffer(bh); 893 lock_buffer(bh);
832 xfs_add_to_ioend(inode, bh, offset, 894 xfs_add_to_ioend(inode, bh, offset,
@@ -926,7 +988,7 @@ xfs_aops_discard_page(
926 struct buffer_head *bh, *head; 988 struct buffer_head *bh, *head;
927 loff_t offset = page_offset(page); 989 loff_t offset = page_offset(page);
928 990
929 if (!xfs_is_delayed_page(page, IO_DELAY)) 991 if (!xfs_is_delayed_page(page, IO_DELALLOC))
930 goto out_invalidate; 992 goto out_invalidate;
931 993
932 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) 994 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
@@ -994,9 +1056,10 @@ xfs_vm_writepage(
994 __uint64_t end_offset; 1056 __uint64_t end_offset;
995 pgoff_t end_index, last_index; 1057 pgoff_t end_index, last_index;
996 ssize_t size, len; 1058 ssize_t size, len;
997 int flags, err, imap_valid = 0, uptodate = 1; 1059 int err, imap_valid = 0, uptodate = 1;
998 int count = 0; 1060 int count = 0;
999 int all_bh = 0; 1061 int all_bh = 0;
1062 int nonblocking = 0;
1000 1063
1001 trace_xfs_writepage(inode, page, 0); 1064 trace_xfs_writepage(inode, page, 0);
1002 1065
@@ -1047,8 +1110,10 @@ xfs_vm_writepage(
1047 1110
1048 bh = head = page_buffers(page); 1111 bh = head = page_buffers(page);
1049 offset = page_offset(page); 1112 offset = page_offset(page);
1050 flags = BMAPI_READ; 1113 type = IO_OVERWRITE;
1051 type = IO_NEW; 1114
1115 if (wbc->sync_mode == WB_SYNC_NONE && wbc->nonblocking)
1116 nonblocking = 1;
1052 1117
1053 do { 1118 do {
1054 int new_ioend = 0; 1119 int new_ioend = 0;
@@ -1078,16 +1143,11 @@ xfs_vm_writepage(
1078 type = IO_UNWRITTEN; 1143 type = IO_UNWRITTEN;
1079 imap_valid = 0; 1144 imap_valid = 0;
1080 } 1145 }
1081 flags = BMAPI_WRITE | BMAPI_IGNSTATE;
1082 } else if (buffer_delay(bh)) { 1146 } else if (buffer_delay(bh)) {
1083 if (type != IO_DELAY) { 1147 if (type != IO_DELALLOC) {
1084 type = IO_DELAY; 1148 type = IO_DELALLOC;
1085 imap_valid = 0; 1149 imap_valid = 0;
1086 } 1150 }
1087 flags = BMAPI_ALLOCATE;
1088
1089 if (wbc->sync_mode == WB_SYNC_NONE)
1090 flags |= BMAPI_TRYLOCK;
1091 } 1151 }
1092 1152
1093 if (!imap_valid) { 1153 if (!imap_valid) {
@@ -1100,8 +1160,8 @@ xfs_vm_writepage(
1100 * for unwritten extent conversion. 1160 * for unwritten extent conversion.
1101 */ 1161 */
1102 new_ioend = 1; 1162 new_ioend = 1;
1103 err = xfs_map_blocks(inode, offset, len, 1163 err = xfs_map_blocks(inode, offset, len, &imap,
1104 &imap, flags); 1164 type, nonblocking);
1105 if (err) 1165 if (err)
1106 goto error; 1166 goto error;
1107 imap_valid = xfs_imap_valid(inode, &imap, 1167 imap_valid = xfs_imap_valid(inode, &imap,
@@ -1119,30 +1179,21 @@ xfs_vm_writepage(
1119 * That means it must already have extents allocated 1179 * That means it must already have extents allocated
1120 * underneath it. Map the extent by reading it. 1180 * underneath it. Map the extent by reading it.
1121 */ 1181 */
1122 if (flags != BMAPI_READ) { 1182 if (type != IO_OVERWRITE) {
1123 flags = BMAPI_READ; 1183 type = IO_OVERWRITE;
1124 imap_valid = 0; 1184 imap_valid = 0;
1125 } 1185 }
1126 if (!imap_valid) { 1186 if (!imap_valid) {
1127 new_ioend = 1; 1187 new_ioend = 1;
1128 size = xfs_probe_cluster(inode, page, bh, head); 1188 size = xfs_probe_cluster(inode, page, bh, head);
1129 err = xfs_map_blocks(inode, offset, size, 1189 err = xfs_map_blocks(inode, offset, size,
1130 &imap, flags); 1190 &imap, type, nonblocking);
1131 if (err) 1191 if (err)
1132 goto error; 1192 goto error;
1133 imap_valid = xfs_imap_valid(inode, &imap, 1193 imap_valid = xfs_imap_valid(inode, &imap,
1134 offset); 1194 offset);
1135 } 1195 }
1136 1196
1137 /*
1138 * We set the type to IO_NEW in case we are doing a
1139 * small write at EOF that is extending the file but
1140 * without needing an allocation. We need to update the
1141 * file size on I/O completion in this case so it is
1142 * the same case as having just allocated a new extent
1143 * that we are writing into for the first time.
1144 */
1145 type = IO_NEW;
1146 if (imap_valid) { 1197 if (imap_valid) {
1147 all_bh = 1; 1198 all_bh = 1;
1148 lock_buffer(bh); 1199 lock_buffer(bh);
@@ -1250,13 +1301,19 @@ __xfs_get_blocks(
1250 int create, 1301 int create,
1251 int direct) 1302 int direct)
1252{ 1303{
1253 int flags = create ? BMAPI_WRITE : BMAPI_READ; 1304 struct xfs_inode *ip = XFS_I(inode);
1305 struct xfs_mount *mp = ip->i_mount;
1306 xfs_fileoff_t offset_fsb, end_fsb;
1307 int error = 0;
1308 int lockmode = 0;
1254 struct xfs_bmbt_irec imap; 1309 struct xfs_bmbt_irec imap;
1310 int nimaps = 1;
1255 xfs_off_t offset; 1311 xfs_off_t offset;
1256 ssize_t size; 1312 ssize_t size;
1257 int nimap = 1;
1258 int new = 0; 1313 int new = 0;
1259 int error; 1314
1315 if (XFS_FORCED_SHUTDOWN(mp))
1316 return -XFS_ERROR(EIO);
1260 1317
1261 offset = (xfs_off_t)iblock << inode->i_blkbits; 1318 offset = (xfs_off_t)iblock << inode->i_blkbits;
1262 ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); 1319 ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
@@ -1265,15 +1322,45 @@ __xfs_get_blocks(
1265 if (!create && direct && offset >= i_size_read(inode)) 1322 if (!create && direct && offset >= i_size_read(inode))
1266 return 0; 1323 return 0;
1267 1324
1268 if (direct && create) 1325 if (create) {
1269 flags |= BMAPI_DIRECT; 1326 lockmode = XFS_ILOCK_EXCL;
1327 xfs_ilock(ip, lockmode);
1328 } else {
1329 lockmode = xfs_ilock_map_shared(ip);
1330 }
1331
1332 ASSERT(offset <= mp->m_maxioffset);
1333 if (offset + size > mp->m_maxioffset)
1334 size = mp->m_maxioffset - offset;
1335 end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size);
1336 offset_fsb = XFS_B_TO_FSBT(mp, offset);
1270 1337
1271 error = xfs_iomap(XFS_I(inode), offset, size, flags, &imap, &nimap, 1338 error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb,
1272 &new); 1339 XFS_BMAPI_ENTIRE, NULL, 0, &imap, &nimaps, NULL);
1273 if (error) 1340 if (error)
1274 return -error; 1341 goto out_unlock;
1275 if (nimap == 0) 1342
1276 return 0; 1343 if (create &&
1344 (!nimaps ||
1345 (imap.br_startblock == HOLESTARTBLOCK ||
1346 imap.br_startblock == DELAYSTARTBLOCK))) {
1347 if (direct) {
1348 error = xfs_iomap_write_direct(ip, offset, size,
1349 &imap, nimaps);
1350 } else {
1351 error = xfs_iomap_write_delay(ip, offset, size, &imap);
1352 }
1353 if (error)
1354 goto out_unlock;
1355
1356 trace_xfs_get_blocks_alloc(ip, offset, size, 0, &imap);
1357 } else if (nimaps) {
1358 trace_xfs_get_blocks_found(ip, offset, size, 0, &imap);
1359 } else {
1360 trace_xfs_get_blocks_notfound(ip, offset, size);
1361 goto out_unlock;
1362 }
1363 xfs_iunlock(ip, lockmode);
1277 1364
1278 if (imap.br_startblock != HOLESTARTBLOCK && 1365 if (imap.br_startblock != HOLESTARTBLOCK &&
1279 imap.br_startblock != DELAYSTARTBLOCK) { 1366 imap.br_startblock != DELAYSTARTBLOCK) {
@@ -1340,6 +1427,10 @@ __xfs_get_blocks(
1340 } 1427 }
1341 1428
1342 return 0; 1429 return 0;
1430
1431out_unlock:
1432 xfs_iunlock(ip, lockmode);
1433 return -error;
1343} 1434}
1344 1435
1345int 1436int
@@ -1427,7 +1518,7 @@ xfs_vm_direct_IO(
1427 ssize_t ret; 1518 ssize_t ret;
1428 1519
1429 if (rw & WRITE) { 1520 if (rw & WRITE) {
1430 iocb->private = xfs_alloc_ioend(inode, IO_NEW); 1521 iocb->private = xfs_alloc_ioend(inode, IO_DIRECT);
1431 1522
1432 ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov, 1523 ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov,
1433 offset, nr_segs, 1524 offset, nr_segs,