aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@sgi.com>2007-05-07 23:49:46 -0400
committerTim Shimmin <tes@sgi.com>2007-05-07 23:49:46 -0400
commitba87ea699ebd9dd577bf055ebc4a98200e337542 (patch)
tree713b7d32937372fd7c5b8647f14d0e7262fc7075
parent2a32963130aec5e157b58ff7dfa3dfa1afdf7ca1 (diff)
[XFS] Fix to prevent the notorious 'NULL files' problem after a crash.
The problem that has been addressed is that of synchronising updates of the file size with writes that extend a file. Without the fix the update of a file's size, as a result of a write beyond eof, is independent of when the cached data is flushed to disk. Often the file size update would be written to the filesystem log before the data is flushed to disk. When a system crashes between these two events and the filesystem log is replayed on mount the file's size will be set but since the contents never made it to disk the file is full of holes. If some of the cached data was flushed to disk then it may just be a section of the file at the end that has holes. There are existing fixes to help alleviate this problem, particularly in the case where a file has been truncated, that force cached data to be flushed to disk when the file is closed. If the system crashes while the file(s) are still open then this flushing will never occur. The fix that we have implemented is to introduce a second file size, called the in-memory file size, that represents the current file size as viewed by the user. The existing file size, called the on-disk file size, is the one that get's written to the filesystem log and we only update it when it is safe to do so. When we write to a file beyond eof we only update the in- memory file size in the write operation. Later when the I/O operation, that flushes the cached data to disk completes, an I/O completion routine will update the on-disk file size. The on-disk file size will be updated to the maximum offset of the I/O or to the value of the in-memory file size if the I/O includes eof. SGI-PV: 958522 SGI-Modid: xfs-linux-melb:xfs-kern:28322a Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Tim Shimmin <tes@sgi.com>
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c89
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c91
-rw-r--r--fs/xfs/xfs_bmap.c14
-rw-r--r--fs/xfs/xfs_inode.c48
-rw-r--r--fs/xfs/xfs_inode.h3
-rw-r--r--fs/xfs/xfs_iocore.c2
-rw-r--r--fs/xfs/xfs_iomap.c8
-rw-r--r--fs/xfs/xfs_iomap.h1
-rw-r--r--fs/xfs/xfs_vnodeops.c40
9 files changed, 208 insertions, 88 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 143ffc851c9d..4475588e973a 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -141,9 +141,46 @@ xfs_destroy_ioend(
141} 141}
142 142
143/* 143/*
144 * Update on-disk file size now that data has been written to disk.
145 * The current in-memory file size is i_size. If a write is beyond
146 * eof io_new_size will be the intended file size until i_size is
147 * updated. If this write does not extend all the way to the valid
148 * file size then restrict this update to the end of the write.
149 */
150STATIC void
151xfs_setfilesize(
152 xfs_ioend_t *ioend)
153{
154 xfs_inode_t *ip;
155 xfs_fsize_t isize;
156 xfs_fsize_t bsize;
157
158 ip = xfs_vtoi(ioend->io_vnode);
159
160 ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
161 ASSERT(ioend->io_type != IOMAP_READ);
162
163 if (unlikely(ioend->io_error))
164 return;
165
166 bsize = ioend->io_offset + ioend->io_size;
167
168 xfs_ilock(ip, XFS_ILOCK_EXCL);
169
170 isize = MAX(ip->i_size, ip->i_iocore.io_new_size);
171 isize = MIN(isize, bsize);
172
173 if (ip->i_d.di_size < isize) {
174 ip->i_d.di_size = isize;
175 ip->i_update_core = 1;
176 ip->i_update_size = 1;
177 }
178
179 xfs_iunlock(ip, XFS_ILOCK_EXCL);
180}
181
182/*
144 * Buffered IO write completion for delayed allocate extents. 183 * Buffered IO write completion for delayed allocate extents.
145 * TODO: Update ondisk isize now that we know the file data
146 * has been flushed (i.e. the notorious "NULL file" problem).
147 */ 184 */
148STATIC void 185STATIC void
149xfs_end_bio_delalloc( 186xfs_end_bio_delalloc(
@@ -152,6 +189,7 @@ xfs_end_bio_delalloc(
152 xfs_ioend_t *ioend = 189 xfs_ioend_t *ioend =
153 container_of(work, xfs_ioend_t, io_work); 190 container_of(work, xfs_ioend_t, io_work);
154 191
192 xfs_setfilesize(ioend);
155 xfs_destroy_ioend(ioend); 193 xfs_destroy_ioend(ioend);
156} 194}
157 195
@@ -165,6 +203,7 @@ xfs_end_bio_written(
165 xfs_ioend_t *ioend = 203 xfs_ioend_t *ioend =
166 container_of(work, xfs_ioend_t, io_work); 204 container_of(work, xfs_ioend_t, io_work);
167 205
206 xfs_setfilesize(ioend);
168 xfs_destroy_ioend(ioend); 207 xfs_destroy_ioend(ioend);
169} 208}
170 209
@@ -184,8 +223,23 @@ xfs_end_bio_unwritten(
184 xfs_off_t offset = ioend->io_offset; 223 xfs_off_t offset = ioend->io_offset;
185 size_t size = ioend->io_size; 224 size_t size = ioend->io_size;
186 225
187 if (likely(!ioend->io_error)) 226 if (likely(!ioend->io_error)) {
188 bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL); 227 bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL);
228 xfs_setfilesize(ioend);
229 }
230 xfs_destroy_ioend(ioend);
231}
232
233/*
234 * IO read completion for regular, written extents.
235 */
236STATIC void
237xfs_end_bio_read(
238 struct work_struct *work)
239{
240 xfs_ioend_t *ioend =
241 container_of(work, xfs_ioend_t, io_work);
242
189 xfs_destroy_ioend(ioend); 243 xfs_destroy_ioend(ioend);
190} 244}
191 245
@@ -224,6 +278,8 @@ xfs_alloc_ioend(
224 INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten); 278 INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten);
225 else if (type == IOMAP_DELAY) 279 else if (type == IOMAP_DELAY)
226 INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc); 280 INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc);
281 else if (type == IOMAP_READ)
282 INIT_WORK(&ioend->io_work, xfs_end_bio_read);
227 else 283 else
228 INIT_WORK(&ioend->io_work, xfs_end_bio_written); 284 INIT_WORK(&ioend->io_work, xfs_end_bio_written);
229 285
@@ -913,7 +969,7 @@ xfs_page_state_convert(
913 bh = head = page_buffers(page); 969 bh = head = page_buffers(page);
914 offset = page_offset(page); 970 offset = page_offset(page);
915 flags = -1; 971 flags = -1;
916 type = 0; 972 type = IOMAP_READ;
917 973
918 /* TODO: cleanup count and page_dirty */ 974 /* TODO: cleanup count and page_dirty */
919 975
@@ -999,7 +1055,7 @@ xfs_page_state_convert(
999 * That means it must already have extents allocated 1055 * That means it must already have extents allocated
1000 * underneath it. Map the extent by reading it. 1056 * underneath it. Map the extent by reading it.
1001 */ 1057 */
1002 if (!iomap_valid || type != 0) { 1058 if (!iomap_valid || type != IOMAP_READ) {
1003 flags = BMAPI_READ; 1059 flags = BMAPI_READ;
1004 size = xfs_probe_cluster(inode, page, bh, 1060 size = xfs_probe_cluster(inode, page, bh,
1005 head, 1); 1061 head, 1);
@@ -1010,7 +1066,7 @@ xfs_page_state_convert(
1010 iomap_valid = xfs_iomap_valid(&iomap, offset); 1066 iomap_valid = xfs_iomap_valid(&iomap, offset);
1011 } 1067 }
1012 1068
1013 type = 0; 1069 type = IOMAP_READ;
1014 if (!test_and_set_bit(BH_Lock, &bh->b_state)) { 1070 if (!test_and_set_bit(BH_Lock, &bh->b_state)) {
1015 ASSERT(buffer_mapped(bh)); 1071 ASSERT(buffer_mapped(bh));
1016 if (iomap_valid) 1072 if (iomap_valid)
@@ -1356,12 +1412,21 @@ xfs_end_io_direct(
1356 * completion handler in the future, in which case all this can 1412 * completion handler in the future, in which case all this can
1357 * go away. 1413 * go away.
1358 */ 1414 */
1359 if (private && size > 0) { 1415 ioend->io_offset = offset;
1360 ioend->io_offset = offset; 1416 ioend->io_size = size;
1361 ioend->io_size = size; 1417 if (ioend->io_type == IOMAP_READ) {
1418 xfs_finish_ioend(ioend);
1419 } else if (private && size > 0) {
1362 xfs_finish_ioend(ioend); 1420 xfs_finish_ioend(ioend);
1363 } else { 1421 } else {
1364 xfs_destroy_ioend(ioend); 1422 /*
1423 * A direct I/O write ioend starts it's life in unwritten
1424 * state in case they map an unwritten extent. This write
1425 * didn't map an unwritten extent so switch it's completion
1426 * handler.
1427 */
1428 INIT_WORK(&ioend->io_work, xfs_end_bio_written);
1429 xfs_finish_ioend(ioend);
1365 } 1430 }
1366 1431
1367 /* 1432 /*
@@ -1392,15 +1457,15 @@ xfs_vm_direct_IO(
1392 if (error) 1457 if (error)
1393 return -error; 1458 return -error;
1394 1459
1395 iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);
1396
1397 if (rw == WRITE) { 1460 if (rw == WRITE) {
1461 iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);
1398 ret = blockdev_direct_IO_own_locking(rw, iocb, inode, 1462 ret = blockdev_direct_IO_own_locking(rw, iocb, inode,
1399 iomap.iomap_target->bt_bdev, 1463 iomap.iomap_target->bt_bdev,
1400 iov, offset, nr_segs, 1464 iov, offset, nr_segs,
1401 xfs_get_blocks_direct, 1465 xfs_get_blocks_direct,
1402 xfs_end_io_direct); 1466 xfs_end_io_direct);
1403 } else { 1467 } else {
1468 iocb->private = xfs_alloc_ioend(inode, IOMAP_READ);
1404 ret = blockdev_direct_IO_no_locking(rw, iocb, inode, 1469 ret = blockdev_direct_IO_no_locking(rw, iocb, inode,
1405 iomap.iomap_target->bt_bdev, 1470 iomap.iomap_target->bt_bdev,
1406 iov, offset, nr_segs, 1471 iov, offset, nr_segs,
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 80fe31233471..82ab792c7fc9 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -224,7 +224,7 @@ xfs_read(
224 mp->m_rtdev_targp : mp->m_ddev_targp; 224 mp->m_rtdev_targp : mp->m_ddev_targp;
225 if ((*offset & target->bt_smask) || 225 if ((*offset & target->bt_smask) ||
226 (size & target->bt_smask)) { 226 (size & target->bt_smask)) {
227 if (*offset == ip->i_d.di_size) { 227 if (*offset == ip->i_size) {
228 return (0); 228 return (0);
229 } 229 }
230 return -XFS_ERROR(EINVAL); 230 return -XFS_ERROR(EINVAL);
@@ -387,9 +387,10 @@ xfs_splice_write(
387{ 387{
388 xfs_inode_t *ip = XFS_BHVTOI(bdp); 388 xfs_inode_t *ip = XFS_BHVTOI(bdp);
389 xfs_mount_t *mp = ip->i_mount; 389 xfs_mount_t *mp = ip->i_mount;
390 xfs_iocore_t *io = &ip->i_iocore;
390 ssize_t ret; 391 ssize_t ret;
391 struct inode *inode = outfilp->f_mapping->host; 392 struct inode *inode = outfilp->f_mapping->host;
392 xfs_fsize_t isize; 393 xfs_fsize_t isize, new_size;
393 394
394 XFS_STATS_INC(xs_write_calls); 395 XFS_STATS_INC(xs_write_calls);
395 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) 396 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
@@ -410,6 +411,14 @@ xfs_splice_write(
410 return -error; 411 return -error;
411 } 412 }
412 } 413 }
414
415 new_size = *ppos + count;
416
417 xfs_ilock(ip, XFS_ILOCK_EXCL);
418 if (new_size > ip->i_size)
419 io->io_new_size = new_size;
420 xfs_iunlock(ip, XFS_ILOCK_EXCL);
421
413 xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore, 422 xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore,
414 pipe, count, *ppos, ioflags); 423 pipe, count, *ppos, ioflags);
415 ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); 424 ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags);
@@ -420,14 +429,18 @@ xfs_splice_write(
420 if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize)) 429 if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize))
421 *ppos = isize; 430 *ppos = isize;
422 431
423 if (*ppos > ip->i_d.di_size) { 432 if (*ppos > ip->i_size) {
424 xfs_ilock(ip, XFS_ILOCK_EXCL); 433 xfs_ilock(ip, XFS_ILOCK_EXCL);
425 if (*ppos > ip->i_d.di_size) { 434 if (*ppos > ip->i_size)
426 ip->i_d.di_size = *ppos; 435 ip->i_size = *ppos;
427 i_size_write(inode, *ppos); 436 xfs_iunlock(ip, XFS_ILOCK_EXCL);
428 ip->i_update_core = 1; 437 }
429 ip->i_update_size = 1; 438
430 } 439 if (io->io_new_size) {
440 xfs_ilock(ip, XFS_ILOCK_EXCL);
441 io->io_new_size = 0;
442 if (ip->i_d.di_size > ip->i_size)
443 ip->i_d.di_size = ip->i_size;
431 xfs_iunlock(ip, XFS_ILOCK_EXCL); 444 xfs_iunlock(ip, XFS_ILOCK_EXCL);
432 } 445 }
433 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 446 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
@@ -711,8 +724,6 @@ start:
711 goto out_unlock_mutex; 724 goto out_unlock_mutex;
712 } 725 }
713 726
714 isize = i_size_read(inode);
715
716 if (ioflags & IO_ISDIRECT) { 727 if (ioflags & IO_ISDIRECT) {
717 xfs_buftarg_t *target = 728 xfs_buftarg_t *target =
718 (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? 729 (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
@@ -723,7 +734,7 @@ start:
723 return XFS_ERROR(-EINVAL); 734 return XFS_ERROR(-EINVAL);
724 } 735 }
725 736
726 if (!need_i_mutex && (VN_CACHED(vp) || pos > isize)) { 737 if (!need_i_mutex && (VN_CACHED(vp) || pos > xip->i_size)) {
727 xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); 738 xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
728 iolock = XFS_IOLOCK_EXCL; 739 iolock = XFS_IOLOCK_EXCL;
729 locktype = VRWLOCK_WRITE; 740 locktype = VRWLOCK_WRITE;
@@ -735,7 +746,7 @@ start:
735 } 746 }
736 747
737 new_size = pos + count; 748 new_size = pos + count;
738 if (new_size > isize) 749 if (new_size > xip->i_size)
739 io->io_new_size = new_size; 750 io->io_new_size = new_size;
740 751
741 if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) && 752 if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) &&
@@ -751,8 +762,7 @@ start:
751 pos, count, 762 pos, count,
752 dmflags, &locktype); 763 dmflags, &locktype);
753 if (error) { 764 if (error) {
754 xfs_iunlock(xip, iolock); 765 goto out_unlock_internal;
755 goto out_unlock_mutex;
756 } 766 }
757 xfs_ilock(xip, XFS_ILOCK_EXCL); 767 xfs_ilock(xip, XFS_ILOCK_EXCL);
758 eventsent = 1; 768 eventsent = 1;
@@ -764,9 +774,8 @@ start:
764 * event prevents another call to XFS_SEND_DATA, which is 774 * event prevents another call to XFS_SEND_DATA, which is
765 * what allows the size to change in the first place. 775 * what allows the size to change in the first place.
766 */ 776 */
767 if ((file->f_flags & O_APPEND) && savedsize != isize) { 777 if ((file->f_flags & O_APPEND) && savedsize != xip->i_size)
768 goto start; 778 goto start;
769 }
770 } 779 }
771 780
772 if (likely(!(ioflags & IO_INVIS))) { 781 if (likely(!(ioflags & IO_INVIS))) {
@@ -784,11 +793,11 @@ start:
784 * to zero it out up to the new size. 793 * to zero it out up to the new size.
785 */ 794 */
786 795
787 if (pos > isize) { 796 if (pos > xip->i_size) {
788 error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, isize); 797 error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, xip->i_size);
789 if (error) { 798 if (error) {
790 xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); 799 xfs_iunlock(xip, XFS_ILOCK_EXCL);
791 goto out_unlock_mutex; 800 goto out_unlock_internal;
792 } 801 }
793 } 802 }
794 xfs_iunlock(xip, XFS_ILOCK_EXCL); 803 xfs_iunlock(xip, XFS_ILOCK_EXCL);
@@ -808,8 +817,7 @@ start:
808 if (likely(!error)) 817 if (likely(!error))
809 error = -remove_suid(file->f_path.dentry); 818 error = -remove_suid(file->f_path.dentry);
810 if (unlikely(error)) { 819 if (unlikely(error)) {
811 xfs_iunlock(xip, iolock); 820 goto out_unlock_internal;
812 goto out_unlock_mutex;
813 } 821 }
814 } 822 }
815 823
@@ -879,12 +887,12 @@ retry:
879 error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp, 887 error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
880 DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL, 888 DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
881 0, 0, 0); /* Delay flag intentionally unused */ 889 0, 0, 0); /* Delay flag intentionally unused */
882 if (error)
883 goto out_nounlocks;
884 if (need_i_mutex) 890 if (need_i_mutex)
885 mutex_lock(&inode->i_mutex); 891 mutex_lock(&inode->i_mutex);
886 xfs_rwlock(bdp, locktype); 892 xfs_rwlock(bdp, locktype);
887 pos = xip->i_d.di_size; 893 if (error)
894 goto out_unlock_internal;
895 pos = xip->i_size;
888 ret = 0; 896 ret = 0;
889 goto retry; 897 goto retry;
890 } 898 }
@@ -893,14 +901,10 @@ retry:
893 if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize)) 901 if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize))
894 *offset = isize; 902 *offset = isize;
895 903
896 if (*offset > xip->i_d.di_size) { 904 if (*offset > xip->i_size) {
897 xfs_ilock(xip, XFS_ILOCK_EXCL); 905 xfs_ilock(xip, XFS_ILOCK_EXCL);
898 if (*offset > xip->i_d.di_size) { 906 if (*offset > xip->i_size)
899 xip->i_d.di_size = *offset; 907 xip->i_size = *offset;
900 i_size_write(inode, *offset);
901 xip->i_update_core = 1;
902 xip->i_update_size = 1;
903 }
904 xfs_iunlock(xip, XFS_ILOCK_EXCL); 908 xfs_iunlock(xip, XFS_ILOCK_EXCL);
905 } 909 }
906 910
@@ -922,16 +926,31 @@ retry:
922 926
923 error = sync_page_range(inode, mapping, pos, ret); 927 error = sync_page_range(inode, mapping, pos, ret);
924 if (!error) 928 if (!error)
925 error = ret; 929 error = -ret;
926 return error; 930 if (need_i_mutex)
931 mutex_lock(&inode->i_mutex);
932 xfs_rwlock(bdp, locktype);
927 } 933 }
928 934
929 out_unlock_internal: 935 out_unlock_internal:
936 if (io->io_new_size) {
937 xfs_ilock(xip, XFS_ILOCK_EXCL);
938 io->io_new_size = 0;
939 /*
940 * If this was a direct or synchronous I/O that failed (such
941 * as ENOSPC) then part of the I/O may have been written to
942 * disk before the error occured. In this case the on-disk
943 * file size may have been adjusted beyond the in-memory file
944 * size and now needs to be truncated back.
945 */
946 if (xip->i_d.di_size > xip->i_size)
947 xip->i_d.di_size = xip->i_size;
948 xfs_iunlock(xip, XFS_ILOCK_EXCL);
949 }
930 xfs_rwunlock(bdp, locktype); 950 xfs_rwunlock(bdp, locktype);
931 out_unlock_mutex: 951 out_unlock_mutex:
932 if (need_i_mutex) 952 if (need_i_mutex)
933 mutex_unlock(&inode->i_mutex); 953 mutex_unlock(&inode->i_mutex);
934 out_nounlocks:
935 return -error; 954 return -error;
936} 955}
937 956
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 50f2213589f8..b1ea26e40aaf 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -4444,8 +4444,11 @@ xfs_bmap_one_block(
4444 xfs_bmbt_irec_t s; /* internal version of extent */ 4444 xfs_bmbt_irec_t s; /* internal version of extent */
4445 4445
4446#ifndef DEBUG 4446#ifndef DEBUG
4447 if (whichfork == XFS_DATA_FORK) 4447 if (whichfork == XFS_DATA_FORK) {
4448 return ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize; 4448 return ((ip->i_d.di_mode & S_IFMT) == S_IFREG) ?
4449 (ip->i_size == ip->i_mount->m_sb.sb_blocksize) :
4450 (ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize);
4451 }
4449#endif /* !DEBUG */ 4452#endif /* !DEBUG */
4450 if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1) 4453 if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1)
4451 return 0; 4454 return 0;
@@ -4457,7 +4460,7 @@ xfs_bmap_one_block(
4457 xfs_bmbt_get_all(ep, &s); 4460 xfs_bmbt_get_all(ep, &s);
4458 rval = s.br_startoff == 0 && s.br_blockcount == 1; 4461 rval = s.br_startoff == 0 && s.br_blockcount == 1;
4459 if (rval && whichfork == XFS_DATA_FORK) 4462 if (rval && whichfork == XFS_DATA_FORK)
4460 ASSERT(ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize); 4463 ASSERT(ip->i_size == ip->i_mount->m_sb.sb_blocksize);
4461 return rval; 4464 return rval;
4462} 4465}
4463 4466
@@ -5817,7 +5820,7 @@ xfs_getbmap(
5817 fixlen = XFS_MAXIOFFSET(mp); 5820 fixlen = XFS_MAXIOFFSET(mp);
5818 } else { 5821 } else {
5819 prealloced = 0; 5822 prealloced = 0;
5820 fixlen = ip->i_d.di_size; 5823 fixlen = ip->i_size;
5821 } 5824 }
5822 } else { 5825 } else {
5823 prealloced = 0; 5826 prealloced = 0;
@@ -5841,7 +5844,8 @@ xfs_getbmap(
5841 5844
5842 xfs_ilock(ip, XFS_IOLOCK_SHARED); 5845 xfs_ilock(ip, XFS_IOLOCK_SHARED);
5843 5846
5844 if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) { 5847 if (whichfork == XFS_DATA_FORK &&
5848 (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
5845 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ 5849 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
5846 error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF); 5850 error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
5847 } 5851 }
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 7d1ab3967b8e..3ca5d43b8345 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -442,6 +442,7 @@ xfs_iformat(
442 return XFS_ERROR(EFSCORRUPTED); 442 return XFS_ERROR(EFSCORRUPTED);
443 } 443 }
444 ip->i_d.di_size = 0; 444 ip->i_d.di_size = 0;
445 ip->i_size = 0;
445 ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT); 446 ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT);
446 break; 447 break;
447 448
@@ -980,6 +981,7 @@ xfs_iread(
980 } 981 }
981 982
982 ip->i_delayed_blks = 0; 983 ip->i_delayed_blks = 0;
984 ip->i_size = ip->i_d.di_size;
983 985
984 /* 986 /*
985 * Mark the buffer containing the inode as something to keep 987 * Mark the buffer containing the inode as something to keep
@@ -1170,6 +1172,7 @@ xfs_ialloc(
1170 } 1172 }
1171 1173
1172 ip->i_d.di_size = 0; 1174 ip->i_d.di_size = 0;
1175 ip->i_size = 0;
1173 ip->i_d.di_nextents = 0; 1176 ip->i_d.di_nextents = 0;
1174 ASSERT(ip->i_d.di_nblocks == 0); 1177 ASSERT(ip->i_d.di_nblocks == 0);
1175 xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD); 1178 xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD);
@@ -1340,7 +1343,7 @@ xfs_file_last_byte(
1340 } else { 1343 } else {
1341 last_block = 0; 1344 last_block = 0;
1342 } 1345 }
1343 size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_d.di_size); 1346 size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_size);
1344 last_block = XFS_FILEOFF_MAX(last_block, size_last_block); 1347 last_block = XFS_FILEOFF_MAX(last_block, size_last_block);
1345 1348
1346 last_byte = XFS_FSB_TO_B(mp, last_block); 1349 last_byte = XFS_FSB_TO_B(mp, last_block);
@@ -1434,7 +1437,7 @@ xfs_itruncate_start(
1434 int error = 0; 1437 int error = 0;
1435 1438
1436 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); 1439 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
1437 ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size)); 1440 ASSERT((new_size == 0) || (new_size <= ip->i_size));
1438 ASSERT((flags == XFS_ITRUNC_DEFINITE) || 1441 ASSERT((flags == XFS_ITRUNC_DEFINITE) ||
1439 (flags == XFS_ITRUNC_MAYBE)); 1442 (flags == XFS_ITRUNC_MAYBE));
1440 1443
@@ -1558,7 +1561,7 @@ xfs_itruncate_finish(
1558 1561
1559 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); 1562 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
1560 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0); 1563 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0);
1561 ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size)); 1564 ASSERT((new_size == 0) || (new_size <= ip->i_size));
1562 ASSERT(*tp != NULL); 1565 ASSERT(*tp != NULL);
1563 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); 1566 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
1564 ASSERT(ip->i_transp == *tp); 1567 ASSERT(ip->i_transp == *tp);
@@ -1632,8 +1635,20 @@ xfs_itruncate_finish(
1632 */ 1635 */
1633 if (fork == XFS_DATA_FORK) { 1636 if (fork == XFS_DATA_FORK) {
1634 if (ip->i_d.di_nextents > 0) { 1637 if (ip->i_d.di_nextents > 0) {
1635 ip->i_d.di_size = new_size; 1638 /*
1636 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); 1639 * If we are not changing the file size then do
1640 * not update the on-disk file size - we may be
1641 * called from xfs_inactive_free_eofblocks(). If we
1642 * update the on-disk file size and then the system
1643 * crashes before the contents of the file are
1644 * flushed to disk then the files may be full of
1645 * holes (ie NULL files bug).
1646 */
1647 if (ip->i_size != new_size) {
1648 ip->i_d.di_size = new_size;
1649 ip->i_size = new_size;
1650 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
1651 }
1637 } 1652 }
1638 } else if (sync) { 1653 } else if (sync) {
1639 ASSERT(!(mp->m_flags & XFS_MOUNT_WSYNC)); 1654 ASSERT(!(mp->m_flags & XFS_MOUNT_WSYNC));
@@ -1769,7 +1784,19 @@ xfs_itruncate_finish(
1769 */ 1784 */
1770 if (fork == XFS_DATA_FORK) { 1785 if (fork == XFS_DATA_FORK) {
1771 xfs_isize_check(mp, ip, new_size); 1786 xfs_isize_check(mp, ip, new_size);
1772 ip->i_d.di_size = new_size; 1787 /*
1788 * If we are not changing the file size then do
1789 * not update the on-disk file size - we may be
1790 * called from xfs_inactive_free_eofblocks(). If we
1791 * update the on-disk file size and then the system
1792 * crashes before the contents of the file are
1793 * flushed to disk then the files may be full of
1794 * holes (ie NULL files bug).
1795 */
1796 if (ip->i_size != new_size) {
1797 ip->i_d.di_size = new_size;
1798 ip->i_size = new_size;
1799 }
1773 } 1800 }
1774 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); 1801 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
1775 ASSERT((new_size != 0) || 1802 ASSERT((new_size != 0) ||
@@ -1802,7 +1829,7 @@ xfs_igrow_start(
1802 1829
1803 ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); 1830 ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0);
1804 ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); 1831 ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0);
1805 ASSERT(new_size > ip->i_d.di_size); 1832 ASSERT(new_size > ip->i_size);
1806 1833
1807 /* 1834 /*
1808 * Zero any pages that may have been created by 1835 * Zero any pages that may have been created by
@@ -1810,7 +1837,7 @@ xfs_igrow_start(
1810 * and any blocks between the old and new file sizes. 1837 * and any blocks between the old and new file sizes.
1811 */ 1838 */
1812 error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size, 1839 error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size,
1813 ip->i_d.di_size); 1840 ip->i_size);
1814 return error; 1841 return error;
1815} 1842}
1816 1843
@@ -1834,13 +1861,14 @@ xfs_igrow_finish(
1834 ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); 1861 ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0);
1835 ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); 1862 ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0);
1836 ASSERT(ip->i_transp == tp); 1863 ASSERT(ip->i_transp == tp);
1837 ASSERT(new_size > ip->i_d.di_size); 1864 ASSERT(new_size > ip->i_size);
1838 1865
1839 /* 1866 /*
1840 * Update the file size. Update the inode change timestamp 1867 * Update the file size. Update the inode change timestamp
1841 * if change_flag set. 1868 * if change_flag set.
1842 */ 1869 */
1843 ip->i_d.di_size = new_size; 1870 ip->i_d.di_size = new_size;
1871 ip->i_size = new_size;
1844 if (change_flag) 1872 if (change_flag)
1845 xfs_ichgtime(ip, XFS_ICHGTIME_CHG); 1873 xfs_ichgtime(ip, XFS_ICHGTIME_CHG);
1846 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1874 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
@@ -2323,7 +2351,7 @@ xfs_ifree(
2323 ASSERT(ip->i_d.di_nlink == 0); 2351 ASSERT(ip->i_d.di_nlink == 0);
2324 ASSERT(ip->i_d.di_nextents == 0); 2352 ASSERT(ip->i_d.di_nextents == 0);
2325 ASSERT(ip->i_d.di_anextents == 0); 2353 ASSERT(ip->i_d.di_anextents == 0);
2326 ASSERT((ip->i_d.di_size == 0) || 2354 ASSERT((ip->i_d.di_size == 0 && ip->i_size == 0) ||
2327 ((ip->i_d.di_mode & S_IFMT) != S_IFREG)); 2355 ((ip->i_d.di_mode & S_IFMT) != S_IFREG));
2328 ASSERT(ip->i_d.di_nblocks == 0); 2356 ASSERT(ip->i_d.di_nblocks == 0);
2329 2357
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 699960f3459f..cfe7b58c4533 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -287,6 +287,7 @@ typedef struct xfs_inode {
287 struct xfs_inode *i_cnext; /* cluster hash link forward */ 287 struct xfs_inode *i_cnext; /* cluster hash link forward */
288 struct xfs_inode *i_cprev; /* cluster hash link backward */ 288 struct xfs_inode *i_cprev; /* cluster hash link backward */
289 289
290 xfs_fsize_t i_size; /* in-memory size */
290 /* Trace buffers per inode. */ 291 /* Trace buffers per inode. */
291#ifdef XFS_BMAP_TRACE 292#ifdef XFS_BMAP_TRACE
292 struct ktrace *i_xtrace; /* inode extent list trace */ 293 struct ktrace *i_xtrace; /* inode extent list trace */
@@ -305,6 +306,8 @@ typedef struct xfs_inode {
305#endif 306#endif
306} xfs_inode_t; 307} xfs_inode_t;
307 308
309#define XFS_ISIZE(ip) (((ip)->i_d.di_mode & S_IFMT) == S_IFREG) ? \
310 (ip)->i_size : (ip)->i_d.di_size;
308 311
309/* 312/*
310 * i_flags helper functions 313 * i_flags helper functions
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c
index 06d710c9ce4b..81548ec72ba6 100644
--- a/fs/xfs/xfs_iocore.c
+++ b/fs/xfs/xfs_iocore.c
@@ -52,7 +52,7 @@ STATIC xfs_fsize_t
52xfs_size_fn( 52xfs_size_fn(
53 xfs_inode_t *ip) 53 xfs_inode_t *ip)
54{ 54{
55 return (ip->i_d.di_size); 55 return XFS_ISIZE(ip);
56} 56}
57 57
58STATIC int 58STATIC int
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index cde70e895443..3f2b9f2a7b94 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -458,7 +458,7 @@ xfs_iomap_write_direct(
458 extsz = ip->i_d.di_extsize; 458 extsz = ip->i_d.di_extsize;
459 } 459 }
460 460
461 isize = ip->i_d.di_size; 461 isize = ip->i_size;
462 if (io->io_new_size > isize) 462 if (io->io_new_size > isize)
463 isize = io->io_new_size; 463 isize = io->io_new_size;
464 464
@@ -524,7 +524,7 @@ xfs_iomap_write_direct(
524 xfs_trans_ihold(tp, ip); 524 xfs_trans_ihold(tp, ip);
525 525
526 bmapi_flag = XFS_BMAPI_WRITE; 526 bmapi_flag = XFS_BMAPI_WRITE;
527 if ((flags & BMAPI_DIRECT) && (offset < ip->i_d.di_size || extsz)) 527 if ((flags & BMAPI_DIRECT) && (offset < ip->i_size || extsz))
528 bmapi_flag |= XFS_BMAPI_PREALLOC; 528 bmapi_flag |= XFS_BMAPI_PREALLOC;
529 529
530 /* 530 /*
@@ -676,7 +676,7 @@ xfs_iomap_write_delay(
676 offset_fsb = XFS_B_TO_FSBT(mp, offset); 676 offset_fsb = XFS_B_TO_FSBT(mp, offset);
677 677
678retry: 678retry:
679 isize = ip->i_d.di_size; 679 isize = ip->i_size;
680 if (io->io_new_size > isize) 680 if (io->io_new_size > isize)
681 isize = io->io_new_size; 681 isize = io->io_new_size;
682 682
@@ -817,7 +817,7 @@ xfs_iomap_write_allocate(
817 * we dropped the ilock in the interim. 817 * we dropped the ilock in the interim.
818 */ 818 */
819 819
820 end_fsb = XFS_B_TO_FSB(mp, ip->i_d.di_size); 820 end_fsb = XFS_B_TO_FSB(mp, ip->i_size);
821 xfs_bmap_last_offset(NULL, ip, &last_block, 821 xfs_bmap_last_offset(NULL, ip, &last_block,
822 XFS_DATA_FORK); 822 XFS_DATA_FORK);
823 last_block = XFS_FILEOFF_MAX(last_block, end_fsb); 823 last_block = XFS_FILEOFF_MAX(last_block, end_fsb);
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index 3ce204a524b0..df441ee936b2 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -22,6 +22,7 @@
22 22
23 23
24typedef enum { /* iomap_flags values */ 24typedef enum { /* iomap_flags values */
25 IOMAP_READ = 0, /* mapping for a read */
25 IOMAP_EOF = 0x01, /* mapping contains EOF */ 26 IOMAP_EOF = 0x01, /* mapping contains EOF */
26 IOMAP_HOLE = 0x02, /* mapping covers a hole */ 27 IOMAP_HOLE = 0x02, /* mapping covers a hole */
27 IOMAP_DELAY = 0x04, /* mapping covers delalloc region */ 28 IOMAP_DELAY = 0x04, /* mapping covers delalloc region */
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 6e49bd362460..e17be3b647be 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -133,7 +133,7 @@ xfs_getattr(
133 if (!(flags & ATTR_LAZY)) 133 if (!(flags & ATTR_LAZY))
134 xfs_ilock(ip, XFS_ILOCK_SHARED); 134 xfs_ilock(ip, XFS_ILOCK_SHARED);
135 135
136 vap->va_size = ip->i_d.di_size; 136 vap->va_size = XFS_ISIZE(ip);
137 if (vap->va_mask == XFS_AT_SIZE) 137 if (vap->va_mask == XFS_AT_SIZE)
138 goto all_done; 138 goto all_done;
139 139
@@ -496,7 +496,7 @@ xfs_setattr(
496 if (mask & XFS_AT_SIZE) { 496 if (mask & XFS_AT_SIZE) {
497 /* Short circuit the truncate case for zero length files */ 497 /* Short circuit the truncate case for zero length files */
498 if ((vap->va_size == 0) && 498 if ((vap->va_size == 0) &&
499 (ip->i_d.di_size == 0) && (ip->i_d.di_nextents == 0)) { 499 (ip->i_size == 0) && (ip->i_d.di_nextents == 0)) {
500 xfs_iunlock(ip, XFS_ILOCK_EXCL); 500 xfs_iunlock(ip, XFS_ILOCK_EXCL);
501 lock_flags &= ~XFS_ILOCK_EXCL; 501 lock_flags &= ~XFS_ILOCK_EXCL;
502 if (mask & XFS_AT_CTIME) 502 if (mask & XFS_AT_CTIME)
@@ -614,7 +614,7 @@ xfs_setattr(
614 */ 614 */
615 if (mask & XFS_AT_SIZE) { 615 if (mask & XFS_AT_SIZE) {
616 code = 0; 616 code = 0;
617 if ((vap->va_size > ip->i_d.di_size) && 617 if ((vap->va_size > ip->i_size) &&
618 (flags & ATTR_NOSIZETOK) == 0) { 618 (flags & ATTR_NOSIZETOK) == 0) {
619 code = xfs_igrow_start(ip, vap->va_size, credp); 619 code = xfs_igrow_start(ip, vap->va_size, credp);
620 } 620 }
@@ -654,10 +654,10 @@ xfs_setattr(
654 * Truncate file. Must have write permission and not be a directory. 654 * Truncate file. Must have write permission and not be a directory.
655 */ 655 */
656 if (mask & XFS_AT_SIZE) { 656 if (mask & XFS_AT_SIZE) {
657 if (vap->va_size > ip->i_d.di_size) { 657 if (vap->va_size > ip->i_size) {
658 xfs_igrow_finish(tp, ip, vap->va_size, 658 xfs_igrow_finish(tp, ip, vap->va_size,
659 !(flags & ATTR_DMI)); 659 !(flags & ATTR_DMI));
660 } else if ((vap->va_size <= ip->i_d.di_size) || 660 } else if ((vap->va_size <= ip->i_size) ||
661 ((vap->va_size == 0) && ip->i_d.di_nextents)) { 661 ((vap->va_size == 0) && ip->i_d.di_nextents)) {
662 /* 662 /*
663 * signal a sync transaction unless 663 * signal a sync transaction unless
@@ -1221,7 +1221,7 @@ xfs_inactive_free_eofblocks(
1221 * Figure out if there are any blocks beyond the end 1221 * Figure out if there are any blocks beyond the end
1222 * of the file. If not, then there is nothing to do. 1222 * of the file. If not, then there is nothing to do.
1223 */ 1223 */
1224 end_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)ip->i_d.di_size)); 1224 end_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)ip->i_size));
1225 last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp)); 1225 last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
1226 map_len = last_fsb - end_fsb; 1226 map_len = last_fsb - end_fsb;
1227 if (map_len <= 0) 1227 if (map_len <= 0)
@@ -1258,7 +1258,7 @@ xfs_inactive_free_eofblocks(
1258 */ 1258 */
1259 xfs_ilock(ip, XFS_IOLOCK_EXCL); 1259 xfs_ilock(ip, XFS_IOLOCK_EXCL);
1260 error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 1260 error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
1261 ip->i_d.di_size); 1261 ip->i_size);
1262 if (error) { 1262 if (error) {
1263 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 1263 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1264 return error; 1264 return error;
@@ -1282,7 +1282,7 @@ xfs_inactive_free_eofblocks(
1282 xfs_trans_ihold(tp, ip); 1282 xfs_trans_ihold(tp, ip);
1283 1283
1284 error = xfs_itruncate_finish(&tp, ip, 1284 error = xfs_itruncate_finish(&tp, ip,
1285 ip->i_d.di_size, 1285 ip->i_size,
1286 XFS_DATA_FORK, 1286 XFS_DATA_FORK,
1287 0); 1287 0);
1288 /* 1288 /*
@@ -1568,7 +1568,7 @@ xfs_release(
1568 1568
1569 if (ip->i_d.di_nlink != 0) { 1569 if (ip->i_d.di_nlink != 0) {
1570 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 1570 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
1571 ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 || 1571 ((ip->i_size > 0) || (VN_CACHED(vp) > 0 ||
1572 ip->i_delayed_blks > 0)) && 1572 ip->i_delayed_blks > 0)) &&
1573 (ip->i_df.if_flags & XFS_IFEXTENTS)) && 1573 (ip->i_df.if_flags & XFS_IFEXTENTS)) &&
1574 (!(ip->i_d.di_flags & 1574 (!(ip->i_d.di_flags &
@@ -1629,8 +1629,8 @@ xfs_inactive(
1629 * only one with a reference to the inode. 1629 * only one with a reference to the inode.
1630 */ 1630 */
1631 truncate = ((ip->i_d.di_nlink == 0) && 1631 truncate = ((ip->i_d.di_nlink == 0) &&
1632 ((ip->i_d.di_size != 0) || (ip->i_d.di_nextents > 0) || 1632 ((ip->i_d.di_size != 0) || (ip->i_size != 0) ||
1633 (ip->i_delayed_blks > 0)) && 1633 (ip->i_d.di_nextents > 0) || (ip->i_delayed_blks > 0)) &&
1634 ((ip->i_d.di_mode & S_IFMT) == S_IFREG)); 1634 ((ip->i_d.di_mode & S_IFMT) == S_IFREG));
1635 1635
1636 mp = ip->i_mount; 1636 mp = ip->i_mount;
@@ -1648,7 +1648,7 @@ xfs_inactive(
1648 1648
1649 if (ip->i_d.di_nlink != 0) { 1649 if (ip->i_d.di_nlink != 0) {
1650 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 1650 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
1651 ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 || 1651 ((ip->i_size > 0) || (VN_CACHED(vp) > 0 ||
1652 ip->i_delayed_blks > 0)) && 1652 ip->i_delayed_blks > 0)) &&
1653 (ip->i_df.if_flags & XFS_IFEXTENTS) && 1653 (ip->i_df.if_flags & XFS_IFEXTENTS) &&
1654 (!(ip->i_d.di_flags & 1654 (!(ip->i_d.di_flags &
@@ -4055,14 +4055,14 @@ xfs_alloc_file_space(
4055 allocatesize_fsb = XFS_B_TO_FSB(mp, count); 4055 allocatesize_fsb = XFS_B_TO_FSB(mp, count);
4056 4056
4057 /* Generate a DMAPI event if needed. */ 4057 /* Generate a DMAPI event if needed. */
4058 if (alloc_type != 0 && offset < ip->i_d.di_size && 4058 if (alloc_type != 0 && offset < ip->i_size &&
4059 (attr_flags&ATTR_DMI) == 0 && 4059 (attr_flags&ATTR_DMI) == 0 &&
4060 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { 4060 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
4061 xfs_off_t end_dmi_offset; 4061 xfs_off_t end_dmi_offset;
4062 4062
4063 end_dmi_offset = offset+len; 4063 end_dmi_offset = offset+len;
4064 if (end_dmi_offset > ip->i_d.di_size) 4064 if (end_dmi_offset > ip->i_size)
4065 end_dmi_offset = ip->i_d.di_size; 4065 end_dmi_offset = ip->i_size;
4066 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip), 4066 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip),
4067 offset, end_dmi_offset - offset, 4067 offset, end_dmi_offset - offset,
4068 0, NULL); 4068 0, NULL);
@@ -4318,11 +4318,11 @@ xfs_free_file_space(
4318 end_dmi_offset = offset + len; 4318 end_dmi_offset = offset + len;
4319 endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset); 4319 endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
4320 4320
4321 if (offset < ip->i_d.di_size && 4321 if (offset < ip->i_size &&
4322 (attr_flags & ATTR_DMI) == 0 && 4322 (attr_flags & ATTR_DMI) == 0 &&
4323 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { 4323 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
4324 if (end_dmi_offset > ip->i_d.di_size) 4324 if (end_dmi_offset > ip->i_size)
4325 end_dmi_offset = ip->i_d.di_size; 4325 end_dmi_offset = ip->i_size;
4326 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, 4326 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp,
4327 offset, end_dmi_offset - offset, 4327 offset, end_dmi_offset - offset,
4328 AT_DELAY_FLAG(attr_flags), NULL); 4328 AT_DELAY_FLAG(attr_flags), NULL);
@@ -4541,7 +4541,7 @@ xfs_change_file_space(
4541 bf->l_start += offset; 4541 bf->l_start += offset;
4542 break; 4542 break;
4543 case 2: /*SEEK_END*/ 4543 case 2: /*SEEK_END*/
4544 bf->l_start += ip->i_d.di_size; 4544 bf->l_start += ip->i_size;
4545 break; 4545 break;
4546 default: 4546 default:
4547 return XFS_ERROR(EINVAL); 4547 return XFS_ERROR(EINVAL);
@@ -4558,7 +4558,7 @@ xfs_change_file_space(
4558 bf->l_whence = 0; 4558 bf->l_whence = 0;
4559 4559
4560 startoffset = bf->l_start; 4560 startoffset = bf->l_start;
4561 fsize = ip->i_d.di_size; 4561 fsize = ip->i_size;
4562 4562
4563 /* 4563 /*
4564 * XFS_IOC_RESVSP and XFS_IOC_UNRESVSP will reserve or unreserve 4564 * XFS_IOC_RESVSP and XFS_IOC_UNRESVSP will reserve or unreserve