diff options
| author | Dave Chinner <david@fromorbit.com> | 2015-04-16 08:13:18 -0400 |
|---|---|---|
| committer | Dave Chinner <david@fromorbit.com> | 2015-04-16 08:13:18 -0400 |
| commit | 542c311813d5cb2e6f0dfa9557f41c829b8fb6a0 (patch) | |
| tree | 573c5644eb966e44112016c9ae86e80251326223 | |
| parent | 6a63ef064b2444883ce8b68b0779d0c739d27204 (diff) | |
| parent | 0cefb29e6a63727bc7606c47fc538467594ef112 (diff) | |
Merge branch 'xfs-dio-extend-fix' into for-next
Conflicts:
fs/xfs/xfs_file.c
| -rw-r--r-- | fs/xfs/xfs_aops.c | 270 | ||||
| -rw-r--r-- | fs/xfs/xfs_file.c | 46 | ||||
| -rw-r--r-- | fs/xfs/xfs_trace.h | 5 |
3 files changed, 239 insertions, 82 deletions
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 3a9b7a1b8704..598b259fda04 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
| @@ -1233,6 +1233,117 @@ xfs_vm_releasepage( | |||
| 1233 | return try_to_free_buffers(page); | 1233 | return try_to_free_buffers(page); |
| 1234 | } | 1234 | } |
| 1235 | 1235 | ||
| 1236 | /* | ||
| 1237 | * When we map a DIO buffer, we may need to attach an ioend that describes the | ||
| 1238 | * type of write IO we are doing. This passes to the completion function the | ||
| 1239 | * operations it needs to perform. If the mapping is for an overwrite wholly | ||
| 1240 | * within the EOF then we don't need an ioend and so we don't allocate one. | ||
| 1241 | * This avoids the unnecessary overhead of allocating and freeing ioends for | ||
| 1242 | * workloads that don't require transactions on IO completion. | ||
| 1243 | * | ||
| 1244 | * If we get multiple mappings in a single IO, we might be mapping different | ||
| 1245 | * types. But because the direct IO can only have a single private pointer, we | ||
| 1246 | * need to ensure that: | ||
| 1247 | * | ||
| 1248 | * a) i) the ioend spans the entire region of unwritten mappings; or | ||
| 1249 | * ii) the ioend spans all the mappings that cross or are beyond EOF; and | ||
| 1250 | * b) if it contains unwritten extents, it is *permanently* marked as such | ||
| 1251 | * | ||
| 1252 | * We could do this by chaining ioends like buffered IO does, but we only | ||
| 1253 | * actually get one IO completion callback from the direct IO, and that spans | ||
| 1254 | * the entire IO regardless of how many mappings and IOs are needed to complete | ||
| 1255 | * the DIO. There is only going to be one reference to the ioend and its life | ||
| 1256 | * cycle is constrained by the DIO completion code. hence we don't need | ||
| 1257 | * reference counting here. | ||
| 1258 | */ | ||
| 1259 | static void | ||
| 1260 | xfs_map_direct( | ||
| 1261 | struct inode *inode, | ||
| 1262 | struct buffer_head *bh_result, | ||
| 1263 | struct xfs_bmbt_irec *imap, | ||
| 1264 | xfs_off_t offset) | ||
| 1265 | { | ||
| 1266 | struct xfs_ioend *ioend; | ||
| 1267 | xfs_off_t size = bh_result->b_size; | ||
| 1268 | int type; | ||
| 1269 | |||
| 1270 | if (ISUNWRITTEN(imap)) | ||
| 1271 | type = XFS_IO_UNWRITTEN; | ||
| 1272 | else | ||
| 1273 | type = XFS_IO_OVERWRITE; | ||
| 1274 | |||
| 1275 | trace_xfs_gbmap_direct(XFS_I(inode), offset, size, type, imap); | ||
| 1276 | |||
| 1277 | if (bh_result->b_private) { | ||
| 1278 | ioend = bh_result->b_private; | ||
| 1279 | ASSERT(ioend->io_size > 0); | ||
| 1280 | ASSERT(offset >= ioend->io_offset); | ||
| 1281 | if (offset + size > ioend->io_offset + ioend->io_size) | ||
| 1282 | ioend->io_size = offset - ioend->io_offset + size; | ||
| 1283 | |||
| 1284 | if (type == XFS_IO_UNWRITTEN && type != ioend->io_type) | ||
| 1285 | ioend->io_type = XFS_IO_UNWRITTEN; | ||
| 1286 | |||
| 1287 | trace_xfs_gbmap_direct_update(XFS_I(inode), ioend->io_offset, | ||
| 1288 | ioend->io_size, ioend->io_type, | ||
| 1289 | imap); | ||
| 1290 | } else if (type == XFS_IO_UNWRITTEN || | ||
| 1291 | offset + size > i_size_read(inode)) { | ||
| 1292 | ioend = xfs_alloc_ioend(inode, type); | ||
| 1293 | ioend->io_offset = offset; | ||
| 1294 | ioend->io_size = size; | ||
| 1295 | |||
| 1296 | bh_result->b_private = ioend; | ||
| 1297 | set_buffer_defer_completion(bh_result); | ||
| 1298 | |||
| 1299 | trace_xfs_gbmap_direct_new(XFS_I(inode), offset, size, type, | ||
| 1300 | imap); | ||
| 1301 | } else { | ||
| 1302 | trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type, | ||
| 1303 | imap); | ||
| 1304 | } | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | /* | ||
| 1308 | * If this is O_DIRECT or the mpage code calling tell them how large the mapping | ||
| 1309 | * is, so that we can avoid repeated get_blocks calls. | ||
| 1310 | * | ||
| 1311 | * If the mapping spans EOF, then we have to break the mapping up as the mapping | ||
| 1312 | * for blocks beyond EOF must be marked new so that sub block regions can be | ||
| 1313 | * correctly zeroed. We can't do this for mappings within EOF unless the mapping | ||
| 1314 | * was just allocated or is unwritten, otherwise the callers would overwrite | ||
| 1315 | * existing data with zeros. Hence we have to split the mapping into a range up | ||
| 1316 | * to and including EOF, and a second mapping for beyond EOF. | ||
| 1317 | */ | ||
| 1318 | static void | ||
| 1319 | xfs_map_trim_size( | ||
| 1320 | struct inode *inode, | ||
| 1321 | sector_t iblock, | ||
| 1322 | struct buffer_head *bh_result, | ||
| 1323 | struct xfs_bmbt_irec *imap, | ||
| 1324 | xfs_off_t offset, | ||
| 1325 | ssize_t size) | ||
| 1326 | { | ||
| 1327 | xfs_off_t mapping_size; | ||
| 1328 | |||
| 1329 | mapping_size = imap->br_startoff + imap->br_blockcount - iblock; | ||
| 1330 | mapping_size <<= inode->i_blkbits; | ||
| 1331 | |||
| 1332 | ASSERT(mapping_size > 0); | ||
| 1333 | if (mapping_size > size) | ||
| 1334 | mapping_size = size; | ||
| 1335 | if (offset < i_size_read(inode) && | ||
| 1336 | offset + mapping_size >= i_size_read(inode)) { | ||
| 1337 | /* limit mapping to block that spans EOF */ | ||
| 1338 | mapping_size = roundup_64(i_size_read(inode) - offset, | ||
| 1339 | 1 << inode->i_blkbits); | ||
| 1340 | } | ||
| 1341 | if (mapping_size > LONG_MAX) | ||
| 1342 | mapping_size = LONG_MAX; | ||
| 1343 | |||
| 1344 | bh_result->b_size = mapping_size; | ||
| 1345 | } | ||
| 1346 | |||
| 1236 | STATIC int | 1347 | STATIC int |
| 1237 | __xfs_get_blocks( | 1348 | __xfs_get_blocks( |
| 1238 | struct inode *inode, | 1349 | struct inode *inode, |
| @@ -1321,31 +1432,37 @@ __xfs_get_blocks( | |||
| 1321 | 1432 | ||
| 1322 | xfs_iunlock(ip, lockmode); | 1433 | xfs_iunlock(ip, lockmode); |
| 1323 | } | 1434 | } |
| 1324 | 1435 | trace_xfs_get_blocks_alloc(ip, offset, size, | |
| 1325 | trace_xfs_get_blocks_alloc(ip, offset, size, 0, &imap); | 1436 | ISUNWRITTEN(&imap) ? XFS_IO_UNWRITTEN |
| 1437 | : XFS_IO_DELALLOC, &imap); | ||
| 1326 | } else if (nimaps) { | 1438 | } else if (nimaps) { |
| 1327 | trace_xfs_get_blocks_found(ip, offset, size, 0, &imap); | 1439 | trace_xfs_get_blocks_found(ip, offset, size, |
| 1440 | ISUNWRITTEN(&imap) ? XFS_IO_UNWRITTEN | ||
| 1441 | : XFS_IO_OVERWRITE, &imap); | ||
| 1328 | xfs_iunlock(ip, lockmode); | 1442 | xfs_iunlock(ip, lockmode); |
| 1329 | } else { | 1443 | } else { |
| 1330 | trace_xfs_get_blocks_notfound(ip, offset, size); | 1444 | trace_xfs_get_blocks_notfound(ip, offset, size); |
| 1331 | goto out_unlock; | 1445 | goto out_unlock; |
| 1332 | } | 1446 | } |
| 1333 | 1447 | ||
| 1448 | /* trim mapping down to size requested */ | ||
| 1449 | if (direct || size > (1 << inode->i_blkbits)) | ||
| 1450 | xfs_map_trim_size(inode, iblock, bh_result, | ||
| 1451 | &imap, offset, size); | ||
| 1452 | |||
| 1453 | /* | ||
| 1454 | * For unwritten extents do not report a disk address in the buffered | ||
| 1455 | * read case (treat as if we're reading into a hole). | ||
| 1456 | */ | ||
| 1334 | if (imap.br_startblock != HOLESTARTBLOCK && | 1457 | if (imap.br_startblock != HOLESTARTBLOCK && |
| 1335 | imap.br_startblock != DELAYSTARTBLOCK) { | 1458 | imap.br_startblock != DELAYSTARTBLOCK && |
| 1336 | /* | 1459 | (create || !ISUNWRITTEN(&imap))) { |
| 1337 | * For unwritten extents do not report a disk address on | 1460 | xfs_map_buffer(inode, bh_result, &imap, offset); |
| 1338 | * the read case (treat as if we're reading into a hole). | 1461 | if (ISUNWRITTEN(&imap)) |
| 1339 | */ | ||
| 1340 | if (create || !ISUNWRITTEN(&imap)) | ||
| 1341 | xfs_map_buffer(inode, bh_result, &imap, offset); | ||
| 1342 | if (create && ISUNWRITTEN(&imap)) { | ||
| 1343 | if (direct) { | ||
| 1344 | bh_result->b_private = inode; | ||
| 1345 | set_buffer_defer_completion(bh_result); | ||
| 1346 | } | ||
| 1347 | set_buffer_unwritten(bh_result); | 1462 | set_buffer_unwritten(bh_result); |
| 1348 | } | 1463 | /* direct IO needs special help */ |
| 1464 | if (create && direct) | ||
| 1465 | xfs_map_direct(inode, bh_result, &imap, offset); | ||
| 1349 | } | 1466 | } |
| 1350 | 1467 | ||
| 1351 | /* | 1468 | /* |
| @@ -1378,39 +1495,6 @@ __xfs_get_blocks( | |||
| 1378 | } | 1495 | } |
| 1379 | } | 1496 | } |
| 1380 | 1497 | ||
| 1381 | /* | ||
| 1382 | * If this is O_DIRECT or the mpage code calling tell them how large | ||
| 1383 | * the mapping is, so that we can avoid repeated get_blocks calls. | ||
| 1384 | * | ||
| 1385 | * If the mapping spans EOF, then we have to break the mapping up as the | ||
| 1386 | * mapping for blocks beyond EOF must be marked new so that sub block | ||
| 1387 | * regions can be correctly zeroed. We can't do this for mappings within | ||
| 1388 | * EOF unless the mapping was just allocated or is unwritten, otherwise | ||
| 1389 | * the callers would overwrite existing data with zer | ||
