diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_aops.c')
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.c | 38 | 
1 files changed, 28 insertions, 10 deletions
| diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 381854461b28..c2e30eea74dc 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
| @@ -186,19 +186,37 @@ xfs_destroy_ioend( | |||
| 186 | } | 186 | } | 
| 187 | 187 | ||
| 188 | /* | 188 | /* | 
| 189 | * If the end of the current ioend is beyond the current EOF, | ||
| 190 | * return the new EOF value, otherwise zero. | ||
| 191 | */ | ||
| 192 | STATIC xfs_fsize_t | ||
| 193 | xfs_ioend_new_eof( | ||
| 194 | xfs_ioend_t *ioend) | ||
| 195 | { | ||
| 196 | xfs_inode_t *ip = XFS_I(ioend->io_inode); | ||
| 197 | xfs_fsize_t isize; | ||
| 198 | xfs_fsize_t bsize; | ||
| 199 | |||
| 200 | bsize = ioend->io_offset + ioend->io_size; | ||
| 201 | isize = MAX(ip->i_size, ip->i_new_size); | ||
| 202 | isize = MIN(isize, bsize); | ||
| 203 | return isize > ip->i_d.di_size ? isize : 0; | ||
| 204 | } | ||
| 205 | |||
| 206 | /* | ||
| 189 | * Update on-disk file size now that data has been written to disk. | 207 | * Update on-disk file size now that data has been written to disk. | 
| 190 | * The current in-memory file size is i_size. If a write is beyond | 208 | * The current in-memory file size is i_size. If a write is beyond | 
| 191 | * eof i_new_size will be the intended file size until i_size is | 209 | * eof i_new_size will be the intended file size until i_size is | 
| 192 | * updated. If this write does not extend all the way to the valid | 210 | * updated. If this write does not extend all the way to the valid | 
| 193 | * file size then restrict this update to the end of the write. | 211 | * file size then restrict this update to the end of the write. | 
| 194 | */ | 212 | */ | 
| 213 | |||
| 195 | STATIC void | 214 | STATIC void | 
| 196 | xfs_setfilesize( | 215 | xfs_setfilesize( | 
| 197 | xfs_ioend_t *ioend) | 216 | xfs_ioend_t *ioend) | 
| 198 | { | 217 | { | 
| 199 | xfs_inode_t *ip = XFS_I(ioend->io_inode); | 218 | xfs_inode_t *ip = XFS_I(ioend->io_inode); | 
| 200 | xfs_fsize_t isize; | 219 | xfs_fsize_t isize; | 
| 201 | xfs_fsize_t bsize; | ||
| 202 | 220 | ||
| 203 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); | 221 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); | 
| 204 | ASSERT(ioend->io_type != IOMAP_READ); | 222 | ASSERT(ioend->io_type != IOMAP_READ); | 
| @@ -206,16 +224,10 @@ xfs_setfilesize( | |||
| 206 | if (unlikely(ioend->io_error)) | 224 | if (unlikely(ioend->io_error)) | 
| 207 | return; | 225 | return; | 
| 208 | 226 | ||
| 209 | bsize = ioend->io_offset + ioend->io_size; | ||
| 210 | |||
| 211 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 227 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 
| 212 | 228 | isize = xfs_ioend_new_eof(ioend); | |
| 213 | isize = MAX(ip->i_size, ip->i_new_size); | 229 | if (isize) { | 
| 214 | isize = MIN(isize, bsize); | ||
| 215 | |||
| 216 | if (ip->i_d.di_size < isize) { | ||
| 217 | ip->i_d.di_size = isize; | 230 | ip->i_d.di_size = isize; | 
| 218 | ip->i_update_core = 1; | ||
| 219 | xfs_mark_inode_dirty_sync(ip); | 231 | xfs_mark_inode_dirty_sync(ip); | 
| 220 | } | 232 | } | 
| 221 | 233 | ||
| @@ -404,10 +416,16 @@ xfs_submit_ioend_bio( | |||
| 404 | struct bio *bio) | 416 | struct bio *bio) | 
| 405 | { | 417 | { | 
| 406 | atomic_inc(&ioend->io_remaining); | 418 | atomic_inc(&ioend->io_remaining); | 
| 407 | |||
| 408 | bio->bi_private = ioend; | 419 | bio->bi_private = ioend; | 
| 409 | bio->bi_end_io = xfs_end_bio; | 420 | bio->bi_end_io = xfs_end_bio; | 
| 410 | 421 | ||
| 422 | /* | ||
| 423 | * If the I/O is beyond EOF we mark the inode dirty immediately | ||
| 424 | * but don't update the inode size until I/O completion. | ||
| 425 | */ | ||
| 426 | if (xfs_ioend_new_eof(ioend)) | ||
| 427 | xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode)); | ||
| 428 | |||
| 411 | submit_bio(WRITE, bio); | 429 | submit_bio(WRITE, bio); | 
| 412 | ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP)); | 430 | ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP)); | 
| 413 | bio_put(bio); | 431 | bio_put(bio); | 
