diff options
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 87 |
1 files changed, 29 insertions, 58 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index b572f7e840e0..6558ffd8d140 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -53,6 +53,7 @@ | |||
| 53 | #include "xfs_log_priv.h" | 53 | #include "xfs_log_priv.h" |
| 54 | #include "xfs_filestream.h" | 54 | #include "xfs_filestream.h" |
| 55 | #include "xfs_vnodeops.h" | 55 | #include "xfs_vnodeops.h" |
| 56 | #include "xfs_trace.h" | ||
| 56 | 57 | ||
| 57 | int | 58 | int |
| 58 | xfs_setattr( | 59 | xfs_setattr( |
| @@ -538,9 +539,8 @@ xfs_readlink_bmap( | |||
| 538 | d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); | 539 | d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); |
| 539 | byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); | 540 | byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); |
| 540 | 541 | ||
| 541 | bp = xfs_buf_read_flags(mp->m_ddev_targp, d, BTOBB(byte_cnt), | 542 | bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), |
| 542 | XBF_LOCK | XBF_MAPPED | | 543 | XBF_LOCK | XBF_MAPPED | XBF_DONT_BLOCK); |
| 543 | XBF_DONT_BLOCK); | ||
| 544 | error = XFS_BUF_GETERROR(bp); | 544 | error = XFS_BUF_GETERROR(bp); |
| 545 | if (error) { | 545 | if (error) { |
| 546 | xfs_ioerror_alert("xfs_readlink", | 546 | xfs_ioerror_alert("xfs_readlink", |
| @@ -709,6 +709,11 @@ xfs_fsync( | |||
| 709 | } | 709 | } |
| 710 | 710 | ||
| 711 | /* | 711 | /* |
| 712 | * Flags for xfs_free_eofblocks | ||
| 713 | */ | ||
| 714 | #define XFS_FREE_EOF_TRYLOCK (1<<0) | ||
| 715 | |||
| 716 | /* | ||
| 712 | * This is called by xfs_inactive to free any blocks beyond eof | 717 | * 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 | 718 | * when the link count isn't zero and by xfs_dm_punch_hole() when |
| 714 | * punching a hole to EOF. | 719 | * punching a hole to EOF. |
| @@ -726,7 +731,6 @@ xfs_free_eofblocks( | |||
| 726 | xfs_filblks_t map_len; | 731 | xfs_filblks_t map_len; |
| 727 | int nimaps; | 732 | int nimaps; |
| 728 | xfs_bmbt_irec_t imap; | 733 | xfs_bmbt_irec_t imap; |
| 729 | int use_iolock = (flags & XFS_FREE_EOF_LOCK); | ||
| 730 | 734 | ||
| 731 | /* | 735 | /* |
| 732 | * Figure out if there are any blocks beyond the end | 736 | * Figure out if there are any blocks beyond the end |
| @@ -768,14 +772,19 @@ xfs_free_eofblocks( | |||
| 768 | * cache and we can't | 772 | * cache and we can't |
| 769 | * do that within a transaction. | 773 | * do that within a transaction. |
| 770 | */ | 774 | */ |
| 771 | if (use_iolock) | 775 | if (flags & XFS_FREE_EOF_TRYLOCK) { |
| 776 | if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { | ||
| 777 | xfs_trans_cancel(tp, 0); | ||
| 778 | return 0; | ||
| 779 | } | ||
| 780 | } else { | ||
| 772 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 781 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
| 782 | } | ||
| 773 | error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, | 783 | error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, |
| 774 | ip->i_size); | 784 | ip->i_size); |
| 775 | if (error) { | 785 | if (error) { |
| 776 | xfs_trans_cancel(tp, 0); | 786 | xfs_trans_cancel(tp, 0); |
| 777 | if (use_iolock) | 787 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
| 778 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
| 779 | return error; | 788 | return error; |
| 780 | } | 789 | } |
| 781 | 790 | ||
| @@ -812,8 +821,7 @@ xfs_free_eofblocks( | |||
| 812 | error = xfs_trans_commit(tp, | 821 | error = xfs_trans_commit(tp, |
| 813 | XFS_TRANS_RELEASE_LOG_RES); | 822 | XFS_TRANS_RELEASE_LOG_RES); |
| 814 | } | 823 | } |
| 815 | xfs_iunlock(ip, (use_iolock ? (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL) | 824 | xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL); |
| 816 | : XFS_ILOCK_EXCL)); | ||
| 817 | } | 825 | } |
| 818 | return error; | 826 | return error; |
| 819 | } | 827 | } |
| @@ -1113,7 +1121,17 @@ xfs_release( | |||
| 1113 | (ip->i_df.if_flags & XFS_IFEXTENTS)) && | 1121 | (ip->i_df.if_flags & XFS_IFEXTENTS)) && |
| 1114 | (!(ip->i_d.di_flags & | 1122 | (!(ip->i_d.di_flags & |
| 1115 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) { | 1123 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) { |
| 1116 | error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); | 1124 | |
| 1125 | /* | ||
| 1126 | * If we can't get the iolock just skip truncating | ||
| 1127 | * the blocks past EOF because we could deadlock | ||
| 1128 | * with the mmap_sem otherwise. We'll get another | ||
| 1129 | * chance to drop them once the last reference to | ||
| 1130 | * the inode is dropped, so we'll never leak blocks | ||
| 1131 | * permanently. | ||
| 1132 | */ | ||
| 1133 | error = xfs_free_eofblocks(mp, ip, | ||
| 1134 | XFS_FREE_EOF_TRYLOCK); | ||
| 1117 | if (error) | 1135 | if (error) |
| 1118 | return error; | 1136 | return error; |
| 1119 | } | 1137 | } |
| @@ -1184,7 +1202,7 @@ xfs_inactive( | |||
| 1184 | (!(ip->i_d.di_flags & | 1202 | (!(ip->i_d.di_flags & |
| 1185 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || | 1203 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || |
| 1186 | (ip->i_delayed_blks != 0)))) { | 1204 | (ip->i_delayed_blks != 0)))) { |
| 1187 | error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); | 1205 | error = xfs_free_eofblocks(mp, ip, 0); |
| 1188 | if (error) | 1206 | if (error) |
| 1189 | return VN_INACTIVE_CACHE; | 1207 | return VN_INACTIVE_CACHE; |
| 1190 | } | 1208 | } |
| @@ -1380,7 +1398,6 @@ xfs_lookup( | |||
| 1380 | if (error) | 1398 | if (error) |
| 1381 | goto out_free_name; | 1399 | goto out_free_name; |
| 1382 | 1400 | ||
| 1383 | xfs_itrace_ref(*ipp); | ||
| 1384 | return 0; | 1401 | return 0; |
| 1385 | 1402 | ||
| 1386 | out_free_name: | 1403 | out_free_name: |
| @@ -1526,7 +1543,6 @@ xfs_create( | |||
| 1526 | * At this point, we've gotten a newly allocated inode. | 1543 | * At this point, we've gotten a newly allocated inode. |
| 1527 | * It is locked (and joined to the transaction). | 1544 | * It is locked (and joined to the transaction). |
| 1528 | */ | 1545 | */ |
| 1529 | xfs_itrace_ref(ip); | ||
| 1530 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 1546 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
| 1531 | 1547 | ||
| 1532 | /* | 1548 | /* |
| @@ -1986,9 +2002,6 @@ xfs_remove( | |||
| 1986 | if (!is_dir && link_zero && xfs_inode_is_filestream(ip)) | 2002 | if (!is_dir && link_zero && xfs_inode_is_filestream(ip)) |
| 1987 | xfs_filestream_deassociate(ip); | 2003 | xfs_filestream_deassociate(ip); |
| 1988 | 2004 | ||
| 1989 | xfs_itrace_exit(ip); | ||
| 1990 | xfs_itrace_exit(dp); | ||
| 1991 | |||
| 1992 | std_return: | 2005 | std_return: |
| 1993 | if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { | 2006 | if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { |
| 1994 | XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, dp, DM_RIGHT_NULL, | 2007 | XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, dp, DM_RIGHT_NULL, |
| @@ -2285,7 +2298,6 @@ xfs_symlink( | |||
| 2285 | goto error_return; | 2298 | goto error_return; |
| 2286 | goto error1; | 2299 | goto error1; |
| 2287 | } | 2300 | } |
| 2288 | xfs_itrace_ref(ip); | ||
| 2289 | 2301 | ||
| 2290 | /* | 2302 | /* |
| 2291 | * An error after we've joined dp to the transaction will result in the | 2303 | * An error after we've joined dp to the transaction will result in the |
| @@ -2456,46 +2468,6 @@ xfs_set_dmattrs( | |||
| 2456 | return error; | 2468 | return error; |
| 2457 | } | 2469 | } |
| 2458 | 2470 | ||
| 2459 | int | ||
| 2460 | xfs_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 | /* | 2471 | /* |
| 2500 | * xfs_alloc_file_space() | 2472 | * xfs_alloc_file_space() |
| 2501 | * This routine allocates disk space for the given file. | 2473 | * This routine allocates disk space for the given file. |
| @@ -2868,7 +2840,6 @@ xfs_free_file_space( | |||
| 2868 | ioffset = offset & ~(rounding - 1); | 2840 | ioffset = offset & ~(rounding - 1); |
| 2869 | 2841 | ||
| 2870 | if (VN_CACHED(VFS_I(ip)) != 0) { | 2842 | if (VN_CACHED(VFS_I(ip)) != 0) { |
| 2871 | xfs_inval_cached_trace(ip, ioffset, -1, ioffset, -1); | ||
| 2872 | error = xfs_flushinval_pages(ip, ioffset, -1, FI_REMAPF_LOCKED); | 2843 | error = xfs_flushinval_pages(ip, ioffset, -1, FI_REMAPF_LOCKED); |
| 2873 | if (error) | 2844 | if (error) |
| 2874 | goto out_unlock_iolock; | 2845 | goto out_unlock_iolock; |
