diff options
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.c | 4 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 20 | ||||
| -rw-r--r-- | fs/xfs/xfs_buf_item.c | 44 | ||||
| -rw-r--r-- | fs/xfs/xfs_dfrag.c | 9 | ||||
| -rw-r--r-- | fs/xfs/xfs_log.c | 62 | ||||
| -rw-r--r-- | fs/xfs/xfs_log_priv.h | 1 | ||||
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 26 |
7 files changed, 119 insertions, 47 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index f42f80a3b1fa..a44d68eb50b5 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
| @@ -1338,6 +1338,10 @@ __xfs_get_blocks( | |||
| 1338 | offset = (xfs_off_t)iblock << inode->i_blkbits; | 1338 | offset = (xfs_off_t)iblock << inode->i_blkbits; |
| 1339 | ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); | 1339 | ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); |
| 1340 | size = bh_result->b_size; | 1340 | size = bh_result->b_size; |
| 1341 | |||
| 1342 | if (!create && direct && offset >= i_size_read(inode)) | ||
| 1343 | return 0; | ||
| 1344 | |||
| 1341 | error = xfs_iomap(XFS_I(inode), offset, size, | 1345 | error = xfs_iomap(XFS_I(inode), offset, size, |
| 1342 | create ? flags : BMAPI_READ, &iomap, &niomap); | 1346 | create ? flags : BMAPI_READ, &iomap, &niomap); |
| 1343 | if (error) | 1347 | if (error) |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 73c65f19e549..18d3c8487835 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
| @@ -1302,9 +1302,29 @@ xfs_fs_remount( | |||
| 1302 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 1302 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
| 1303 | break; | 1303 | break; |
| 1304 | default: | 1304 | default: |
| 1305 | /* | ||
| 1306 | * Logically we would return an error here to prevent | ||
| 1307 | * users from believing they might have changed | ||
| 1308 | * mount options using remount which can't be changed. | ||
| 1309 | * | ||
| 1310 | * But unfortunately mount(8) adds all options from | ||
| 1311 | * mtab and fstab to the mount arguments in some cases | ||
| 1312 | * so we can't blindly reject options, but have to | ||
| 1313 | * check for each specified option if it actually | ||
| 1314 | * differs from the currently set option and only | ||
| 1315 | * reject it if that's the case. | ||
| 1316 | * | ||
| 1317 | * Until that is implemented we return success for | ||
| 1318 | * every remount request, and silently ignore all | ||
| 1319 | * options that we can't actually change. | ||
| 1320 | */ | ||
| 1321 | #if 0 | ||
| 1305 | printk(KERN_INFO | 1322 | printk(KERN_INFO |
| 1306 | "XFS: mount option \"%s\" not supported for remount\n", p); | 1323 | "XFS: mount option \"%s\" not supported for remount\n", p); |
| 1307 | return -EINVAL; | 1324 | return -EINVAL; |
| 1325 | #else | ||
| 1326 | return 0; | ||
| 1327 | #endif | ||
| 1308 | } | 1328 | } |
| 1309 | } | 1329 | } |
| 1310 | 1330 | ||
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 608c30c3f76b..002fc2617c8e 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
| @@ -732,6 +732,7 @@ xfs_buf_item_init( | |||
| 732 | bip->bli_item.li_ops = &xfs_buf_item_ops; | 732 | bip->bli_item.li_ops = &xfs_buf_item_ops; |
| 733 | bip->bli_item.li_mountp = mp; | 733 | bip->bli_item.li_mountp = mp; |
| 734 | bip->bli_buf = bp; | 734 | bip->bli_buf = bp; |
| 735 | xfs_buf_hold(bp); | ||
| 735 | bip->bli_format.blf_type = XFS_LI_BUF; | 736 | bip->bli_format.blf_type = XFS_LI_BUF; |
| 736 | bip->bli_format.blf_blkno = (__int64_t)XFS_BUF_ADDR(bp); | 737 | bip->bli_format.blf_blkno = (__int64_t)XFS_BUF_ADDR(bp); |
| 737 | bip->bli_format.blf_len = (ushort)BTOBB(XFS_BUF_COUNT(bp)); | 738 | bip->bli_format.blf_len = (ushort)BTOBB(XFS_BUF_COUNT(bp)); |
| @@ -867,6 +868,21 @@ xfs_buf_item_dirty( | |||
| 867 | return (bip->bli_flags & XFS_BLI_DIRTY); | 868 | return (bip->bli_flags & XFS_BLI_DIRTY); |
| 868 | } | 869 | } |
| 869 | 870 | ||
| 871 | STATIC void | ||
| 872 | xfs_buf_item_free( | ||
| 873 | xfs_buf_log_item_t *bip) | ||
| 874 | { | ||
| 875 | #ifdef XFS_TRANS_DEBUG | ||
| 876 | kmem_free(bip->bli_orig); | ||
| 877 | kmem_free(bip->bli_logged); | ||
| 878 | #endif /* XFS_TRANS_DEBUG */ | ||
| 879 | |||
| 880 | #ifdef XFS_BLI_TRACE | ||
| 881 | ktrace_free(bip->bli_trace); | ||
| 882 | #endif | ||
| 883 | kmem_zone_free(xfs_buf_item_zone, bip); | ||
| 884 | } | ||
| 885 | |||
| 870 | /* | 886 | /* |
| 871 | * This is called when the buf log item is no longer needed. It should | 887 | * This is called when the buf log item is no longer needed. It should |
| 872 | * free the buf log item associated with the given buffer and clear | 888 | * free the buf log item associated with the given buffer and clear |
| @@ -887,18 +903,8 @@ xfs_buf_item_relse( | |||
| 887 | (XFS_BUF_IODONE_FUNC(bp) != NULL)) { | 903 | (XFS_BUF_IODONE_FUNC(bp) != NULL)) { |
| 888 | XFS_BUF_CLR_IODONE_FUNC(bp); | 904 | XFS_BUF_CLR_IODONE_FUNC(bp); |
| 889 | } | 905 | } |
| 890 | 906 | xfs_buf_rele(bp); | |
| 891 | #ifdef XFS_TRANS_DEBUG | 907 | xfs_buf_item_free(bip); |
| 892 | kmem_free(bip->bli_orig); | ||
| 893 | bip->bli_orig = NULL; | ||
| 894 | kmem_free(bip->bli_logged); | ||
| 895 | bip->bli_logged = NULL; | ||
| 896 | #endif /* XFS_TRANS_DEBUG */ | ||
| 897 | |||
| 898 | #ifdef XFS_BLI_TRACE | ||
| 899 | ktrace_free(bip->bli_trace); | ||
| 900 | #endif | ||
| 901 | kmem_zone_free(xfs_buf_item_zone, bip); | ||
| 902 | } | 908 | } |
| 903 | 909 | ||
| 904 | 910 | ||
| @@ -1120,6 +1126,7 @@ xfs_buf_iodone( | |||
| 1120 | 1126 | ||
| 1121 | ASSERT(bip->bli_buf == bp); | 1127 | ASSERT(bip->bli_buf == bp); |
| 1122 | 1128 | ||
| 1129 | xfs_buf_rele(bp); | ||
| 1123 | mp = bip->bli_item.li_mountp; | 1130 | mp = bip->bli_item.li_mountp; |
| 1124 | 1131 | ||
| 1125 | /* | 1132 | /* |
| @@ -1136,18 +1143,7 @@ xfs_buf_iodone( | |||
| 1136 | * xfs_trans_delete_ail() drops the AIL lock. | 1143 | * xfs_trans_delete_ail() drops the AIL lock. |
| 1137 | */ | 1144 | */ |
| 1138 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip); | 1145 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip); |
| 1139 | 1146 | xfs_buf_item_free(bip); | |
| 1140 | #ifdef XFS_TRANS_DEBUG | ||
| 1141 | kmem_free(bip->bli_orig); | ||
| 1142 | bip->bli_orig = NULL; | ||
| 1143 | kmem_free(bip->bli_logged); | ||
| 1144 | bip->bli_logged = NULL; | ||
| 1145 | #endif /* XFS_TRANS_DEBUG */ | ||
| 1146 | |||
| 1147 | #ifdef XFS_BLI_TRACE | ||
| 1148 | ktrace_free(bip->bli_trace); | ||
| 1149 | #endif | ||
| 1150 | kmem_zone_free(xfs_buf_item_zone, bip); | ||
| 1151 | } | 1147 | } |
| 1152 | 1148 | ||
| 1153 | #if defined(XFS_BLI_TRACE) | 1149 | #if defined(XFS_BLI_TRACE) |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 760f4c5b5160..75b0cd4da0ea 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
| @@ -149,7 +149,14 @@ xfs_swap_extents( | |||
| 149 | 149 | ||
| 150 | sbp = &sxp->sx_stat; | 150 | sbp = &sxp->sx_stat; |
| 151 | 151 | ||
| 152 | xfs_lock_two_inodes(ip, tip, lock_flags); | 152 | /* |
| 153 | * we have to do two separate lock calls here to keep lockdep | ||
| 154 | * happy. If we try to get all the locks in one call, lock will | ||
| 155 | * report false positives when we drop the ILOCK and regain them | ||
| 156 | * below. | ||
| 157 | */ | ||
| 158 | xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL); | ||
| 159 | xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL); | ||
| 153 | locked = 1; | 160 | locked = 1; |
| 154 | 161 | ||
| 155 | /* Verify that both files have the same format */ | 162 | /* Verify that both files have the same format */ |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index ccba14eb9dbe..503ea89e8b9a 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
| @@ -124,16 +124,27 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, | |||
| 124 | STATIC int xlog_iclogs_empty(xlog_t *log); | 124 | STATIC int xlog_iclogs_empty(xlog_t *log); |
| 125 | 125 | ||
| 126 | #if defined(XFS_LOG_TRACE) | 126 | #if defined(XFS_LOG_TRACE) |
| 127 | |||
| 128 | #define XLOG_TRACE_LOGGRANT_SIZE 2048 | ||
| 129 | #define XLOG_TRACE_ICLOG_SIZE 256 | ||
| 130 | |||
| 131 | void | ||
| 132 | xlog_trace_loggrant_alloc(xlog_t *log) | ||
| 133 | { | ||
| 134 | log->l_grant_trace = ktrace_alloc(XLOG_TRACE_LOGGRANT_SIZE, KM_NOFS); | ||
| 135 | } | ||
| 136 | |||
| 137 | void | ||
| 138 | xlog_trace_loggrant_dealloc(xlog_t *log) | ||
| 139 | { | ||
| 140 | ktrace_free(log->l_grant_trace); | ||
| 141 | } | ||
| 142 | |||
| 127 | void | 143 | void |
| 128 | xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string) | 144 | xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string) |
| 129 | { | 145 | { |
| 130 | unsigned long cnts; | 146 | unsigned long cnts; |
| 131 | 147 | ||
| 132 | if (!log->l_grant_trace) { | ||
| 133 | log->l_grant_trace = ktrace_alloc(2048, KM_NOSLEEP); | ||
| 134 | if (!log->l_grant_trace) | ||
| 135 | return; | ||
| 136 | } | ||
| 137 | /* ticket counts are 1 byte each */ | 148 | /* ticket counts are 1 byte each */ |
| 138 | cnts = ((unsigned long)tic->t_ocnt) | ((unsigned long)tic->t_cnt) << 8; | 149 | cnts = ((unsigned long)tic->t_ocnt) | ((unsigned long)tic->t_cnt) << 8; |
| 139 | 150 | ||
| @@ -157,10 +168,20 @@ xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string) | |||
| 157 | } | 168 | } |
| 158 | 169 | ||
| 159 | void | 170 | void |
| 171 | xlog_trace_iclog_alloc(xlog_in_core_t *iclog) | ||
| 172 | { | ||
| 173 | iclog->ic_trace = ktrace_alloc(XLOG_TRACE_ICLOG_SIZE, KM_NOFS); | ||
| 174 | } | ||
| 175 | |||
| 176 | void | ||
| 177 | xlog_trace_iclog_dealloc(xlog_in_core_t *iclog) | ||
| 178 | { | ||
| 179 | ktrace_free(iclog->ic_trace); | ||
| 180 | } | ||
| 181 | |||
| 182 | void | ||
| 160 | xlog_trace_iclog(xlog_in_core_t *iclog, uint state) | 183 | xlog_trace_iclog(xlog_in_core_t *iclog, uint state) |
| 161 | { | 184 | { |
| 162 | if (!iclog->ic_trace) | ||
| 163 | iclog->ic_trace = ktrace_alloc(256, KM_NOFS); | ||
| 164 | ktrace_enter(iclog->ic_trace, | 185 | ktrace_enter(iclog->ic_trace, |
| 165 | (void *)((unsigned long)state), | 186 | (void *)((unsigned long)state), |
| 166 | (void *)((unsigned long)current_pid()), | 187 | (void *)((unsigned long)current_pid()), |
| @@ -170,8 +191,15 @@ xlog_trace_iclog(xlog_in_core_t *iclog, uint state) | |||
| 170 | (void *)NULL, (void *)NULL); | 191 | (void *)NULL, (void *)NULL); |
| 171 | } | 192 | } |
| 172 | #else | 193 | #else |
| 194 | |||
| 195 | #define xlog_trace_loggrant_alloc(log) | ||
| 196 | #define xlog_trace_loggrant_dealloc(log) | ||
| 173 | #define xlog_trace_loggrant(log,tic,string) | 197 | #define xlog_trace_loggrant(log,tic,string) |
| 198 | |||
| 199 | #define xlog_trace_iclog_alloc(iclog) | ||
| 200 | #define xlog_trace_iclog_dealloc(iclog) | ||
| 174 | #define xlog_trace_iclog(iclog,state) | 201 | #define xlog_trace_iclog(iclog,state) |
| 202 | |||
| 175 | #endif /* XFS_LOG_TRACE */ | 203 | #endif /* XFS_LOG_TRACE */ |
| 176 | 204 | ||
| 177 | 205 | ||
| @@ -1009,7 +1037,7 @@ xlog_iodone(xfs_buf_t *bp) | |||
| 1009 | * layer, it means the underlyin device no longer supports | 1037 | * layer, it means the underlyin device no longer supports |
| 1010 | * barrier I/O. Warn loudly and turn off barriers. | 1038 | * barrier I/O. Warn loudly and turn off barriers. |
| 1011 | */ | 1039 | */ |
| 1012 | if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ORDERED(bp)) { | 1040 | if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ISORDERED(bp)) { |
| 1013 | l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER; | 1041 | l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER; |
| 1014 | xfs_fs_cmn_err(CE_WARN, l->l_mp, | 1042 | xfs_fs_cmn_err(CE_WARN, l->l_mp, |
| 1015 | "xlog_iodone: Barriers are no longer supported" | 1043 | "xlog_iodone: Barriers are no longer supported" |
| @@ -1231,6 +1259,7 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
| 1231 | spin_lock_init(&log->l_grant_lock); | 1259 | spin_lock_init(&log->l_grant_lock); |
| 1232 | sv_init(&log->l_flush_wait, 0, "flush_wait"); | 1260 | sv_init(&log->l_flush_wait, 0, "flush_wait"); |
| 1233 | 1261 | ||
| 1262 | xlog_trace_loggrant_alloc(log); | ||
| 1234 | /* log record size must be multiple of BBSIZE; see xlog_rec_header_t */ | 1263 | /* log record size must be multiple of BBSIZE; see xlog_rec_header_t */ |
| 1235 | ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0); | 1264 | ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0); |
| 1236 | 1265 | ||
| @@ -1285,6 +1314,8 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
| 1285 | sv_init(&iclog->ic_force_wait, SV_DEFAULT, "iclog-force"); | 1314 | sv_init(&iclog->ic_force_wait, SV_DEFAULT, "iclog-force"); |
| 1286 | sv_init(&iclog->ic_write_wait, SV_DEFAULT, "iclog-write"); | 1315 | sv_init(&iclog->ic_write_wait, SV_DEFAULT, "iclog-write"); |
| 1287 | 1316 | ||
| 1317 | xlog_trace_iclog_alloc(iclog); | ||
| 1318 | |||
| 1288 | iclogp = &iclog->ic_next; | 1319 | iclogp = &iclog->ic_next; |
| 1289 | } | 1320 | } |
| 1290 | *iclogp = log->l_iclog; /* complete ring */ | 1321 | *iclogp = log->l_iclog; /* complete ring */ |
| @@ -1565,11 +1596,7 @@ xlog_dealloc_log(xlog_t *log) | |||
| 1565 | sv_destroy(&iclog->ic_force_wait); | 1596 | sv_destroy(&iclog->ic_force_wait); |
| 1566 | sv_destroy(&iclog->ic_write_wait); | 1597 | sv_destroy(&iclog->ic_write_wait); |
| 1567 | xfs_buf_free(iclog->ic_bp); | 1598 | xfs_buf_free(iclog->ic_bp); |
| 1568 | #ifdef XFS_LOG_TRACE | 1599 | xlog_trace_iclog_dealloc(iclog); |
| 1569 | if (iclog->ic_trace != NULL) { | ||
| 1570 | ktrace_free(iclog->ic_trace); | ||
| 1571 | } | ||
| 1572 | #endif | ||
| 1573 | next_iclog = iclog->ic_next; | 1600 | next_iclog = iclog->ic_next; |
| 1574 | kmem_free(iclog); | 1601 | kmem_free(iclog); |
| 1575 | iclog = next_iclog; | 1602 | iclog = next_iclog; |
| @@ -1578,14 +1605,7 @@ xlog_dealloc_log(xlog_t *log) | |||
| 1578 | spinlock_destroy(&log->l_grant_lock); | 1605 | spinlock_destroy(&log->l_grant_lock); |
| 1579 | 1606 | ||
| 1580 | xfs_buf_free(log->l_xbuf); | 1607 | xfs_buf_free(log->l_xbuf); |
| 1581 | #ifdef XFS_LOG_TRACE | 1608 | xlog_trace_loggrant_dealloc(log); |
| 1582 | if (log->l_trace != NULL) { | ||
| 1583 | ktrace_free(log->l_trace); | ||
| 1584 | } | ||
| 1585 | if (log->l_grant_trace != NULL) { | ||
| 1586 | ktrace_free(log->l_grant_trace); | ||
| 1587 | } | ||
| 1588 | #endif | ||
| 1589 | log->l_mp->m_log = NULL; | 1609 | log->l_mp->m_log = NULL; |
| 1590 | kmem_free(log); | 1610 | kmem_free(log); |
| 1591 | } /* xlog_dealloc_log */ | 1611 | } /* xlog_dealloc_log */ |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index c8a5b22ee3e3..e7d8f84443fa 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
| @@ -448,7 +448,6 @@ typedef struct log { | |||
| 448 | int l_grant_write_bytes; | 448 | int l_grant_write_bytes; |
| 449 | 449 | ||
| 450 | #ifdef XFS_LOG_TRACE | 450 | #ifdef XFS_LOG_TRACE |
| 451 | struct ktrace *l_trace; | ||
| 452 | struct ktrace *l_grant_trace; | 451 | struct ktrace *l_grant_trace; |
| 453 | #endif | 452 | #endif |
| 454 | 453 | ||
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); |
