diff options
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index aa238c8fbd7a..8b6812f66a15 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -1838,6 +1838,12 @@ again: | |||
| 1838 | #endif | 1838 | #endif |
| 1839 | } | 1839 | } |
| 1840 | 1840 | ||
| 1841 | /* | ||
| 1842 | * xfs_lock_two_inodes() can only be used to lock one type of lock | ||
| 1843 | * at a time - the iolock or the ilock, but not both at once. If | ||
| 1844 | * we lock both at once, lockdep will report false positives saying | ||
| 1845 | * we have violated locking orders. | ||
| 1846 | */ | ||
| 1841 | void | 1847 | void |
| 1842 | xfs_lock_two_inodes( | 1848 | xfs_lock_two_inodes( |
| 1843 | xfs_inode_t *ip0, | 1849 | xfs_inode_t *ip0, |
| @@ -1848,6 +1854,8 @@ xfs_lock_two_inodes( | |||
| 1848 | int attempts = 0; | 1854 | int attempts = 0; |
| 1849 | xfs_log_item_t *lp; | 1855 | xfs_log_item_t *lp; |
| 1850 | 1856 | ||
| 1857 | if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)) | ||
| 1858 | ASSERT((lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)) == 0); | ||
| 1851 | ASSERT(ip0->i_ino != ip1->i_ino); | 1859 | ASSERT(ip0->i_ino != ip1->i_ino); |
| 1852 | 1860 | ||
| 1853 | if (ip0->i_ino > ip1->i_ino) { | 1861 | if (ip0->i_ino > ip1->i_ino) { |
| @@ -3152,6 +3160,13 @@ error1: /* Just cancel transaction */ | |||
| 3152 | /* | 3160 | /* |
| 3153 | * Zero file bytes between startoff and endoff inclusive. | 3161 | * Zero file bytes between startoff and endoff inclusive. |
| 3154 | * The iolock is held exclusive and no blocks are buffered. | 3162 | * The iolock is held exclusive and no blocks are buffered. |
| 3163 | * | ||
| 3164 | * This function is used by xfs_free_file_space() to zero | ||
| 3165 | * partial blocks when the range to free is not block aligned. | ||
| 3166 | * When unreserving space with boundaries that are not block | ||
| 3167 | * aligned we round up the start and round down the end | ||
| 3168 | * boundaries and then use this function to zero the parts of | ||
| 3169 | * the blocks that got dropped during the rounding. | ||
| 3155 | */ | 3170 | */ |
| 3156 | STATIC int | 3171 | STATIC int |
| 3157 | xfs_zero_remaining_bytes( | 3172 | xfs_zero_remaining_bytes( |
| @@ -3168,6 +3183,17 @@ xfs_zero_remaining_bytes( | |||
| 3168 | int nimap; | 3183 | int nimap; |
| 3169 | int error = 0; | 3184 | int error = 0; |
| 3170 | 3185 | ||
| 3186 | /* | ||
| 3187 | * Avoid doing I/O beyond eof - it's not necessary | ||
| 3188 | * since nothing can read beyond eof. The space will | ||
| 3189 | * be zeroed when the file is extended anyway. | ||
| 3190 | */ | ||
| 3191 | if (startoff >= ip->i_size) | ||
| 3192 | return 0; | ||
| 3193 | |||
| 3194 | if (endoff > ip->i_size) | ||
| 3195 | endoff = ip->i_size; | ||
| 3196 | |||
| 3171 | bp = xfs_buf_get_noaddr(mp->m_sb.sb_blocksize, | 3197 | bp = xfs_buf_get_noaddr(mp->m_sb.sb_blocksize, |
| 3172 | XFS_IS_REALTIME_INODE(ip) ? | 3198 | XFS_IS_REALTIME_INODE(ip) ? |
| 3173 | mp->m_rtdev_targp : mp->m_ddev_targp); | 3199 | mp->m_rtdev_targp : mp->m_ddev_targp); |
