diff options
Diffstat (limited to 'fs/xfs/xfs_aops.c')
-rw-r--r-- | fs/xfs/xfs_aops.c | 97 |
1 files changed, 65 insertions, 32 deletions
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 8dad722c0041..e562dd43f41f 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
@@ -124,6 +124,12 @@ xfs_setfilesize_trans_alloc( | |||
124 | ioend->io_append_trans = tp; | 124 | ioend->io_append_trans = tp; |
125 | 125 | ||
126 | /* | 126 | /* |
127 | * We will pass freeze protection with a transaction. So tell lockdep | ||
128 | * we released it. | ||
129 | */ | ||
130 | rwsem_release(&ioend->io_inode->i_sb->s_writers.lock_map[SB_FREEZE_FS-1], | ||
131 | 1, _THIS_IP_); | ||
132 | /* | ||
127 | * We hand off the transaction to the completion thread now, so | 133 | * We hand off the transaction to the completion thread now, so |
128 | * clear the flag here. | 134 | * clear the flag here. |
129 | */ | 135 | */ |
@@ -179,7 +185,7 @@ xfs_finish_ioend( | |||
179 | if (atomic_dec_and_test(&ioend->io_remaining)) { | 185 | if (atomic_dec_and_test(&ioend->io_remaining)) { |
180 | struct xfs_mount *mp = XFS_I(ioend->io_inode)->i_mount; | 186 | struct xfs_mount *mp = XFS_I(ioend->io_inode)->i_mount; |
181 | 187 | ||
182 | if (ioend->io_type == IO_UNWRITTEN) | 188 | if (ioend->io_type == XFS_IO_UNWRITTEN) |
183 | queue_work(mp->m_unwritten_workqueue, &ioend->io_work); | 189 | queue_work(mp->m_unwritten_workqueue, &ioend->io_work); |
184 | else if (ioend->io_append_trans) | 190 | else if (ioend->io_append_trans) |
185 | queue_work(mp->m_data_workqueue, &ioend->io_work); | 191 | queue_work(mp->m_data_workqueue, &ioend->io_work); |
@@ -199,6 +205,15 @@ xfs_end_io( | |||
199 | struct xfs_inode *ip = XFS_I(ioend->io_inode); | 205 | struct xfs_inode *ip = XFS_I(ioend->io_inode); |
200 | int error = 0; | 206 | int error = 0; |
201 | 207 | ||
208 | if (ioend->io_append_trans) { | ||
209 | /* | ||
210 | * We've got freeze protection passed with the transaction. | ||
211 | * Tell lockdep about it. | ||
212 | */ | ||
213 | rwsem_acquire_read( | ||
214 | &ioend->io_inode->i_sb->s_writers.lock_map[SB_FREEZE_FS-1], | ||
215 | 0, 1, _THIS_IP_); | ||
216 | } | ||
202 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { | 217 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { |
203 | ioend->io_error = -EIO; | 218 | ioend->io_error = -EIO; |
204 | goto done; | 219 | goto done; |
@@ -210,7 +225,7 @@ xfs_end_io( | |||
210 | * For unwritten extents we need to issue transactions to convert a | 225 | * For unwritten extents we need to issue transactions to convert a |
211 | * range to normal written extens after the data I/O has finished. | 226 | * range to normal written extens after the data I/O has finished. |
212 | */ | 227 | */ |
213 | if (ioend->io_type == IO_UNWRITTEN) { | 228 | if (ioend->io_type == XFS_IO_UNWRITTEN) { |
214 | /* | 229 | /* |
215 | * For buffered I/O we never preallocate a transaction when | 230 | * For buffered I/O we never preallocate a transaction when |
216 | * doing the unwritten extent conversion, but for direct I/O | 231 | * doing the unwritten extent conversion, but for direct I/O |
@@ -312,7 +327,7 @@ xfs_map_blocks( | |||
312 | if (XFS_FORCED_SHUTDOWN(mp)) | 327 | if (XFS_FORCED_SHUTDOWN(mp)) |
313 | return -XFS_ERROR(EIO); | 328 | return -XFS_ERROR(EIO); |
314 | 329 | ||
315 | if (type == IO_UNWRITTEN) | 330 | if (type == XFS_IO_UNWRITTEN) |
316 | bmapi_flags |= XFS_BMAPI_IGSTATE; | 331 | bmapi_flags |= XFS_BMAPI_IGSTATE; |
317 | 332 | ||
318 | if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) { | 333 | if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) { |
@@ -323,10 +338,10 @@ xfs_map_blocks( | |||
323 | 338 | ||
324 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || | 339 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || |
325 | (ip->i_df.if_flags & XFS_IFEXTENTS)); | 340 | (ip->i_df.if_flags & XFS_IFEXTENTS)); |
326 | ASSERT(offset <= mp->m_maxioffset); | 341 | ASSERT(offset <= mp->m_super->s_maxbytes); |
327 | 342 | ||
328 | if (offset + count > mp->m_maxioffset) | 343 | if (offset + count > mp->m_super->s_maxbytes) |
329 | count = mp->m_maxioffset - offset; | 344 | count = mp->m_super->s_maxbytes - offset; |
330 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); | 345 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); |
331 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 346 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
332 | error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, | 347 | error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, |
@@ -336,7 +351,7 @@ xfs_map_blocks( | |||
336 | if (error) | 351 | if (error) |
337 | return -XFS_ERROR(error); | 352 | return -XFS_ERROR(error); |
338 | 353 | ||
339 | if (type == IO_DELALLOC && | 354 | if (type == XFS_IO_DELALLOC && |
340 | (!nimaps || isnullstartblock(imap->br_startblock))) { | 355 | (!nimaps || isnullstartblock(imap->br_startblock))) { |
341 | error = xfs_iomap_write_allocate(ip, offset, count, imap); | 356 | error = xfs_iomap_write_allocate(ip, offset, count, imap); |
342 | if (!error) | 357 | if (!error) |
@@ -345,7 +360,7 @@ xfs_map_blocks( | |||
345 | } | 360 | } |
346 | 361 | ||
347 | #ifdef DEBUG | 362 | #ifdef DEBUG |
348 | if (type == IO_UNWRITTEN) { | 363 | if (type == XFS_IO_UNWRITTEN) { |
349 | ASSERT(nimaps); | 364 | ASSERT(nimaps); |
350 | ASSERT(imap->br_startblock != HOLESTARTBLOCK); | 365 | ASSERT(imap->br_startblock != HOLESTARTBLOCK); |
351 | ASSERT(imap->br_startblock != DELAYSTARTBLOCK); | 366 | ASSERT(imap->br_startblock != DELAYSTARTBLOCK); |
@@ -634,11 +649,11 @@ xfs_check_page_type( | |||
634 | bh = head = page_buffers(page); | 649 | bh = head = page_buffers(page); |
635 | do { | 650 | do { |
636 | if (buffer_unwritten(bh)) | 651 | if (buffer_unwritten(bh)) |
637 | acceptable += (type == IO_UNWRITTEN); | 652 | acceptable += (type == XFS_IO_UNWRITTEN); |
638 | else if (buffer_delay(bh)) | 653 | else if (buffer_delay(bh)) |
639 | acceptable += (type == IO_DELALLOC); | 654 | acceptable += (type == XFS_IO_DELALLOC); |
640 | else if (buffer_dirty(bh) && buffer_mapped(bh)) | 655 | else if (buffer_dirty(bh) && buffer_mapped(bh)) |
641 | acceptable += (type == IO_OVERWRITE); | 656 | acceptable += (type == XFS_IO_OVERWRITE); |
642 | else | 657 | else |
643 | break; | 658 | break; |
644 | } while ((bh = bh->b_this_page) != head); | 659 | } while ((bh = bh->b_this_page) != head); |
@@ -721,11 +736,11 @@ xfs_convert_page( | |||
721 | if (buffer_unwritten(bh) || buffer_delay(bh) || | 736 | if (buffer_unwritten(bh) || buffer_delay(bh) || |
722 | buffer_mapped(bh)) { | 737 | buffer_mapped(bh)) { |
723 | if (buffer_unwritten(bh)) | 738 | if (buffer_unwritten(bh)) |
724 | type = IO_UNWRITTEN; | 739 | type = XFS_IO_UNWRITTEN; |
725 | else if (buffer_delay(bh)) | 740 | else if (buffer_delay(bh)) |
726 | type = IO_DELALLOC; | 741 | type = XFS_IO_DELALLOC; |
727 | else | 742 | else |
728 | type = IO_OVERWRITE; | 743 | type = XFS_IO_OVERWRITE; |
729 | 744 | ||
730 | if (!xfs_imap_valid(inode, imap, offset)) { | 745 | if (!xfs_imap_valid(inode, imap, offset)) { |
731 | done = 1; | 746 | done = 1; |
@@ -733,7 +748,7 @@ xfs_convert_page( | |||
733 | } | 748 | } |
734 | 749 | ||
735 | lock_buffer(bh); | 750 | lock_buffer(bh); |
736 | if (type != IO_OVERWRITE) | 751 | if (type != XFS_IO_OVERWRITE) |
737 | xfs_map_at_offset(inode, bh, imap, offset); | 752 | xfs_map_at_offset(inode, bh, imap, offset); |
738 | xfs_add_to_ioend(inode, bh, offset, type, | 753 | xfs_add_to_ioend(inode, bh, offset, type, |
739 | ioendp, done); | 754 | ioendp, done); |
@@ -831,7 +846,7 @@ xfs_aops_discard_page( | |||
831 | struct buffer_head *bh, *head; | 846 | struct buffer_head *bh, *head; |
832 | loff_t offset = page_offset(page); | 847 | loff_t offset = page_offset(page); |
833 | 848 | ||
834 | if (!xfs_check_page_type(page, IO_DELALLOC)) | 849 | if (!xfs_check_page_type(page, XFS_IO_DELALLOC)) |
835 | goto out_invalidate; | 850 | goto out_invalidate; |
836 | 851 | ||
837 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 852 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
@@ -927,11 +942,26 @@ xfs_vm_writepage( | |||
927 | end_index = offset >> PAGE_CACHE_SHIFT; | 942 | end_index = offset >> PAGE_CACHE_SHIFT; |
928 | last_index = (offset - 1) >> PAGE_CACHE_SHIFT; | 943 | last_index = (offset - 1) >> PAGE_CACHE_SHIFT; |
929 | if (page->index >= end_index) { | 944 | if (page->index >= end_index) { |
930 | if ((page->index >= end_index + 1) || | 945 | unsigned offset_into_page = offset & (PAGE_CACHE_SIZE - 1); |
931 | !(i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) { | 946 | |
947 | /* | ||
948 | * Just skip the page if it is fully outside i_size, e.g. due | ||
949 | * to a truncate operation that is in progress. | ||
950 | */ | ||
951 | if (page->index >= end_index + 1 || offset_into_page == 0) { | ||
932 | unlock_page(page); | 952 | unlock_page(page); |
933 | return 0; | 953 | return 0; |
934 | } | 954 | } |
955 | |||
956 | /* | ||
957 | * The page straddles i_size. It must be zeroed out on each | ||
958 | * and every writepage invocation because it may be mmapped. | ||
959 | * "A file is mapped in multiples of the page size. For a file | ||
960 | * that is not a multiple of the page size, the remaining | ||
961 | * memory is zeroed when mapped, and writes to that region are | ||
962 | * not written out to the file." | ||
963 | */ | ||
964 | zero_user_segment(page, offset_into_page, PAGE_CACHE_SIZE); | ||
935 | } | 965 | } |
936 | 966 | ||
937 | end_offset = min_t(unsigned long long, | 967 | end_offset = min_t(unsigned long long, |
@@ -941,7 +971,7 @@ xfs_vm_writepage( | |||
941 | 971 | ||
942 | bh = head = page_buffers(page); | 972 | bh = head = page_buffers(page); |
943 | offset = page_offset(page); | 973 | offset = page_offset(page); |
944 | type = IO_OVERWRITE; | 974 | type = XFS_IO_OVERWRITE; |
945 | 975 | ||
946 | if (wbc->sync_mode == WB_SYNC_NONE) | 976 | if (wbc->sync_mode == WB_SYNC_NONE) |
947 | nonblocking = 1; | 977 | nonblocking = 1; |
@@ -966,18 +996,18 @@ xfs_vm_writepage( | |||
966 | } | 996 | } |
967 | 997 | ||
968 | if (buffer_unwritten(bh)) { | 998 | if (buffer_unwritten(bh)) { |
969 | if (type != IO_UNWRITTEN) { | 999 | if (type != XFS_IO_UNWRITTEN) { |
970 | type = IO_UNWRITTEN; | 1000 | type = XFS_IO_UNWRITTEN; |
971 | imap_valid = 0; | 1001 | imap_valid = 0; |
972 | } | 1002 | } |
973 | } else if (buffer_delay(bh)) { | 1003 | } else if (buffer_delay(bh)) { |
974 | if (type != IO_DELALLOC) { | 1004 | if (type != XFS_IO_DELALLOC) { |
975 | type = IO_DELALLOC; | 1005 | type = XFS_IO_DELALLOC; |
976 | imap_valid = 0; | 1006 | imap_valid = 0; |
977 | } | 1007 | } |
978 | } else if (buffer_uptodate(bh)) { | 1008 | } else if (buffer_uptodate(bh)) { |
979 | if (type != IO_OVERWRITE) { | 1009 | if (type != XFS_IO_OVERWRITE) { |
980 | type = IO_OVERWRITE; | 1010 | type = XFS_IO_OVERWRITE; |
981 | imap_valid = 0; | 1011 | imap_valid = 0; |
982 | } | 1012 | } |
983 | } else { | 1013 | } else { |
@@ -1013,7 +1043,7 @@ xfs_vm_writepage( | |||
1013 | } | 1043 | } |
1014 | if (imap_valid) { | 1044 | if (imap_valid) { |
1015 | lock_buffer(bh); | 1045 | lock_buffer(bh); |
1016 | if (type != IO_OVERWRITE) | 1046 | if (type != XFS_IO_OVERWRITE) |
1017 | xfs_map_at_offset(inode, bh, &imap, offset); | 1047 | xfs_map_at_offset(inode, bh, &imap, offset); |
1018 | xfs_add_to_ioend(inode, bh, offset, type, &ioend, | 1048 | xfs_add_to_ioend(inode, bh, offset, type, &ioend, |
1019 | new_ioend); | 1049 | new_ioend); |
@@ -1054,7 +1084,7 @@ xfs_vm_writepage( | |||
1054 | * Reserve log space if we might write beyond the on-disk | 1084 | * Reserve log space if we might write beyond the on-disk |
1055 | * inode size. | 1085 | * inode size. |
1056 | */ | 1086 | */ |
1057 | if (ioend->io_type != IO_UNWRITTEN && | 1087 | if (ioend->io_type != XFS_IO_UNWRITTEN && |
1058 | xfs_ioend_is_append(ioend)) { | 1088 | xfs_ioend_is_append(ioend)) { |
1059 | err = xfs_setfilesize_trans_alloc(ioend); | 1089 | err = xfs_setfilesize_trans_alloc(ioend); |
1060 | if (err) | 1090 | if (err) |
@@ -1162,9 +1192,9 @@ __xfs_get_blocks( | |||
1162 | lockmode = xfs_ilock_map_shared(ip); | 1192 | lockmode = xfs_ilock_map_shared(ip); |
1163 | } | 1193 | } |
1164 | 1194 | ||
1165 | ASSERT(offset <= mp->m_maxioffset); | 1195 | ASSERT(offset <= mp->m_super->s_maxbytes); |
1166 | if (offset + size > mp->m_maxioffset) | 1196 | if (offset + size > mp->m_super->s_maxbytes) |
1167 | size = mp->m_maxioffset - offset; | 1197 | size = mp->m_super->s_maxbytes - offset; |
1168 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size); | 1198 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size); |
1169 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 1199 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
1170 | 1200 | ||
@@ -1351,7 +1381,7 @@ xfs_end_io_direct_write( | |||
1351 | ioend->io_iocb = iocb; | 1381 | ioend->io_iocb = iocb; |
1352 | ioend->io_result = ret; | 1382 | ioend->io_result = ret; |
1353 | if (private && size > 0) | 1383 | if (private && size > 0) |
1354 | ioend->io_type = IO_UNWRITTEN; | 1384 | ioend->io_type = XFS_IO_UNWRITTEN; |
1355 | 1385 | ||
1356 | if (is_async) { | 1386 | if (is_async) { |
1357 | ioend->io_isasync = 1; | 1387 | ioend->io_isasync = 1; |
@@ -1383,7 +1413,7 @@ xfs_vm_direct_IO( | |||
1383 | * and converts at least on unwritten extent we will cancel | 1413 | * and converts at least on unwritten extent we will cancel |
1384 | * the still clean transaction after the I/O has finished. | 1414 | * the still clean transaction after the I/O has finished. |
1385 | */ | 1415 | */ |
1386 | iocb->private = ioend = xfs_alloc_ioend(inode, IO_DIRECT); | 1416 | iocb->private = ioend = xfs_alloc_ioend(inode, XFS_IO_DIRECT); |
1387 | if (offset + size > XFS_I(inode)->i_d.di_size) { | 1417 | if (offset + size > XFS_I(inode)->i_d.di_size) { |
1388 | ret = xfs_setfilesize_trans_alloc(ioend); | 1418 | ret = xfs_setfilesize_trans_alloc(ioend); |
1389 | if (ret) | 1419 | if (ret) |
@@ -1410,6 +1440,9 @@ out_trans_cancel: | |||
1410 | if (ioend->io_append_trans) { | 1440 | if (ioend->io_append_trans) { |
1411 | current_set_flags_nested(&ioend->io_append_trans->t_pflags, | 1441 | current_set_flags_nested(&ioend->io_append_trans->t_pflags, |
1412 | PF_FSTRANS); | 1442 | PF_FSTRANS); |
1443 | rwsem_acquire_read( | ||
1444 | &inode->i_sb->s_writers.lock_map[SB_FREEZE_FS-1], | ||
1445 | 0, 1, _THIS_IP_); | ||
1413 | xfs_trans_cancel(ioend->io_append_trans, 0); | 1446 | xfs_trans_cancel(ioend->io_append_trans, 0); |
1414 | } | 1447 | } |
1415 | out_destroy_ioend: | 1448 | out_destroy_ioend: |