aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 17:41:33 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 17:41:33 -0400
commitfdb64f93b38a3470fa4db8cd5720b8c731922d1a (patch)
tree3b17370d30a2b580af72b26f37ec7176c9ecdd84 /fs/xfs
parent2d9ce177e68645945e3366cfe2d66ee3c28cd4f2 (diff)
parentc32676eea19ce29cb74dba0f97b085e83f6b8915 (diff)
Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6
* 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6: [XFS] Fix inode size update before data write in xfs_setattr [XFS] Allow punching holes to free space when at ENOSPC [XFS] Implement ->page_mkwrite in XFS. [FS] Implement block_page_mkwrite. Manually fix up conflict with Nick's VM fault handling patches in fs/xfs/linux-2.6/xfs_file.c Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c16
-rw-r--r--fs/xfs/xfs_vnodeops.c30
2 files changed, 44 insertions, 2 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 2d4be2f247b2..0d4001eafd16 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -413,6 +413,20 @@ xfs_file_open_exec(
413} 413}
414#endif /* HAVE_FOP_OPEN_EXEC */ 414#endif /* HAVE_FOP_OPEN_EXEC */
415 415
416/*
417 * mmap()d file has taken write protection fault and is being made
418 * writable. We can set the page state up correctly for a writable
419 * page, which means we can do correct delalloc accounting (ENOSPC
420 * checking!) and unwritten extent mapping.
421 */
422STATIC int
423xfs_vm_page_mkwrite(
424 struct vm_area_struct *vma,
425 struct page *page)
426{
427 return block_page_mkwrite(vma, page, xfs_get_blocks);
428}
429
416const struct file_operations xfs_file_operations = { 430const struct file_operations xfs_file_operations = {
417 .llseek = generic_file_llseek, 431 .llseek = generic_file_llseek,
418 .read = do_sync_read, 432 .read = do_sync_read,
@@ -465,11 +479,13 @@ const struct file_operations xfs_dir_file_operations = {
465 479
466static struct vm_operations_struct xfs_file_vm_ops = { 480static struct vm_operations_struct xfs_file_vm_ops = {
467 .fault = filemap_fault, 481 .fault = filemap_fault,
482 .page_mkwrite = xfs_vm_page_mkwrite,
468}; 483};
469 484
470#ifdef CONFIG_XFS_DMAPI 485#ifdef CONFIG_XFS_DMAPI
471static struct vm_operations_struct xfs_dmapi_file_vm_ops = { 486static struct vm_operations_struct xfs_dmapi_file_vm_ops = {
472 .fault = xfs_vm_fault, 487 .fault = xfs_vm_fault,
488 .page_mkwrite = xfs_vm_page_mkwrite,
473#ifdef HAVE_VMOP_MPROTECT 489#ifdef HAVE_VMOP_MPROTECT
474 .mprotect = xfs_vm_mprotect, 490 .mprotect = xfs_vm_mprotect,
475#endif 491#endif
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 79b522779aa4..1a5ad8cd97b0 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -589,7 +589,30 @@ xfs_setattr(
589 code = xfs_igrow_start(ip, vap->va_size, credp); 589 code = xfs_igrow_start(ip, vap->va_size, credp);
590 } 590 }
591 xfs_iunlock(ip, XFS_ILOCK_EXCL); 591 xfs_iunlock(ip, XFS_ILOCK_EXCL);
592 vn_iowait(vp); /* wait for the completion of any pending DIOs */ 592
593 /*
594 * We are going to log the inode size change in this
595 * transaction so any previous writes that are beyond the on
596 * disk EOF and the new EOF that have not been written out need
597 * to be written here. If we do not write the data out, we
598 * expose ourselves to the null files problem.
599 *
600 * Only flush from the on disk size to the smaller of the in
601 * memory file size or the new size as that's the range we
602 * really care about here and prevents waiting for other data
603 * not within the range we care about here.
604 */
605 if (!code &&
606 (ip->i_size != ip->i_d.di_size) &&
607 (vap->va_size > ip->i_d.di_size)) {
608 code = bhv_vop_flush_pages(XFS_ITOV(ip),
609 ip->i_d.di_size, vap->va_size,
610 XFS_B_ASYNC, FI_NONE);
611 }
612
613 /* wait for all I/O to complete */
614 vn_iowait(vp);
615
593 if (!code) 616 if (!code)
594 code = xfs_itruncate_data(ip, vap->va_size); 617 code = xfs_itruncate_data(ip, vap->va_size);
595 if (code) { 618 if (code) {
@@ -4434,9 +4457,12 @@ xfs_free_file_space(
4434 while (!error && !done) { 4457 while (!error && !done) {
4435 4458
4436 /* 4459 /*
4437 * allocate and setup the transaction 4460 * allocate and setup the transaction. Allow this
4461 * transaction to dip into the reserve blocks to ensure
4462 * the freeing of the space succeeds at ENOSPC.
4438 */ 4463 */
4439 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); 4464 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
4465 tp->t_flags |= XFS_TRANS_RESERVE;
4440 error = xfs_trans_reserve(tp, 4466 error = xfs_trans_reserve(tp,
4441 resblks, 4467 resblks,
4442 XFS_WRITE_LOG_RES(mp), 4468 XFS_WRITE_LOG_RES(mp),