diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_aops.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.c | 62 |
1 files changed, 50 insertions, 12 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index d24e78f32f3e..15412fe15c3a 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -1478,22 +1478,38 @@ xfs_vm_direct_IO( | |||
1478 | if (rw & WRITE) { | 1478 | if (rw & WRITE) { |
1479 | iocb->private = xfs_alloc_ioend(inode, IO_NEW); | 1479 | iocb->private = xfs_alloc_ioend(inode, IO_NEW); |
1480 | 1480 | ||
1481 | ret = blockdev_direct_IO_no_locking(rw, iocb, inode, bdev, iov, | 1481 | ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov, |
1482 | offset, nr_segs, | 1482 | offset, nr_segs, |
1483 | xfs_get_blocks_direct, | 1483 | xfs_get_blocks_direct, |
1484 | xfs_end_io_direct_write); | 1484 | xfs_end_io_direct_write, NULL, 0); |
1485 | if (ret != -EIOCBQUEUED && iocb->private) | 1485 | if (ret != -EIOCBQUEUED && iocb->private) |
1486 | xfs_destroy_ioend(iocb->private); | 1486 | xfs_destroy_ioend(iocb->private); |
1487 | } else { | 1487 | } else { |
1488 | ret = blockdev_direct_IO_no_locking(rw, iocb, inode, bdev, iov, | 1488 | ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov, |
1489 | offset, nr_segs, | 1489 | offset, nr_segs, |
1490 | xfs_get_blocks_direct, | 1490 | xfs_get_blocks_direct, |
1491 | NULL); | 1491 | NULL, NULL, 0); |
1492 | } | 1492 | } |
1493 | 1493 | ||
1494 | return ret; | 1494 | return ret; |
1495 | } | 1495 | } |
1496 | 1496 | ||
1497 | STATIC void | ||
1498 | xfs_vm_write_failed( | ||
1499 | struct address_space *mapping, | ||
1500 | loff_t to) | ||
1501 | { | ||
1502 | struct inode *inode = mapping->host; | ||
1503 | |||
1504 | if (to > inode->i_size) { | ||
1505 | struct iattr ia = { | ||
1506 | .ia_valid = ATTR_SIZE | ATTR_FORCE, | ||
1507 | .ia_size = inode->i_size, | ||
1508 | }; | ||
1509 | xfs_setattr(XFS_I(inode), &ia, XFS_ATTR_NOLOCK); | ||
1510 | } | ||
1511 | } | ||
1512 | |||
1497 | STATIC int | 1513 | STATIC int |
1498 | xfs_vm_write_begin( | 1514 | xfs_vm_write_begin( |
1499 | struct file *file, | 1515 | struct file *file, |
@@ -1504,9 +1520,31 @@ xfs_vm_write_begin( | |||
1504 | struct page **pagep, | 1520 | struct page **pagep, |
1505 | void **fsdata) | 1521 | void **fsdata) |
1506 | { | 1522 | { |
1507 | *pagep = NULL; | 1523 | int ret; |
1508 | return block_write_begin(file, mapping, pos, len, flags | AOP_FLAG_NOFS, | 1524 | |
1509 | pagep, fsdata, xfs_get_blocks); | 1525 | ret = block_write_begin(mapping, pos, len, flags | AOP_FLAG_NOFS, |
1526 | pagep, xfs_get_blocks); | ||
1527 | if (unlikely(ret)) | ||
1528 | xfs_vm_write_failed(mapping, pos + len); | ||
1529 | return ret; | ||
1530 | } | ||
1531 | |||
1532 | STATIC int | ||
1533 | xfs_vm_write_end( | ||
1534 | struct file *file, | ||
1535 | struct address_space *mapping, | ||
1536 | loff_t pos, | ||
1537 | unsigned len, | ||
1538 | unsigned copied, | ||
1539 | struct page *page, | ||
1540 | void *fsdata) | ||
1541 | { | ||
1542 | int ret; | ||
1543 | |||
1544 | ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); | ||
1545 | if (unlikely(ret < len)) | ||
1546 | xfs_vm_write_failed(mapping, pos + len); | ||
1547 | return ret; | ||
1510 | } | 1548 | } |
1511 | 1549 | ||
1512 | STATIC sector_t | 1550 | STATIC sector_t |
@@ -1551,7 +1589,7 @@ const struct address_space_operations xfs_address_space_operations = { | |||
1551 | .releasepage = xfs_vm_releasepage, | 1589 | .releasepage = xfs_vm_releasepage, |
1552 | .invalidatepage = xfs_vm_invalidatepage, | 1590 | .invalidatepage = xfs_vm_invalidatepage, |
1553 | .write_begin = xfs_vm_write_begin, | 1591 | .write_begin = xfs_vm_write_begin, |
1554 | .write_end = generic_write_end, | 1592 | .write_end = xfs_vm_write_end, |
1555 | .bmap = xfs_vm_bmap, | 1593 | .bmap = xfs_vm_bmap, |
1556 | .direct_IO = xfs_vm_direct_IO, | 1594 | .direct_IO = xfs_vm_direct_IO, |
1557 | .migratepage = buffer_migrate_page, | 1595 | .migratepage = buffer_migrate_page, |