|
|
| version 1.141, 2007/03/20 05:07:28 | version 1.142, 2007/03/30 04:04:14 |
|---|---|
| Line 141 xfs_destroy_ioend( | Line 141 xfs_destroy_ioend( |
| } | } |
| /* | /* |
| * Update on-disk file size now that data has been written to disk. | |
| * The current in-memory file size is i_size. If a write is beyond | |
| * eof io_new_size will be the intended file size until i_size is | |
| * updated. If this write does not extend all the way to the valid | |
| * file size then restrict this update to the end of the write. | |
| */ | |
| STATIC void | |
| xfs_setfilesize( | |
| xfs_ioend_t *ioend) | |
| { | |
| xfs_inode_t *ip; | |
| xfs_fsize_t isize; | |
| xfs_fsize_t bsize; | |
| ip = xfs_vtoi(ioend->io_vnode); | |
| ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); | |
| ASSERT(ioend->io_type != IOMAP_READ); | |
| if (unlikely(ioend->io_error)) | |
| return; | |
| bsize = ioend->io_offset + ioend->io_size; | |
| xfs_ilock(ip, XFS_ILOCK_EXCL); | |
| isize = MAX(ip->i_size, ip->i_iocore.io_new_size); | |
| isize = MIN(isize, bsize); | |
| if (ip->i_d.di_size < isize) { | |
| ip->i_d.di_size = isize; | |
| ip->i_update_core = 1; | |
| ip->i_update_size = 1; | |
| } | |
| xfs_iunlock(ip, XFS_ILOCK_EXCL); | |
| } | |
| /* | |
| * Buffered IO write completion for delayed allocate extents. | * Buffered IO write completion for delayed allocate extents. |
| * TODO: Update ondisk isize now that we know the file data | |
| * has been flushed (i.e. the notorious "NULL file" problem). | |
| */ | */ |
| STATIC void | STATIC void |
| xfs_end_bio_delalloc( | xfs_end_bio_delalloc( |
| Line 152 xfs_end_bio_delalloc( | Line 189 xfs_end_bio_delalloc( |
| xfs_ioend_t *ioend = | xfs_ioend_t *ioend = |
| container_of(work, xfs_ioend_t, io_work); | container_of(work, xfs_ioend_t, io_work); |
| xfs_setfilesize(ioend); | |
| xfs_destroy_ioend(ioend); | xfs_destroy_ioend(ioend); |
| } | } |
| Line 165 xfs_end_bio_written( | Line 203 xfs_end_bio_written( |
| xfs_ioend_t *ioend = | xfs_ioend_t *ioend = |
| container_of(work, xfs_ioend_t, io_work); | container_of(work, xfs_ioend_t, io_work); |
| xfs_setfilesize(ioend); | |
| xfs_destroy_ioend(ioend); | xfs_destroy_ioend(ioend); |
| } | } |
| Line 184 xfs_end_bio_unwritten( | Line 223 xfs_end_bio_unwritten( |
| xfs_off_t offset = ioend->io_offset; | xfs_off_t offset = ioend->io_offset; |
| size_t size = ioend->io_size; | size_t size = ioend->io_size; |
| if (likely(!ioend->io_error)) | if (likely(!ioend->io_error)) { |
| bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL); | bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL); |
| xfs_setfilesize(ioend); | |
| } | |
| xfs_destroy_ioend(ioend); | |
| } | |
| /* | |
| * IO read completion for regular, written extents. | |
| */ | |
| STATIC void | |
| xfs_end_bio_read( | |
| struct work_struct *work) | |
| { | |
| xfs_ioend_t *ioend = | |
| container_of(work, xfs_ioend_t, io_work); | |
| xfs_destroy_ioend(ioend); | xfs_destroy_ioend(ioend); |
| } | } |
| Line 224 xfs_alloc_ioend( | Line 278 xfs_alloc_ioend( |
| INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten); | INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten); |
| else if (type == IOMAP_DELAY) | else if (type == IOMAP_DELAY) |
| INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc); | INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc); |
| else if (type == IOMAP_READ) | |
| INIT_WORK(&ioend->io_work, xfs_end_bio_read); | |
| else | else |
| INIT_WORK(&ioend->io_work, xfs_end_bio_written); | INIT_WORK(&ioend->io_work, xfs_end_bio_written); |
| Line 913 xfs_page_state_convert( | Line 969 xfs_page_state_convert( |
| bh = head = page_buffers(page); | bh = head = page_buffers(page); |
| offset = page_offset(page); | offset = page_offset(page); |
| flags = -1; | flags = -1; |
| type = 0; | type = IOMAP_READ; |
| /* TODO: cleanup count and page_dirty */ | /* TODO: cleanup count and page_dirty */ |
| Line 999 xfs_page_state_convert( | Line 1055 xfs_page_state_convert( |
| * That means it must already have extents allocated | * That means it must already have extents allocated |
| * underneath it. Map the extent by reading it. | * underneath it. Map the extent by reading it. |
| */ | */ |
| if (!iomap_valid || type != 0) { | if (!iomap_valid || type != IOMAP_READ) { |
| flags = BMAPI_READ; | flags = BMAPI_READ; |
| size = xfs_probe_cluster(inode, page, bh, | size = xfs_probe_cluster(inode, page, bh, |
| head, 1); | head, 1); |
| Line 1010 xfs_page_state_convert( | Line 1066 xfs_page_state_convert( |
| iomap_valid = xfs_iomap_valid(&iomap, offset); | iomap_valid = xfs_iomap_valid(&iomap, offset); |
| } | } |
| type = 0; | type = IOMAP_READ; |
| if (!test_and_set_bit(BH_Lock, &bh->b_state)) { | if (!test_and_set_bit(BH_Lock, &bh->b_state)) { |
| ASSERT(buffer_mapped(bh)); | ASSERT(buffer_mapped(bh)); |
| if (iomap_valid) | if (iomap_valid) |
| Line 1356 xfs_end_io_direct( | Line 1412 xfs_end_io_direct( |
| * completion handler in the future, in which case all this can | * completion handler in the future, in which case all this can |
| * go away. | * go away. |
| */ | */ |
| if (private && size > 0) { | ioend->io_offset = offset; |
| ioend->io_offset = offset; | ioend->io_size = size; |
| ioend->io_size = size; | if (ioend->io_type == IOMAP_READ) { |
| xfs_finish_ioend(ioend); | |
| } else if (private && size > 0) { | |
| xfs_finish_ioend(ioend); | xfs_finish_ioend(ioend); |
| } else { | } else { |
| xfs_destroy_ioend(ioend); | /* |
| * A direct I/O write ioend starts it's life in unwritten | |
| * state in case they map an unwritten extent. This write | |
| * didn't map an unwritten extent so switch it's completion | |
| * handler. | |
| */ | |
| INIT_WORK(&ioend->io_work, xfs_end_bio_written); | |
| xfs_finish_ioend(ioend); | |
| } | } |
| /* | /* |
| Line 1392 xfs_vm_direct_IO( | Line 1457 xfs_vm_direct_IO( |
| if (error) | if (error) |
| return -error; | return -error; |
| iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN); | |
| if (rw == WRITE) { | if (rw == WRITE) { |
| iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN); | |
| ret = blockdev_direct_IO_own_locking(rw, iocb, inode, | ret = blockdev_direct_IO_own_locking(rw, iocb, inode, |
| iomap.iomap_target->bt_bdev, | iomap.iomap_target->bt_bdev, |
| iov, offset, nr_segs, | iov, offset, nr_segs, |
| xfs_get_blocks_direct, | xfs_get_blocks_direct, |
| xfs_end_io_direct); | xfs_end_io_direct); |
| } else { | } else { |
| iocb->private = xfs_alloc_ioend(inode, IOMAP_READ); | |
| ret = blockdev_direct_IO_no_locking(rw, iocb, inode, | ret = blockdev_direct_IO_no_locking(rw, iocb, inode, |
| iomap.iomap_target->bt_bdev, | iomap.iomap_target->bt_bdev, |
| iov, offset, nr_segs, | iov, offset, nr_segs, |