aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_vnodeops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r--fs/xfs/xfs_vnodeops.c79
1 files changed, 28 insertions, 51 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index b572f7e840e0..578f3f59b789 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -538,9 +538,8 @@ xfs_readlink_bmap(
538 d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); 538 d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
539 byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); 539 byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
540 540
541 bp = xfs_buf_read_flags(mp->m_ddev_targp, d, BTOBB(byte_cnt), 541 bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt),
542 XBF_LOCK | XBF_MAPPED | 542 XBF_LOCK | XBF_MAPPED | XBF_DONT_BLOCK);
543 XBF_DONT_BLOCK);
544 error = XFS_BUF_GETERROR(bp); 543 error = XFS_BUF_GETERROR(bp);
545 if (error) { 544 if (error) {
546 xfs_ioerror_alert("xfs_readlink", 545 xfs_ioerror_alert("xfs_readlink",
@@ -709,6 +708,11 @@ xfs_fsync(
709} 708}
710 709
711/* 710/*
711 * Flags for xfs_free_eofblocks
712 */
713#define XFS_FREE_EOF_TRYLOCK (1<<0)
714
715/*
712 * This is called by xfs_inactive to free any blocks beyond eof 716 * This is called by xfs_inactive to free any blocks beyond eof
713 * when the link count isn't zero and by xfs_dm_punch_hole() when 717 * when the link count isn't zero and by xfs_dm_punch_hole() when
714 * punching a hole to EOF. 718 * punching a hole to EOF.
@@ -726,7 +730,6 @@ xfs_free_eofblocks(
726 xfs_filblks_t map_len; 730 xfs_filblks_t map_len;
727 int nimaps; 731 int nimaps;
728 xfs_bmbt_irec_t imap; 732 xfs_bmbt_irec_t imap;
729 int use_iolock = (flags & XFS_FREE_EOF_LOCK);
730 733
731 /* 734 /*
732 * Figure out if there are any blocks beyond the end 735 * Figure out if there are any blocks beyond the end
@@ -768,14 +771,19 @@ xfs_free_eofblocks(
768 * cache and we can't 771 * cache and we can't
769 * do that within a transaction. 772 * do that within a transaction.
770 */ 773 */
771 if (use_iolock) 774 if (flags & XFS_FREE_EOF_TRYLOCK) {
775 if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
776 xfs_trans_cancel(tp, 0);
777 return 0;
778 }
779 } else {
772 xfs_ilock(ip, XFS_IOLOCK_EXCL); 780 xfs_ilock(ip, XFS_IOLOCK_EXCL);
781 }
773 error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 782 error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
774 ip->i_size); 783 ip->i_size);
775 if (error) { 784 if (error) {
776 xfs_trans_cancel(tp, 0); 785 xfs_trans_cancel(tp, 0);
777 if (use_iolock) 786 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
778 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
779 return error; 787 return error;
780 } 788 }
781 789
@@ -812,8 +820,7 @@ xfs_free_eofblocks(
812 error = xfs_trans_commit(tp, 820 error = xfs_trans_commit(tp,
813 XFS_TRANS_RELEASE_LOG_RES); 821 XFS_TRANS_RELEASE_LOG_RES);
814 } 822 }
815 xfs_iunlock(ip, (use_iolock ? (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL) 823 xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
816 : XFS_ILOCK_EXCL));
817 } 824 }
818 return error; 825 return error;
819} 826}
@@ -1113,7 +1120,17 @@ xfs_release(
1113 (ip->i_df.if_flags & XFS_IFEXTENTS)) && 1120 (ip->i_df.if_flags & XFS_IFEXTENTS)) &&
1114 (!(ip->i_d.di_flags & 1121 (!(ip->i_d.di_flags &
1115 (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) { 1122 (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) {
1116 error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); 1123
1124 /*
1125 * If we can't get the iolock just skip truncating
1126 * the blocks past EOF because we could deadlock
1127 * with the mmap_sem otherwise. We'll get another
1128 * chance to drop them once the last reference to
1129 * the inode is dropped, so we'll never leak blocks
1130 * permanently.
1131 */
1132 error = xfs_free_eofblocks(mp, ip,
1133 XFS_FREE_EOF_TRYLOCK);
1117 if (error) 1134 if (error)
1118 return error; 1135 return error;
1119 } 1136 }
@@ -1184,7 +1201,7 @@ xfs_inactive(
1184 (!(ip->i_d.di_flags & 1201 (!(ip->i_d.di_flags &
1185 (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || 1202 (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) ||
1186 (ip->i_delayed_blks != 0)))) { 1203 (ip->i_delayed_blks != 0)))) {
1187 error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); 1204 error = xfs_free_eofblocks(mp, ip, 0);
1188 if (error) 1205 if (error)
1189 return VN_INACTIVE_CACHE; 1206 return VN_INACTIVE_CACHE;
1190 } 1207 }
@@ -2456,46 +2473,6 @@ xfs_set_dmattrs(
2456 return error; 2473 return error;
2457} 2474}
2458 2475
2459int
2460xfs_reclaim(
2461 xfs_inode_t *ip)
2462{
2463
2464 xfs_itrace_entry(ip);
2465
2466 ASSERT(!VN_MAPPED(VFS_I(ip)));
2467
2468 /* bad inode, get out here ASAP */
2469 if (is_bad_inode(VFS_I(ip))) {
2470 xfs_ireclaim(ip);
2471 return 0;
2472 }
2473
2474 xfs_ioend_wait(ip);
2475
2476 ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
2477
2478 /*
2479 * If we have nothing to flush with this inode then complete the
2480 * teardown now, otherwise break the link between the xfs inode and the
2481 * linux inode and clean up the xfs inode later. This avoids flushing
2482 * the inode to disk during the delete operation itself.
2483 *
2484 * When breaking the link, we need to set the XFS_IRECLAIMABLE flag
2485 * first to ensure that xfs_iunpin() will never see an xfs inode
2486 * that has a linux inode being reclaimed. Synchronisation is provided
2487 * by the i_flags_lock.
2488 */
2489 if (!ip->i_update_core && (ip->i_itemp == NULL)) {
2490 xfs_ilock(ip, XFS_ILOCK_EXCL);
2491 xfs_iflock(ip);
2492 xfs_iflags_set(ip, XFS_IRECLAIMABLE);
2493 return xfs_reclaim_inode(ip, 1, XFS_IFLUSH_DELWRI_ELSE_SYNC);
2494 }
2495 xfs_inode_set_reclaim_tag(ip);
2496 return 0;
2497}
2498
2499/* 2476/*
2500 * xfs_alloc_file_space() 2477 * xfs_alloc_file_space()
2501 * This routine allocates disk space for the given file. 2478 * This routine allocates disk space for the given file.