diff options
-rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.c | 89 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.c | 91 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.c | 14 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 48 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_iocore.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.c | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 40 |
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 | */ | ||
150 | STATIC void | ||
151 | xfs_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 | */ |
148 | STATIC void | 185 | STATIC void |
149 | xfs_end_bio_delalloc( | 186 | xfs_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 | */ | ||
236 | STATIC void | ||
237 | xfs_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 | |||
52 | xfs_size_fn( | 52 | xfs_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 | ||
58 | STATIC int | 58 | STATIC 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 | ||
678 | retry: | 678 | retry: |
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 | ||
24 | typedef enum { /* iomap_flags values */ | 24 | typedef 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 |