diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-03 17:33:38 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-03 17:33:38 -0400 |
| commit | 51102ee5b8853d230e534cbcd0d888f0134738a3 (patch) | |
| tree | 5a34844b3040dbc099dd0d3ebc2e6fca0bc65855 /fs/xfs/linux-2.6 | |
| parent | 54161df1fb1469d66bce3a3b14d8281adbb69263 (diff) | |
| parent | 6b0a2996a0c023d84bc27ec7528a6e54cb5ea264 (diff) | |
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
* 'for-linus' of git://oss.sgi.com/xfs/xfs: (49 commits)
xfs simplify and speed up direct I/O completions
xfs: move aio completion after unwritten extent conversion
direct-io: move aio_complete into ->end_io
xfs: fix big endian build
xfs: clean up xfs_bmap_get_bp
xfs: simplify xfs_truncate_file
xfs: kill the b_strat callback in xfs_buf
xfs: remove obsolete osyncisosync mount option
xfs: clean up filestreams helpers
xfs: fix gcc 4.6 set but not read and unused statement warnings
xfs: Fix build when CONFIG_XFS_POSIX_ACL=n
xfs: fix unsigned underflow in xfs_free_eofblocks
xfs: use GFP_NOFS for page cache allocation
xfs: fix memory reclaim recursion deadlock on locked inode buffer
xfs: fix xfs_trans_add_item() lockdep warnings
xfs: simplify and remove xfs_ireclaim
xfs: don't block on buffer read errors
xfs: move inode shrinker unregister even earlier
xfs: remove a dmapi leftover
xfs: writepage always has buffers
...
Diffstat (limited to 'fs/xfs/linux-2.6')
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_acl.c | 2 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.c | 611 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.h | 4 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.c | 62 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.h | 119 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_dmapi_priv.h | 28 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_export.c | 8 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 104 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_fs_subr.c | 4 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_fs_subr.h | 25 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl.c | 27 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl32.c | 6 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 10 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_linux.h | 1 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_quotaops.c | 1 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 171 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_super.h | 7 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 49 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.h | 3 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_trace.c | 4 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_trace.h | 128 |
21 files changed, 485 insertions, 889 deletions
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index 9f769b5b38fc..b2771862fd3d 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c | |||
| @@ -225,7 +225,7 @@ xfs_check_acl(struct inode *inode, int mask) | |||
| 225 | struct posix_acl *acl; | 225 | struct posix_acl *acl; |
| 226 | int error = -EAGAIN; | 226 | int error = -EAGAIN; |
| 227 | 227 | ||
| 228 | xfs_itrace_entry(ip); | 228 | trace_xfs_check_acl(ip); |
| 229 | 229 | ||
| 230 | /* | 230 | /* |
| 231 | * If there is no attribute fork no ACL exists on this inode and | 231 | * If there is no attribute fork no ACL exists on this inode and |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 34640d6dbdcb..d24e78f32f3e 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
| @@ -21,19 +21,12 @@ | |||
| 21 | #include "xfs_inum.h" | 21 | #include "xfs_inum.h" |
| 22 | #include "xfs_sb.h" | 22 | #include "xfs_sb.h" |
| 23 | #include "xfs_ag.h" | 23 | #include "xfs_ag.h" |
| 24 | #include "xfs_dir2.h" | ||
| 25 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
| 26 | #include "xfs_dmapi.h" | ||
| 27 | #include "xfs_mount.h" | 25 | #include "xfs_mount.h" |
| 28 | #include "xfs_bmap_btree.h" | 26 | #include "xfs_bmap_btree.h" |
| 29 | #include "xfs_alloc_btree.h" | ||
| 30 | #include "xfs_ialloc_btree.h" | ||
| 31 | #include "xfs_dir2_sf.h" | ||
| 32 | #include "xfs_attr_sf.h" | ||
| 33 | #include "xfs_dinode.h" | 27 | #include "xfs_dinode.h" |
| 34 | #include "xfs_inode.h" | 28 | #include "xfs_inode.h" |
| 35 | #include "xfs_alloc.h" | 29 | #include "xfs_alloc.h" |
| 36 | #include "xfs_btree.h" | ||
| 37 | #include "xfs_error.h" | 30 | #include "xfs_error.h" |
| 38 | #include "xfs_rw.h" | 31 | #include "xfs_rw.h" |
| 39 | #include "xfs_iomap.h" | 32 | #include "xfs_iomap.h" |
| @@ -92,18 +85,15 @@ void | |||
| 92 | xfs_count_page_state( | 85 | xfs_count_page_state( |
| 93 | struct page *page, | 86 | struct page *page, |
| 94 | int *delalloc, | 87 | int *delalloc, |
| 95 | int *unmapped, | ||
| 96 | int *unwritten) | 88 | int *unwritten) |
| 97 | { | 89 | { |
| 98 | struct buffer_head *bh, *head; | 90 | struct buffer_head *bh, *head; |
| 99 | 91 | ||
| 100 | *delalloc = *unmapped = *unwritten = 0; | 92 | *delalloc = *unwritten = 0; |
| 101 | 93 | ||
| 102 | bh = head = page_buffers(page); | 94 | bh = head = page_buffers(page); |
| 103 | do { | 95 | do { |
| 104 | if (buffer_uptodate(bh) && !buffer_mapped(bh)) | 96 | if (buffer_unwritten(bh)) |
| 105 | (*unmapped) = 1; | ||
| 106 | else if (buffer_unwritten(bh)) | ||
| 107 | (*unwritten) = 1; | 97 | (*unwritten) = 1; |
| 108 | else if (buffer_delay(bh)) | 98 | else if (buffer_delay(bh)) |
| 109 | (*delalloc) = 1; | 99 | (*delalloc) = 1; |
| @@ -212,23 +202,17 @@ xfs_setfilesize( | |||
| 212 | } | 202 | } |
| 213 | 203 | ||
| 214 | /* | 204 | /* |
| 215 | * Schedule IO completion handling on a xfsdatad if this was | 205 | * Schedule IO completion handling on the final put of an ioend. |
| 216 | * the final hold on this ioend. If we are asked to wait, | ||
| 217 | * flush the workqueue. | ||
| 218 | */ | 206 | */ |
| 219 | STATIC void | 207 | STATIC void |
| 220 | xfs_finish_ioend( | 208 | xfs_finish_ioend( |
| 221 | xfs_ioend_t *ioend, | 209 | struct xfs_ioend *ioend) |
| 222 | int wait) | ||
| 223 | { | 210 | { |
| 224 | if (atomic_dec_and_test(&ioend->io_remaining)) { | 211 | if (atomic_dec_and_test(&ioend->io_remaining)) { |
| 225 | struct workqueue_struct *wq; | 212 | if (ioend->io_type == IO_UNWRITTEN) |
| 226 | 213 | queue_work(xfsconvertd_workqueue, &ioend->io_work); | |
| 227 | wq = (ioend->io_type == IO_UNWRITTEN) ? | 214 | else |
| 228 | xfsconvertd_workqueue : xfsdatad_workqueue; | 215 | queue_work(xfsdatad_workqueue, &ioend->io_work); |
| 229 | queue_work(wq, &ioend->io_work); | ||
| 230 | if (wait) | ||
| 231 | flush_workqueue(wq); | ||
| 232 | } | 216 | } |
| 233 | } | 217 | } |
| 234 | 218 | ||
| @@ -272,11 +256,25 @@ xfs_end_io( | |||
| 272 | */ | 256 | */ |
| 273 | if (error == EAGAIN) { | 257 | if (error == EAGAIN) { |
| 274 | atomic_inc(&ioend->io_remaining); | 258 | atomic_inc(&ioend->io_remaining); |
| 275 | xfs_finish_ioend(ioend, 0); | 259 | xfs_finish_ioend(ioend); |
| 276 | /* ensure we don't spin on blocked ioends */ | 260 | /* ensure we don't spin on blocked ioends */ |
| 277 | delay(1); | 261 | delay(1); |
| 278 | } else | 262 | } else { |
| 263 | if (ioend->io_iocb) | ||
| 264 | aio_complete(ioend->io_iocb, ioend->io_result, 0); | ||
| 279 | xfs_destroy_ioend(ioend); | 265 | xfs_destroy_ioend(ioend); |
| 266 | } | ||
| 267 | } | ||
| 268 | |||
| 269 | /* | ||
| 270 | * Call IO completion handling in caller context on the final put of an ioend. | ||
| 271 | */ | ||
| 272 | STATIC void | ||
| 273 | xfs_finish_ioend_sync( | ||
| 274 | struct xfs_ioend *ioend) | ||
| 275 | { | ||
| 276 | if (atomic_dec_and_test(&ioend->io_remaining)) | ||
| 277 | xfs_end_io(&ioend->io_work); | ||
| 280 | } | 278 | } |
| 281 | 279 | ||
| 282 | /* | 280 | /* |
| @@ -309,6 +307,8 @@ xfs_alloc_ioend( | |||
| 309 | atomic_inc(&XFS_I(ioend->io_inode)->i_iocount); | 307 | atomic_inc(&XFS_I(ioend->io_inode)->i_iocount); |
| 310 | ioend->io_offset = 0; | 308 | ioend->io_offset = 0; |
| 311 | ioend->io_size = 0; | 309 | ioend->io_size = 0; |
| 310 | ioend->io_iocb = NULL; | ||
| 311 | ioend->io_result = 0; | ||
| 312 | 312 | ||
| 313 | INIT_WORK(&ioend->io_work, xfs_end_io); | 313 | INIT_WORK(&ioend->io_work, xfs_end_io); |
| 314 | return ioend; | 314 | return ioend; |
| @@ -358,7 +358,7 @@ xfs_end_bio( | |||
| 358 | bio->bi_end_io = NULL; | 358 | bio->bi_end_io = NULL; |
| 359 | bio_put(bio); | 359 | bio_put(bio); |
| 360 | 360 | ||
| 361 | xfs_finish_ioend(ioend, 0); | 361 | xfs_finish_ioend(ioend); |
| 362 | } | 362 | } |
| 363 | 363 | ||
| 364 | STATIC void | 364 | STATIC void |
| @@ -500,7 +500,7 @@ xfs_submit_ioend( | |||
| 500 | } | 500 | } |
| 501 | if (bio) | 501 | if (bio) |
| 502 | xfs_submit_ioend_bio(wbc, ioend, bio); | 502 | xfs_submit_ioend_bio(wbc, ioend, bio); |
| 503 | xfs_finish_ioend(ioend, 0); | 503 | xfs_finish_ioend(ioend); |
| 504 | } while ((ioend = next) != NULL); | 504 | } while ((ioend = next) != NULL); |
| 505 | } | 505 | } |
| 506 | 506 | ||
| @@ -614,31 +614,30 @@ xfs_map_at_offset( | |||
| 614 | STATIC unsigned int | 614 | STATIC unsigned int |
| 615 | xfs_probe_page( | 615 | xfs_probe_page( |
| 616 | struct page *page, | 616 | struct page *page, |
| 617 | unsigned int pg_offset, | 617 | unsigned int pg_offset) |
| 618 | int mapped) | ||
| 619 | { | 618 | { |
| 619 | struct buffer_head *bh, *head; | ||
| 620 | int ret = 0; | 620 | int ret = 0; |
| 621 | 621 | ||
| 622 | if (PageWriteback(page)) | 622 | if (PageWriteback(page)) |
| 623 | return 0; | 623 | return 0; |
| 624 | if (!PageDirty(page)) | ||
| 625 | return 0; | ||
| 626 | if (!page->mapping) | ||
| 627 | return 0; | ||
| 628 | if (!page_has_buffers(page)) | ||
| 629 | return 0; | ||
| 624 | 630 | ||
| 625 | if (page->mapping && PageDirty(page)) { | 631 | bh = head = page_buffers(page); |
| 626 | if (page_has_buffers(page)) { | 632 | do { |
| 627 | struct buffer_head *bh, *head; | 633 | if (!buffer_uptodate(bh)) |
| 628 | 634 | break; | |
| 629 | bh = head = page_buffers(page); | 635 | if (!buffer_mapped(bh)) |
| 630 | do { | 636 | break; |
| 631 | if (!buffer_uptodate(bh)) | 637 | ret += bh->b_size; |
| 632 | break; | 638 | if (ret >= pg_offset) |
| 633 | if (mapped != buffer_mapped(bh)) | 639 | break; |
| 634 | break; | 640 | } while ((bh = bh->b_this_page) != head); |
| 635 | ret += bh->b_size; | ||
| 636 | if (ret >= pg_offset) | ||
| 637 | break; | ||
| 638 | } while ((bh = bh->b_this_page) != head); | ||
| 639 | } else | ||
| 640 | ret = mapped ? 0 : PAGE_CACHE_SIZE; | ||
| 641 | } | ||
| 642 | 641 | ||
| 643 | return ret; | 642 | return ret; |
| 644 | } | 643 | } |
| @@ -648,8 +647,7 @@ xfs_probe_cluster( | |||
| 648 | struct inode *inode, | 647 | struct inode *inode, |
| 649 | struct page *startpage, | 648 | struct page *startpage, |
| 650 | struct buffer_head *bh, | 649 | struct buffer_head *bh, |
| 651 | struct buffer_head *head, | 650 | struct buffer_head *head) |
| 652 | int mapped) | ||
| 653 | { | 651 | { |
| 654 | struct pagevec pvec; | 652 | struct pagevec pvec; |
| 655 | pgoff_t tindex, tlast, tloff; | 653 | pgoff_t tindex, tlast, tloff; |
| @@ -658,7 +656,7 @@ xfs_probe_cluster( | |||
| 658 | 656 | ||
| 659 | /* First sum forwards in this page */ | 657 | /* First sum forwards in this page */ |
| 660 | do { | 658 | do { |
| 661 | if (!buffer_uptodate(bh) || (mapped != buffer_mapped(bh))) | 659 | if (!buffer_uptodate(bh) || !buffer_mapped(bh)) |
| 662 | return total; | 660 | return total; |
| 663 | total += bh->b_size; | 661 | total += bh->b_size; |
| 664 | } while ((bh = bh->b_this_page) != head); | 662 | } while ((bh = bh->b_this_page) != head); |
| @@ -692,7 +690,7 @@ xfs_probe_cluster( | |||
| 692 | pg_offset = PAGE_CACHE_SIZE; | 690 | pg_offset = PAGE_CACHE_SIZE; |
| 693 | 691 | ||
| 694 | if (page->index == tindex && trylock_page(page)) { | 692 | if (page->index == tindex && trylock_page(page)) { |
| 695 | pg_len = xfs_probe_page(page, pg_offset, mapped); | 693 | pg_len = xfs_probe_page(page, pg_offset); |
| 696 | unlock_page(page); | 694 | unlock_page(page); |
| 697 | } | 695 | } |
| 698 | 696 | ||
| @@ -761,7 +759,6 @@ xfs_convert_page( | |||
| 761 | struct xfs_bmbt_irec *imap, | 759 | struct xfs_bmbt_irec *imap, |
| 762 | xfs_ioend_t **ioendp, | 760 | xfs_ioend_t **ioendp, |
| 763 | struct writeback_control *wbc, | 761 | struct writeback_control *wbc, |
| 764 | int startio, | ||
| 765 | int all_bh) | 762 | int all_bh) |
| 766 | { | 763 | { |
| 767 | struct buffer_head *bh, *head; | 764 | struct buffer_head *bh, *head; |
| @@ -832,19 +829,14 @@ xfs_convert_page( | |||
| 832 | ASSERT(imap->br_startblock != DELAYSTARTBLOCK); | 829 | ASSERT(imap->br_startblock != DELAYSTARTBLOCK); |
| 833 | 830 | ||
| 834 | xfs_map_at_offset(inode, bh, imap, offset); | 831 | xfs_map_at_offset(inode, bh, imap, offset); |
| 835 | if (startio) { | 832 | xfs_add_to_ioend(inode, bh, offset, type, |
| 836 | xfs_add_to_ioend(inode, bh, offset, | 833 | ioendp, done); |
| 837 | type, ioendp, done); | 834 | |
| 838 | } else { | ||
| 839 | set_buffer_dirty(bh); | ||
| 840 | unlock_buffer(bh); | ||
| 841 | mark_buffer_dirty(bh); | ||
| 842 | } | ||
| 843 | page_dirty--; | 835 | page_dirty--; |
| 844 | count++; | 836 | count++; |
| 845 | } else { | 837 | } else { |
| 846 | type = IO_NEW; | 838 | type = IO_NEW; |
| 847 | if (buffer_mapped(bh) && all_bh && startio) { | 839 | if (buffer_mapped(bh) && all_bh) { |
| 848 | lock_buffer(bh); | 840 | lock_buffer(bh); |
| 849 | xfs_add_to_ioend(inode, bh, offset, | 841 | xfs_add_to_ioend(inode, bh, offset, |
| 850 | type, ioendp, done); | 842 | type, ioendp, done); |
| @@ -859,14 +851,12 @@ xfs_convert_page( | |||
| 859 | if (uptodate && bh == head) | 851 | if (uptodate && bh == head) |
| 860 | SetPageUptodate(page); | 852 | SetPageUptodate(page); |
| 861 | 853 | ||
| 862 | if (startio) { | 854 | if (count) { |
| 863 | if (count) { | 855 | wbc->nr_to_write--; |
| 864 | wbc->nr_to_write--; | 856 | if (wbc->nr_to_write <= 0) |
| 865 | if (wbc->nr_to_write <= 0) | 857 | done = 1; |
| 866 | done = 1; | ||
| 867 | } | ||
| 868 | xfs_start_page_writeback(page, !page_dirty, count); | ||
| 869 | } | 858 | } |
| 859 | xfs_start_page_writeback(page, !page_dirty, count); | ||
| 870 | 860 | ||
| 871 | return done; | 861 | return done; |
| 872 | fail_unlock_page: | 862 | fail_unlock_page: |
| @@ -886,7 +876,6 @@ xfs_cluster_write( | |||
| 886 | struct xfs_bmbt_irec *imap, | 876 | struct xfs_bmbt_irec *imap, |
| 887 | xfs_ioend_t **ioendp, | 877 | xfs_ioend_t **ioendp, |
| 888 | struct writeback_control *wbc, | 878 | struct writeback_control *wbc, |
| 889 | int startio, | ||
| 890 | int all_bh, | 879 | int all_bh, |
| 891 | pgoff_t tlast) | 880 | pgoff_t tlast) |
| 892 | { | 881 | { |
| @@ -902,7 +891,7 @@ xfs_cluster_write( | |||
| 902 | 891 | ||
| 903 | for (i = 0; i < pagevec_count(&pvec); i++) { | 892 | for (i = 0; i < pagevec_count(&pvec); i++) { |
| 904 | done = xfs_convert_page(inode, pvec.pages[i], tindex++, | 893 | done = xfs_convert_page(inode, pvec.pages[i], tindex++, |
| 905 | imap, ioendp, wbc, startio, all_bh); | 894 | imap, ioendp, wbc, all_bh); |
| 906 | if (done) | 895 | if (done) |
| 907 | break; | 896 | break; |
| 908 | } | 897 | } |
| @@ -981,7 +970,7 @@ xfs_aops_discard_page( | |||
| 981 | */ | 970 | */ |
| 982 | error = xfs_bmapi(NULL, ip, offset_fsb, 1, | 971 | error = xfs_bmapi(NULL, ip, offset_fsb, 1, |
| 983 | XFS_BMAPI_ENTIRE, NULL, 0, &imap, | 972 | XFS_BMAPI_ENTIRE, NULL, 0, &imap, |
| 984 | &nimaps, NULL, NULL); | 973 | &nimaps, NULL); |
| 985 | 974 | ||
| 986 | if (error) { | 975 | if (error) { |
| 987 | /* something screwed, just bail */ | 976 | /* something screwed, just bail */ |
| @@ -1009,7 +998,7 @@ xfs_aops_discard_page( | |||
| 1009 | */ | 998 | */ |
| 1010 | xfs_bmap_init(&flist, &firstblock); | 999 | xfs_bmap_init(&flist, &firstblock); |
| 1011 | error = xfs_bunmapi(NULL, ip, offset_fsb, 1, 0, 1, &firstblock, | 1000 | error = xfs_bunmapi(NULL, ip, offset_fsb, 1, 0, 1, &firstblock, |
| 1012 | &flist, NULL, &done); | 1001 | &flist, &done); |
| 1013 | 1002 | ||
| 1014 | ASSERT(!flist.xbf_count && !flist.xbf_first); | 1003 | ASSERT(!flist.xbf_count && !flist.xbf_first); |
| 1015 | if (error) { | 1004 | if (error) { |
| @@ -1032,50 +1021,66 @@ out_invalidate: | |||
| 1032 | } | 1021 | } |
| 1033 | 1022 | ||
| 1034 | /* | 1023 | /* |
| 1035 | * Calling this without startio set means we are being asked to make a dirty | 1024 | * Write out a dirty page. |
| 1036 | * page ready for freeing it's buffers. When called with startio set then | 1025 | * |
| 1037 | * we are coming from writepage. | 1026 | * For delalloc space on the page we need to allocate space and flush it. |
| 1027 | * For unwritten space on the page we need to start the conversion to | ||
| 1028 | * regular allocated space. | ||
| 1029 | * For any other dirty buffer heads on the page we should flush them. | ||
| 1038 | * | 1030 | * |
| 1039 | * When called with startio set it is important that we write the WHOLE | 1031 | * If we detect that a transaction would be required to flush the page, we |
| 1040 | * page if possible. | 1032 | * have to check the process flags first, if we are already in a transaction |
| 1041 | * The bh->b_state's cannot know if any of the blocks or which block for | 1033 | * or disk I/O during allocations is off, we need to fail the writepage and |
| 1042 | * that matter are dirty due to mmap writes, and therefore bh uptodate is | 1034 | * redirty the page. |
| 1043 | * only valid if the page itself isn't completely uptodate. Some layers | ||
| 1044 | * may clear the page dirty flag prior to calling write page, under the | ||
| 1045 | * assumption the entire page will be written out; by not writing out the | ||
| 1046 | * whole page the page can be reused before all valid dirty data is | ||
| 1047 | * written out. Note: in the case of a page that has been dirty'd by | ||
| 1048 | * mapwrite and but partially setup by block_prepare_write the | ||
| 1049 | * bh->b_states's will not agree and only ones setup by BPW/BCW will have | ||
| 1050 | * valid state, thus the whole page must be written out thing. | ||
| 1051 | */ | 1035 | */ |
| 1052 | |||
| 1053 | STATIC int | 1036 | STATIC int |
| 1054 | xfs_page_state_convert( | 1037 | xfs_vm_writepage( |
| 1055 | struct inode *inode, | 1038 | struct page *page, |
| 1056 | struct page *page, | 1039 | struct writeback_control *wbc) |
| 1057 | struct writeback_control *wbc, | ||
| 1058 | int startio, | ||
| 1059 | int unmapped) /* also implies page uptodate */ | ||
| 1060 | { | 1040 | { |
| 1041 | struct inode *inode = page->mapping->host; | ||
| 1042 | int delalloc, unwritten; | ||
| 1061 | struct buffer_head *bh, *head; | 1043 | struct buffer_head *bh, *head; |
| 1062 | struct xfs_bmbt_irec imap; | 1044 | struct xfs_bmbt_irec imap; |
| 1063 | xfs_ioend_t *ioend = NULL, *iohead = NULL; | 1045 | xfs_ioend_t *ioend = NULL, *iohead = NULL; |
| 1064 | loff_t offset; | 1046 | loff_t offset; |
| 1065 | unsigned long p_offset = 0; | ||
| 1066 | unsigned int type; | 1047 | unsigned int type; |
| 1067 | __uint64_t end_offset; | 1048 | __uint64_t end_offset; |
| 1068 | pgoff_t end_index, last_index; | 1049 | pgoff_t end_index, last_index; |
| 1069 | ssize_t size, len; | 1050 | ssize_t size, len; |
| 1070 | int flags, err, imap_valid = 0, uptodate = 1; | 1051 | int flags, err, imap_valid = 0, uptodate = 1; |
| 1071 | int page_dirty, count = 0; | 1052 | int count = 0; |
| 1072 | int trylock = 0; | 1053 | int all_bh = 0; |
| 1073 | int all_bh = unmapped; | ||
| 1074 | 1054 | ||
| 1075 | if (startio) { | 1055 | trace_xfs_writepage(inode, page, 0); |
| 1076 | if (wbc->sync_mode == WB_SYNC_NONE && wbc->nonblocking) | 1056 | |
| 1077 | trylock |= BMAPI_TRYLOCK; | 1057 | ASSERT(page_has_buffers(page)); |
| 1078 | } | 1058 | |
| 1059 | /* | ||
| 1060 | * Refuse to write the page out if we are called from reclaim context. | ||
| 1061 | * | ||
| 1062 | * This avoids stack overflows when called from deeply used stacks in | ||
| 1063 | * random callers for direct reclaim or memcg reclaim. We explicitly | ||
| 1064 | * allow reclaim from kswapd as the stack usage there is relatively low. | ||
| 1065 | * | ||
| 1066 | * This should really be done by the core VM, but until that happens | ||
| 1067 | * filesystems like XFS, btrfs and ext4 have to take care of this | ||
| 1068 | * by themselves. | ||
| 1069 | */ | ||
| 1070 | if ((current->flags & (PF_MEMALLOC|PF_KSWAPD)) == PF_MEMALLOC) | ||
| 1071 | goto out_fail; | ||
| 1072 | |||
| 1073 | /* | ||
| 1074 | * We need a transaction if there are delalloc or unwritten buffers | ||
| 1075 | * on the page. | ||
| 1076 | * | ||
| 1077 | * If we need a transaction and the process flags say we are already | ||
| 1078 | * in a transaction, or no IO is allowed then mark the page dirty | ||
| 1079 | * again and leave the page as is. | ||
| 1080 | */ | ||
| 1081 | xfs_count_page_state(page, &delalloc, &unwritten); | ||
| 1082 | if ((current->flags & PF_FSTRANS) && (delalloc || unwritten)) | ||
| 1083 | goto out_fail; | ||
| 1079 | 1084 | ||
| 1080 | /* Is this page beyond the end of the file? */ | 1085 | /* Is this page beyond the end of the file? */ |
| 1081 | offset = i_size_read(inode); | 1086 | offset = i_size_read(inode); |
| @@ -1084,50 +1089,33 @@ xfs_page_state_convert( | |||
| 1084 | if (page->index >= end_index) { | 1089 | if (page->index >= end_index) { |
| 1085 | if ((page->index >= end_index + 1) || | 1090 | if ((page->index >= end_index + 1) || |
| 1086 | !(i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) { | 1091 | !(i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) { |
| 1087 | if (startio) | 1092 | unlock_page(page); |
| 1088 | unlock_page(page); | ||
| 1089 | return 0; | 1093 | return 0; |
| 1090 | } | 1094 | } |
| 1091 | } | 1095 | } |
| 1092 | 1096 | ||
| 1093 | /* | ||
| 1094 | * page_dirty is initially a count of buffers on the page before | ||
| 1095 | * EOF and is decremented as we move each into a cleanable state. | ||
| 1096 | * | ||
| 1097 | * Derivation: | ||
| 1098 | * | ||
| 1099 | * End offset is the highest offset that this page should represent. | ||
| 1100 | * If we are on the last page, (end_offset & (PAGE_CACHE_SIZE - 1)) | ||
| 1101 | * will evaluate non-zero and be less than PAGE_CACHE_SIZE and | ||
| 1102 | * hence give us the correct page_dirty count. On any other page, | ||
| 1103 | * it will be zero and in that case we need page_dirty to be the | ||
| 1104 | * count of buffers on the page. | ||
| 1105 | */ | ||
| 1106 | end_offset = min_t(unsigned long long, | 1097 | end_offset = min_t(unsigned long long, |
| 1107 | (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset); | 1098 | (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT, |
| 1099 | offset); | ||
| 1108 | len = 1 << inode->i_blkbits; | 1100 | len = 1 << inode->i_blkbits; |
| 1109 | p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1), | ||
| 1110 | PAGE_CACHE_SIZE); | ||
| 1111 | p_offset = p_offset ? roundup(p_offset, len) : PAGE_CACHE_SIZE; | ||
| 1112 | page_dirty = p_offset / len; | ||
| 1113 | 1101 | ||
| 1114 | bh = head = page_buffers(page); | 1102 | bh = head = page_buffers(page); |
| 1115 | offset = page_offset(page); | 1103 | offset = page_offset(page); |
| 1116 | flags = BMAPI_READ; | 1104 | flags = BMAPI_READ; |
| 1117 | type = IO_NEW; | 1105 | type = IO_NEW; |
| 1118 | 1106 | ||
| 1119 | /* TODO: cleanup count and page_dirty */ | ||
| 1120 | |||
| 1121 | do { | 1107 | do { |
| 1122 | if (offset >= end_offset) | 1108 | if (offset >= end_offset) |
| 1123 | break; | 1109 | break; |
| 1124 | if (!buffer_uptodate(bh)) | 1110 | if (!buffer_uptodate(bh)) |
| 1125 | uptodate = 0; | 1111 | uptodate = 0; |
| 1126 | if (!(PageUptodate(page) || buffer_uptodate(bh)) && !startio) { | 1112 | |
| 1127 | /* | 1113 | /* |
| 1128 | * the iomap is actually still valid, but the ioend | 1114 | * A hole may still be marked uptodate because discard_buffer |
| 1129 | * isn't. shouldn't happen too often. | 1115 | * leaves the flag set. |
| 1130 | */ | 1116 | */ |
| 1117 | if (!buffer_mapped(bh) && buffer_uptodate(bh)) { | ||
| 1118 | ASSERT(!buffer_dirty(bh)); | ||
| 1131 | imap_valid = 0; | 1119 | imap_valid = 0; |
| 1132 | continue; | 1120 | continue; |
| 1133 | } | 1121 | } |
| @@ -1135,19 +1123,7 @@ xfs_page_state_convert( | |||
| 1135 | if (imap_valid) | 1123 | if (imap_valid) |
| 1136 | imap_valid = xfs_imap_valid(inode, &imap, offset); | 1124 | imap_valid = xfs_imap_valid(inode, &imap, offset); |
| 1137 | 1125 | ||
| 1138 | /* | 1126 | if (buffer_unwritten(bh) || buffer_delay(bh)) { |
| 1139 | * First case, map an unwritten extent and prepare for | ||
| 1140 | * extent state conversion transaction on completion. | ||
| 1141 | * | ||
| 1142 | * Second case, allocate space for a delalloc buffer. | ||
| 1143 | * We can return EAGAIN here in the release page case. | ||
| 1144 | * | ||
| 1145 | * Third case, an unmapped buffer was found, and we are | ||
| 1146 | * in a path where we need to write the whole page out. | ||
| 1147 | */ | ||
| 1148 | if (buffer_unwritten(bh) || buffer_delay(bh) || | ||
| 1149 | ((buffer_uptodate(bh) || PageUptodate(page)) && | ||
| 1150 | !buffer_mapped(bh) && (unmapped || startio))) { | ||
| 1151 | int new_ioend = 0; | 1127 | int new_ioend = 0; |
| 1152 | 1128 | ||
| 1153 | /* | 1129 | /* |
| @@ -1161,15 +1137,16 @@ xfs_page_state_convert( | |||
| 1161 | flags = BMAPI_WRITE | BMAPI_IGNSTATE; | 1137 | flags = BMAPI_WRITE | BMAPI_IGNSTATE; |
| 1162 | } else if (buffer_delay(bh)) { | 1138 | } else if (buffer_delay(bh)) { |
| 1163 | type = IO_DELAY; | 1139 | type = IO_DELAY; |
| 1164 | flags = BMAPI_ALLOCATE | trylock; | 1140 | flags = BMAPI_ALLOCATE; |
| 1165 | } else { | 1141 | |
| 1166 | type = IO_NEW; | 1142 | if (wbc->sync_mode == WB_SYNC_NONE && |
| 1167 | flags = BMAPI_WRITE | BMAPI_MMAP; | 1143 | wbc->nonblocking) |
| 1144 | flags |= BMAPI_TRYLOCK; | ||
| 1168 | } | 1145 | } |
| 1169 | 1146 | ||
| 1170 | if (!imap_valid) { | 1147 | if (!imap_valid) { |
| 1171 | /* | 1148 | /* |
| 1172 | * if we didn't have a valid mapping then we | 1149 | * If we didn't have a valid mapping then we |
| 1173 | * need to ensure that we put the new mapping | 1150 | * need to ensure that we put the new mapping |
| 1174 | * in a new ioend structure. This needs to be | 1151 | * in a new ioend structure. This needs to be |
| 1175 | * done to ensure that the ioends correctly | 1152 | * done to ensure that the ioends correctly |
| @@ -1177,14 +1154,7 @@ xfs_page_state_convert( | |||
| 1177 | * for unwritten extent conversion. | 1154 | * for unwritten extent conversion. |
| 1178 | */ | 1155 | */ |
| 1179 | new_ioend = 1; | 1156 | new_ioend = 1; |
| 1180 | if (type == IO_NEW) { | 1157 | err = xfs_map_blocks(inode, offset, len, |
| 1181 | size = xfs_probe_cluster(inode, | ||
| 1182 | page, bh, head, 0); | ||
| 1183 | } else { | ||
| 1184 | size = len; | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | err = xfs_map_blocks(inode, offset, size, | ||
| 1188 | &imap, flags); | 1158 | &imap, flags); |
| 1189 | if (err) | 1159 | if (err) |
| 1190 | goto error; | 1160 | goto error; |
| @@ -1193,19 +1163,11 @@ xfs_page_state_convert( | |||
| 1193 | } | 1163 | } |
| 1194 | if (imap_valid) { | 1164 | if (imap_valid) { |
| 1195 | xfs_map_at_offset(inode, bh, &imap, offset); | 1165 | xfs_map_at_offset(inode, bh, &imap, offset); |
| 1196 | if (startio) { | 1166 | xfs_add_to_ioend(inode, bh, offset, type, |
| 1197 | xfs_add_to_ioend(inode, bh, offset, | 1167 | &ioend, new_ioend); |
| 1198 | type, &ioend, | ||
| 1199 | new_ioend); | ||
| 1200 | } else { | ||
| 1201 | set_buffer_dirty(bh); | ||
| 1202 | unlock_buffer(bh); | ||
| 1203 | mark_buffer_dirty(bh); | ||
| 1204 | } | ||
| 1205 | page_dirty--; | ||
| 1206 | count++; | 1168 | count++; |
| 1207 | } | 1169 | } |
| 1208 | } else if (buffer_uptodate(bh) && startio) { | 1170 | } else if (buffer_uptodate(bh)) { |
| 1209 | /* | 1171 | /* |
| 1210 | * we got here because the buffer is already mapped. | 1172 | * we got here because the buffer is already mapped. |
| 1211 | * That means it must already have extents allocated | 1173 | * That means it must already have extents allocated |
| @@ -1213,8 +1175,7 @@ xfs_page_state_convert( | |||
| 1213 | */ | 1175 | */ |
| 1214 | if (!imap_valid || flags != BMAPI_READ) { | 1176 | if (!imap_valid || flags != BMAPI_READ) { |
| 1215 | flags = BMAPI_READ; | 1177 | flags = BMAPI_READ; |
| 1216 | size = xfs_probe_cluster(inode, page, bh, | 1178 | size = xfs_probe_cluster(inode, page, bh, head); |
| 1217 | head, 1); | ||
| 1218 | err = xfs_map_blocks(inode, offset, size, | 1179 | err = xfs_map_blocks(inode, offset, size, |
| 1219 | &imap, flags); | 1180 | &imap, flags); |
| 1220 | if (err) | 1181 | if (err) |
| @@ -1233,18 +1194,16 @@ xfs_page_state_convert( | |||
| 1233 | */ | 1194 | */ |
| 1234 | type = IO_NEW; | 1195 | type = IO_NEW; |
| 1235 | if (trylock_buffer(bh)) { | 1196 | if (trylock_buffer(bh)) { |
| 1236 | ASSERT(buffer_mapped(bh)); | ||
| 1237 | if (imap_valid) | 1197 | if (imap_valid) |
| 1238 | all_bh = 1; | 1198 | all_bh = 1; |
| 1239 | xfs_add_to_ioend(inode, bh, offset, type, | 1199 | xfs_add_to_ioend(inode, bh, offset, type, |
| 1240 | &ioend, !imap_valid); | 1200 | &ioend, !imap_valid); |
| 1241 | page_dirty--; | ||
| 1242 | count++; | 1201 | count++; |
| 1243 | } else { | 1202 | } else { |
| 1244 | imap_valid = 0; | 1203 | imap_valid = 0; |
| 1245 | } | 1204 | } |
| 1246 | } else if ((buffer_uptodate(bh) || PageUptodate(page)) && | 1205 | } else if (PageUptodate(page)) { |
| 1247 | (unmapped || startio)) { | 1206 | ASSERT(buffer_mapped(bh)); |
| 1248 | imap_valid = 0; | 1207 | imap_valid = 0; |
| 1249 | } | 1208 | } |
| 1250 | 1209 | ||
| @@ -1256,8 +1215,7 @@ xfs_page_state_convert( | |||
| 1256 | if (uptodate && bh == head) | 1215 | if (uptodate && bh == head) |
| 1257 | SetPageUptodate(page); | 1216 | SetPageUptodate(page); |
| 1258 | 1217 | ||
| 1259 | if (startio) | 1218 | xfs_start_page_writeback(page, 1, count); |
| 1260 | xfs_start_page_writeback(page, 1, count); | ||
| 1261 | 1219 | ||
| 1262 | if (ioend && imap_valid) { | 1220 | if (ioend && imap_valid) { |
| 1263 | xfs_off_t end_index; | 1221 | xfs_off_t end_index; |
| @@ -1275,131 +1233,27 @@ xfs_page_state_convert( | |||
| 1275 | end_index = last_index; | 1233 | end_index = last_index; |
| 1276 | 1234 | ||
| 1277 | xfs_cluster_write(inode, page->index + 1, &imap, &ioend, | 1235 | xfs_cluster_write(inode, page->index + 1, &imap, &ioend, |
| 1278 | wbc, startio, all_bh, end_index); | 1236 | wbc, all_bh, end_index); |
| 1279 | } | 1237 | } |
| 1280 | 1238 | ||
| 1281 | if (iohead) | 1239 | if (iohead) |
| 1282 | xfs_submit_ioend(wbc, iohead); | 1240 | xfs_submit_ioend(wbc, iohead); |
| 1283 | 1241 | ||
| 1284 | return page_dirty; | 1242 | return 0; |
| 1285 | 1243 | ||
| 1286 | error: | 1244 | error: |
| 1287 | if (iohead) | 1245 | if (iohead) |
| 1288 | xfs_cancel_ioend(iohead); | 1246 | xfs_cancel_ioend(iohead); |
| 1289 | 1247 | ||
| 1290 | /* | 1248 | xfs_aops_discard_page(page); |
| 1291 | * If it's delalloc and we have nowhere to put it, | 1249 | ClearPageUptodate(page); |
| 1292 | * throw it away, unless the lower layers told | 1250 | unlock_page(page); |
| 1293 | * us to try again. | ||
| 1294 | */ | ||
| 1295 | if (err != -EAGAIN) { | ||
| 1296 | if (!unmapped) | ||
| 1297 | xfs_aops_discard_page(page); | ||
| 1298 | ClearPageUptodate(page); | ||
| 1299 | } | ||
| 1300 | return err; | 1251 | return err; |
| 1301 | } | ||
| 1302 | |||
| 1303 | /* | ||
| 1304 | * writepage: Called from one of two places: | ||
| 1305 | * | ||
| 1306 | * 1. we are flushing a delalloc buffer head. | ||
| 1307 | * | ||
| 1308 | * 2. we are writing out a dirty page. Typically the page dirty | ||
| 1309 | * state is cleared before we get here. In this case is it | ||
| 1310 | * conceivable we have no buffer heads. | ||
| 1311 | * | ||
| 1312 | * For delalloc space on the page we need to allocate space and | ||
| 1313 | * flush it. For unmapped buffer heads on the page we should | ||
| 1314 | * allocate space if the page is uptodate. For any other dirty | ||
| 1315 | * buffer heads on the page we should flush them. | ||
| 1316 | * | ||
| 1317 | * If we detect that a transaction would be required to flush | ||
| 1318 | * the page, we have to check the process flags first, if we | ||
| 1319 | * are already in a transaction or disk I/O during allocations | ||
| 1320 | * is off, we need to fail the writepage and redirty the page. | ||
| 1321 | */ | ||
| 1322 | |||
| 1323 | STATIC int | ||
| 1324 | xfs_vm_writepage( | ||
| 1325 | struct page *page, | ||
| 1326 | struct writeback_control *wbc) | ||
| 1327 | { | ||
| 1328 | int error; | ||
| 1329 | int need_trans; | ||
| 1330 | int delalloc, unmapped, unwritten; | ||
| 1331 | struct inode *inode = page->mapping->host; | ||
| 1332 | |||
| 1333 | trace_xfs_writepage(inode, page, 0); | ||
| 1334 | |||
| 1335 | /* | ||
| 1336 | * Refuse to write the page out if we are called from reclaim context. | ||
| 1337 | * | ||
| 1338 | * This is primarily to avoid stack overflows when called from deep | ||
| 1339 | * used stacks in random callers for direct reclaim, but disabling | ||
| 1340 | * reclaim for kswap is a nice side-effect as kswapd causes rather | ||
| 1341 | * suboptimal I/O patters, too. | ||
| 1342 | * | ||
| 1343 | * This should really be done by the core VM, but until that happens | ||
| 1344 | * filesystems like XFS, btrfs and ext4 have to take care of this | ||
| 1345 | * by themselves. | ||
| 1346 | */ | ||
| 1347 | if (current->flags & PF_MEMALLOC) | ||
| 1348 | goto out_fail; | ||
| 1349 | |||
| 1350 | /* | ||
| 1351 | * We need a transaction if: | ||
| 1352 | * 1. There are delalloc buffers on the page | ||
| 1353 | * 2. The page is uptodate and we have unmapped buffers | ||
| 1354 | * 3. The page is uptodate and we have no buffers | ||
| 1355 | * 4. There are unwritten buffers on the page | ||
| 1356 | */ | ||
| 1357 | |||
| 1358 | if (!page_has_buffers(page)) { | ||
| 1359 | unmapped = 1; | ||
| 1360 | need_trans = 1; | ||
| 1361 | } else { | ||
| 1362 | xfs_count_page_state(page, &delalloc, &unmapped, &unwritten); | ||
| 1363 | if (!PageUptodate(page)) | ||
| 1364 | unmapped = 0; | ||
| 1365 | need_trans = delalloc + unmapped + unwritten; | ||
| 1366 | } | ||
| 1367 | |||
| 1368 | /* | ||
| 1369 | * If we need a transaction and the process flags say | ||
| 1370 | * we are already in a transaction, or no IO is allowed | ||
| 1371 | * then mark the page dirty again and leave the page | ||
| 1372 | * as is. | ||
| 1373 | */ | ||
| 1374 | if (current_test_flags(PF_FSTRANS) && need_trans) | ||
| 1375 | goto out_fail; | ||
| 1376 | |||
| 1377 | /* | ||
| 1378 | * Delay hooking up buffer heads until we have | ||
| 1379 | * made our go/no-go decision. | ||
| 1380 | */ | ||
| 1381 | if (!page_has_buffers(page)) | ||
| 1382 | create_empty_buffers(page, 1 << inode->i_blkbits, 0); | ||
| 1383 | |||
| 1384 | /* | ||
| 1385 | * Convert delayed allocate, unwritten or unmapped space | ||
| 1386 | * to real space and flush out to disk. | ||
| 1387 | */ | ||
| 1388 | error = xfs_page_state_convert(inode, page, wbc, 1, unmapped); | ||
| 1389 | if (error == -EAGAIN) | ||
| 1390 | goto out_fail; | ||
| 1391 | if (unlikely(error < 0)) | ||
| 1392 | goto out_unlock; | ||
| 1393 | |||
| 1394 | return 0; | ||
| 1395 | 1252 | ||
| 1396 | out_fail: | 1253 | out_fail: |
| 1397 | redirty_page_for_writepage(wbc, page); | 1254 | redirty_page_for_writepage(wbc, page); |
| 1398 | unlock_page(page); | 1255 | unlock_page(page); |
| 1399 | return 0; | 1256 | return 0; |
| 1400 | out_unlock: | ||
| 1401 | unlock_page(page); | ||
| 1402 | return error; | ||
| 1403 | } | 1257 | } |
| 1404 | 1258 | ||
| 1405 | STATIC int | 1259 | STATIC int |
| @@ -1413,65 +1267,27 @@ xfs_vm_writepages( | |||
| 1413 | 1267 | ||
| 1414 | /* | 1268 | /* |
| 1415 | * Called to move a page into cleanable state - and from there | 1269 | * Called to move a page into cleanable state - and from there |
| 1416 | * to be released. Possibly the page is already clean. We always | 1270 | * to be released. The page should already be clean. We always |
| 1417 | * have buffer heads in this call. | 1271 | * have buffer heads in this call. |
| 1418 | * | 1272 | * |
| 1419 | * Returns 0 if the page is ok to release, 1 otherwise. | 1273 | * Returns 1 if the page is ok to release, 0 otherwise. |
| 1420 | * | ||
| 1421 | * Possible scenarios are: | ||
| 1422 | * | ||
| 1423 | * 1. We are being called to release a page which has been written | ||
| 1424 | * to via regular I/O. buffer heads will be dirty and possibly | ||
| 1425 | * delalloc. If no delalloc buffer heads in this case then we | ||
| 1426 | * can just return zero. | ||
| 1427 | * | ||
| 1428 | * 2. We are called to release a page which has been written via | ||
| 1429 | * mmap, all we need to do is ensure there is no delalloc | ||
| 1430 | * state in the buffer heads, if not we can let the caller | ||
| 1431 | * free them and we should come back later via writepage. | ||
| 1432 | */ | 1274 | */ |
| 1433 | STATIC int | 1275 | STATIC int |
| 1434 | xfs_vm_releasepage( | 1276 | xfs_vm_releasepage( |
| 1435 | struct page *page, | 1277 | struct page *page, |
| 1436 | gfp_t gfp_mask) | 1278 | gfp_t gfp_mask) |
| 1437 | { | 1279 | { |
| 1438 | struct inode *inode = page->mapping->host; | 1280 | int delalloc, unwritten; |
| 1439 | int dirty, delalloc, unmapped, unwritten; | ||
| 1440 | struct writeback_control wbc = { | ||
| 1441 | .sync_mode = WB_SYNC_ALL, | ||
| 1442 | .nr_to_write = 1, | ||
| 1443 | }; | ||
| 1444 | 1281 | ||
| 1445 | trace_xfs_releasepage(inode, page, 0); | 1282 | trace_xfs_releasepage(page->mapping->host, page, 0); |
| 1446 | |||
| 1447 | if (!page_has_buffers(page)) | ||
| 1448 | return 0; | ||
| 1449 | 1283 | ||
| 1450 | xfs_count_page_state(page, &delalloc, &unmapped, &unwritten); | 1284 | xfs_count_page_state(page, &delalloc, &unwritten); |
| 1451 | if (!delalloc && !unwritten) | ||
| 1452 | goto free_buffers; | ||
| 1453 | 1285 | ||
| 1454 | if (!(gfp_mask & __GFP_FS)) | 1286 | if (WARN_ON(delalloc)) |
| 1455 | return 0; | 1287 | return 0; |
| 1456 | 1288 | if (WARN_ON(unwritten)) | |
| 1457 | /* If we are already inside a transaction or the thread cannot | ||
| 1458 | * do I/O, we cannot release this page. | ||
| 1459 | */ | ||
| 1460 | if (current_test_flags(PF_FSTRANS)) | ||
| 1461 | return 0; | 1289 | return 0; |
| 1462 | 1290 | ||
| 1463 | /* | ||
| 1464 | * Convert delalloc space to real space, do not flush the | ||
| 1465 | * data out to disk, that will be done by the caller. | ||
| 1466 | * Never need to allocate space here - we will always | ||
| 1467 | * come back to writepage in that case. | ||
| 1468 | */ | ||
| 1469 | dirty = xfs_page_state_convert(inode, page, &wbc, 0, 0); | ||
| 1470 | if (dirty == 0 && !unwritten) | ||
| 1471 | goto free_buffers; | ||
| 1472 | return 0; | ||
| 1473 | |||
| 1474 | free_buffers: | ||
| 1475 | return try_to_free_buffers(page); | 1291 | return try_to_free_buffers(page); |
| 1476 | } | 1292 | } |
| 1477 | 1293 | ||
| @@ -1481,9 +1297,9 @@ __xfs_get_blocks( | |||
| 1481 | sector_t iblock, | 1297 | sector_t iblock, |
| 1482 | struct buffer_head *bh_result, | 1298 | struct buffer_head *bh_result, |
| 1483 | int create, | 1299 | int create, |
| 1484 | int direct, | 1300 | int direct) |
| 1485 | bmapi_flags_t flags) | ||
| 1486 | { | 1301 | { |
| 1302 | int flags = create ? BMAPI_WRITE : BMAPI_READ; | ||
| 1487 | struct xfs_bmbt_irec imap; | 1303 | struct xfs_bmbt_irec imap; |
| 1488 | xfs_off_t offset; | 1304 | xfs_off_t offset; |
| 1489 | ssize_t size; | 1305 | ssize_t size; |
| @@ -1498,8 +1314,11 @@ __xfs_get_blocks( | |||
| 1498 | if (!create && direct && offset >= i_size_read(inode)) | 1314 | if (!create && direct && offset >= i_size_read(inode)) |
| 1499 | return 0; | 1315 | return 0; |
| 1500 | 1316 | ||
| 1501 | error = xfs_iomap(XFS_I(inode), offset, size, | 1317 | if (direct && create) |
| 1502 | create ? flags : BMAPI_READ, &imap, &nimap, &new); | 1318 | flags |= BMAPI_DIRECT; |
| 1319 | |||
| 1320 | error = xfs_iomap(XFS_I(inode), offset, size, flags, &imap, &nimap, | ||
| 1321 | &new); | ||
| 1503 | if (error) | 1322 | if (error) |
| 1504 | return -error; | 1323 | return -error; |
| 1505 | if (nimap == 0) | 1324 | if (nimap == 0) |
| @@ -1579,8 +1398,7 @@ xfs_get_blocks( | |||
| 1579 | struct buffer_head *bh_result, | 1398 | struct buffer_head *bh_result, |
| 1580 | int create) | 1399 | int create) |
| 1581 | { | 1400 | { |
| 1582 | return __xfs_get_blocks(inode, iblock, | 1401 | return __xfs_get_blocks(inode, iblock, bh_result, create, 0); |
| 1583 | bh_result, create, 0, BMAPI_WRITE); | ||
| 1584 | } | 1402 | } |
| 1585 | 1403 | ||
| 1586 | STATIC int | 1404 | STATIC int |
| @@ -1590,61 +1408,59 @@ xfs_get_blocks_direct( | |||
| 1590 | struct buffer_head *bh_result, | 1408 | struct buffer_head *bh_result, |
| 1591 | int create) | 1409 | int create) |
| 1592 | { | 1410 | { |
| 1593 | return __xfs_get_blocks(inode, iblock, | 1411 | return __xfs_get_blocks(inode, iblock, bh_result, create, 1); |
| 1594 | bh_result, create, 1, BMAPI_WRITE|BMAPI_DIRECT); | ||
| 1595 | } | 1412 | } |
| 1596 | 1413 | ||
| 1414 | /* | ||
| 1415 | * Complete a direct I/O write request. | ||
| 1416 | * | ||
| 1417 | * If the private argument is non-NULL __xfs_get_blocks signals us that we | ||
| 1418 | * need to issue a transaction to convert the range from unwritten to written | ||
| 1419 | * extents. In case this is regular synchronous I/O we just call xfs_end_io | ||
| 1420 | * to do this and we are done. But in case this was a successfull AIO | ||
| 1421 | * request this handler is called from interrupt context, from which we | ||
| 1422 | * can't start transactions. In that case offload the I/O completion to | ||
| 1423 | * the workqueues we also use for buffered I/O completion. | ||
| 1424 | */ | ||
| 1597 | STATIC void | 1425 | STATIC void |
| 1598 | xfs_end_io_direct( | 1426 | xfs_end_io_direct_write( |
| 1599 | struct kiocb *iocb, | 1427 | struct kiocb *iocb, |
| 1600 | loff_t offset, | 1428 | loff_t offset, |
| 1601 | ssize_t size, | 1429 | ssize_t size, |
| 1602 | void *private) | 1430 | void *private, |
| 1431 | int ret, | ||
| 1432 | bool is_async) | ||
| 1603 | { | 1433 | { |
| 1604 | xfs_ioend_t *ioend = iocb->private; | 1434 | struct xfs_ioend *ioend = iocb->private; |
| 1605 | 1435 | ||
| 1606 | /* | 1436 | /* |
| 1607 | * Non-NULL private data means we need to issue a transaction to | 1437 | * blockdev_direct_IO can return an error even after the I/O |
| 1608 | * convert a range from unwritten to written extents. This needs | 1438 | * completion handler was called. Thus we need to protect |
| 1609 | * to happen from process context but aio+dio I/O completion | 1439 | * against double-freeing. |
| 1610 | * happens from irq context so we need to defer it to a workqueue. | ||
| 1611 | * This is not necessary for synchronous direct I/O, but we do | ||
| 1612 | * it anyway to keep the code uniform and simpler. | ||
| 1613 | * | ||
| 1614 | * Well, if only it were that simple. Because synchronous direct I/O | ||
| 1615 | * requires extent conversion to occur *before* we return to userspace, | ||
| 1616 | * we have to wait for extent conversion to complete. Look at the | ||
| 1617 | * iocb that has been passed to us to determine if this is AIO or | ||
| 1618 | * not. If it is synchronous, tell xfs_finish_ioend() to kick the | ||
| 1619 | * workqueue and wait for it to complete. | ||
| 1620 | * | ||
| 1621 | * The core direct I/O code might be changed to always call the | ||
| 1622 | * completion handler in the future, in which case all this can | ||
| 1623 | * go away. | ||
| 1624 | */ | 1440 | */ |
| 1441 | iocb->private = NULL; | ||
| 1442 | |||
| 1625 | ioend->io_offset = offset; | 1443 | ioend->io_offset = offset; |
| 1626 | ioend->io_size = size; | 1444 | ioend->io_size = size; |
| 1627 | if (ioend->io_type == IO_READ) { | 1445 | if (private && size > 0) |
| 1628 | xfs_finish_ioend(ioend, 0); | 1446 | ioend->io_type = IO_UNWRITTEN; |
| 1629 | } else if (private && size > 0) { | 1447 | |
| 1630 | xfs_finish_ioend(ioend, is_sync_kiocb(iocb)); | 1448 | if (is_async) { |
| 1631 | } else { | ||
| 1632 | /* | 1449 | /* |
| 1633 | * A direct I/O write ioend starts it's life in unwritten | 1450 | * If we are converting an unwritten extent we need to delay |
| 1634 | * state in case they map an unwritten extent. This write | 1451 | * the AIO completion until after the unwrittent extent |
| 1635 | * didn't map an unwritten extent so switch it's completion | 1452 | * conversion has completed, otherwise do it ASAP. |
| 1636 | * handler. | ||
| 1637 | */ | 1453 | */ |
| 1638 | ioend->io_type = IO_NEW; | 1454 | if (ioend->io_type == IO_UNWRITTEN) { |
| 1639 | xfs_finish_ioend(ioend, 0); | 1455 | ioend->io_iocb = iocb; |
| 1456 | ioend->io_result = ret; | ||
| 1457 | } else { | ||
| 1458 | aio_complete(iocb, ret, 0); | ||
| 1459 | } | ||
| 1460 | xfs_finish_ioend(ioend); | ||
| 1461 | } else { | ||
| 1462 | xfs_finish_ioend_sync(ioend); | ||
| 1640 | } | 1463 | } |
| 1641 | |||
| 1642 | /* | ||
| 1643 | * blockdev_direct_IO can return an error even after the I/O | ||
| 1644 | * completion handler was called. Thus we need to protect | ||
| 1645 | * against double-freeing. | ||
| 1646 | */ | ||
| 1647 | iocb->private = NULL; | ||
| 1648 | } | 1464 | } |
| 1649 | 1465 | ||
| 1650 | STATIC ssize_t | 1466 | STATIC ssize_t |
| @@ -1655,23 +1471,26 @@ xfs_vm_direct_IO( | |||
| 1655 | loff_t offset, | 1471 | loff_t offset, |
| 1656 | unsigned long nr_segs) | 1472 | unsigned long nr_segs) |
| 1657 | { | 1473 | { |
| 1658 | struct file *file = iocb->ki_filp; | 1474 | struct inode *inode = iocb->ki_filp->f_mapping->host; |
| 1659 | struct inode *inode = file->f_mapping->host; | 1475 | struct block_device *bdev = xfs_find_bdev_for_inode(inode); |
| 1660 | struct block_device *bdev; | 1476 | ssize_t ret; |
| 1661 | ssize_t ret; | 1477 | |
| 1662 | 1478 | if (rw & WRITE) { | |
| 1663 | bdev = xfs_find_bdev_for_inode(inode); | 1479 | iocb->private = xfs_alloc_ioend(inode, IO_NEW); |
| 1664 | 1480 | ||
| 1665 | iocb->private = xfs_alloc_ioend(inode, rw == WRITE ? | 1481 | ret = blockdev_direct_IO_no_locking(rw, iocb, inode, bdev, iov, |
| 1666 | IO_UNWRITTEN : IO_READ); | 1482 | offset, nr_segs, |
| 1667 | 1483 | xfs_get_blocks_direct, | |
| 1668 | ret = blockdev_direct_IO_no_locking(rw, iocb, inode, bdev, iov, | 1484 | xfs_end_io_direct_write); |
| 1669 | offset, nr_segs, | 1485 | if (ret != -EIOCBQUEUED && iocb->private) |
| 1670 | xfs_get_blocks_direct, | 1486 | xfs_destroy_ioend(iocb->private); |
| 1671 | xfs_end_io_direct); | 1487 | } else { |
| 1488 | ret = blockdev_direct_IO_no_locking(rw, iocb, inode, bdev, iov, | ||
| 1489 | offset, nr_segs, | ||
| 1490 | xfs_get_blocks_direct, | ||
| 1491 | NULL); | ||
| 1492 | } | ||
| 1672 | 1493 | ||
| 1673 | if (unlikely(ret != -EIOCBQUEUED && iocb->private)) | ||
| 1674 | xfs_destroy_ioend(iocb->private); | ||
| 1675 | return ret; | 1494 | return ret; |
| 1676 | } | 1495 | } |
| 1677 | 1496 | ||
| @@ -1686,8 +1505,8 @@ xfs_vm_write_begin( | |||
| 1686 | void **fsdata) | 1505 | void **fsdata) |
| 1687 | { | 1506 | { |
| 1688 | *pagep = NULL; | 1507 | *pagep = NULL; |
| 1689 | return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 1508 | return block_write_begin(file, mapping, pos, len, flags | AOP_FLAG_NOFS, |
| 1690 | xfs_get_blocks); | 1509 | pagep, fsdata, xfs_get_blocks); |
| 1691 | } | 1510 | } |
| 1692 | 1511 | ||
| 1693 | STATIC sector_t | 1512 | STATIC sector_t |
| @@ -1698,7 +1517,7 @@ xfs_vm_bmap( | |||
| 1698 | struct inode *inode = (struct inode *)mapping->host; | 1517 | struct inode *inode = (struct inode *)mapping->host; |
| 1699 | struct xfs_inode *ip = XFS_I(inode); | 1518 | struct xfs_inode *ip = XFS_I(inode); |
| 1700 | 1519 | ||
| 1701 | xfs_itrace_entry(XFS_I(inode)); | 1520 | trace_xfs_vm_bmap(XFS_I(inode)); |
| 1702 | xfs_ilock(ip, XFS_IOLOCK_SHARED); | 1521 | xfs_ilock(ip, XFS_IOLOCK_SHARED); |
| 1703 | xfs_flush_pages(ip, (xfs_off_t)0, -1, 0, FI_REMAPF); | 1522 | xfs_flush_pages(ip, (xfs_off_t)0, -1, 0, FI_REMAPF); |
| 1704 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | 1523 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); |
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h index 4cfc6ea87df8..c5057fb6237a 100644 --- a/fs/xfs/linux-2.6/xfs_aops.h +++ b/fs/xfs/linux-2.6/xfs_aops.h | |||
| @@ -37,6 +37,8 @@ typedef struct xfs_ioend { | |||
| 37 | size_t io_size; /* size of the extent */ | 37 | size_t io_size; /* size of the extent */ |
| 38 | xfs_off_t io_offset; /* offset in the file */ | 38 | xfs_off_t io_offset; /* offset in the file */ |
| 39 | struct work_struct io_work; /* xfsdatad work queue */ | 39 | struct work_struct io_work; /* xfsdatad work queue */ |
| 40 | struct kiocb *io_iocb; | ||
| 41 | int io_result; | ||
| 40 | } xfs_ioend_t; | 42 | } xfs_ioend_t; |
| 41 | 43 | ||
| 42 | extern const struct address_space_operations xfs_address_space_operations; | 44 | extern const struct address_space_operations xfs_address_space_operations; |
| @@ -45,6 +47,6 @@ extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int); | |||
| 45 | extern void xfs_ioend_init(void); | 47 | extern void xfs_ioend_init(void); |
| 46 | extern void xfs_ioend_wait(struct xfs_inode *); | 48 | extern void xfs_ioend_wait(struct xfs_inode *); |
| 47 | 49 | ||
| 48 | extern void xfs_count_page_state(struct page *, int *, int *, int *); | 50 | extern void xfs_count_page_state(struct page *, int *, int *); |
| 49 | 51 | ||
| 50 | #endif /* __XFS_AOPS_H__ */ | 52 | #endif /* __XFS_AOPS_H__ */ |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 2ee3f7a60163..ea79072f5210 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
| @@ -39,7 +39,6 @@ | |||
| 39 | #include "xfs_inum.h" | 39 | #include "xfs_inum.h" |
| 40 | #include "xfs_log.h" | 40 | #include "xfs_log.h" |
| 41 | #include "xfs_ag.h" | 41 | #include "xfs_ag.h" |
| 42 | #include "xfs_dmapi.h" | ||
| 43 | #include "xfs_mount.h" | 42 | #include "xfs_mount.h" |
| 44 | #include "xfs_trace.h" | 43 | #include "xfs_trace.h" |
| 45 | 44 | ||
| @@ -579,9 +578,9 @@ _xfs_buf_read( | |||
| 579 | XBF_READ_AHEAD | _XBF_RUN_QUEUES); | 578 | XBF_READ_AHEAD | _XBF_RUN_QUEUES); |
| 580 | 579 | ||
| 581 | status = xfs_buf_iorequest(bp); | 580 | status = xfs_buf_iorequest(bp); |
| 582 | if (!status && !(flags & XBF_ASYNC)) | 581 | if (status || XFS_BUF_ISERROR(bp) || (flags & XBF_ASYNC)) |
| 583 | status = xfs_buf_iowait(bp); | 582 | return status; |
| 584 | return status; | 583 | return xfs_buf_iowait(bp); |
| 585 | } | 584 | } |
| 586 | 585 | ||
| 587 | xfs_buf_t * | 586 | xfs_buf_t * |
| @@ -897,36 +896,6 @@ xfs_buf_unlock( | |||
| 897 | trace_xfs_buf_unlock(bp, _RET_IP_); | 896 | trace_xfs_buf_unlock(bp, _RET_IP_); |
| 898 | } | 897 | } |
| 899 | 898 | ||
| 900 | |||
| 901 | /* | ||
| 902 | * Pinning Buffer Storage in Memory | ||
| 903 | * Ensure that no attempt to force a buffer to disk will succeed. | ||
| 904 | */ | ||
| 905 | void | ||
| 906 | xfs_buf_pin( | ||
| 907 | xfs_buf_t *bp) | ||
| 908 | { | ||
| 909 | trace_xfs_buf_pin(bp, _RET_IP_); | ||
| 910 | atomic_inc(&bp->b_pin_count); | ||
| 911 | } | ||
| 912 | |||
| 913 | void | ||
| 914 | xfs_buf_unpin( | ||
| 915 | xfs_buf_t *bp) | ||
| 916 | { | ||
| 917 | trace_xfs_buf_unpin(bp, _RET_IP_); | ||
| 918 | |||
| 919 | if (atomic_dec_and_test(&bp->b_pin_count)) | ||
| 920 | wake_up_all(&bp->b_waiters); | ||
| 921 | } | ||
| 922 | |||
| 923 | int | ||
| 924 | xfs_buf_ispin( | ||
| 925 | xfs_buf_t *bp) | ||
| 926 | { | ||
| 927 | return atomic_read(&bp->b_pin_count); | ||
| 928 | } | ||
| 929 | |||
| 930 | STATIC void | 899 | STATIC void |
| 931 | xfs_buf_wait_unpin( | 900 | xfs_buf_wait_unpin( |
| 932 | xfs_buf_t *bp) | 901 | xfs_buf_t *bp) |
| @@ -1018,13 +987,12 @@ xfs_bwrite( | |||
| 1018 | { | 987 | { |
| 1019 | int error; | 988 | int error; |
| 1020 | 989 | ||
| 1021 | bp->b_strat = xfs_bdstrat_cb; | ||
| 1022 | bp->b_mount = mp; | 990 | bp->b_mount = mp; |
| 1023 | bp->b_flags |= XBF_WRITE; | 991 | bp->b_flags |= XBF_WRITE; |
| 1024 | bp->b_flags &= ~(XBF_ASYNC | XBF_READ); | 992 | bp->b_flags &= ~(XBF_ASYNC | XBF_READ); |
| 1025 | 993 | ||
| 1026 | xfs_buf_delwri_dequeue(bp); | 994 | xfs_buf_delwri_dequeue(bp); |
| 1027 | xfs_buf_iostrategy(bp); | 995 | xfs_bdstrat_cb(bp); |
| 1028 | 996 | ||
| 1029 | error = xfs_buf_iowait(bp); | 997 | error = xfs_buf_iowait(bp); |
| 1030 | if (error) | 998 | if (error) |
| @@ -1040,7 +1008,6 @@ xfs_bdwrite( | |||
| 1040 | { | 1008 | { |
| 1041 | trace_xfs_buf_bdwrite(bp, _RET_IP_); | 1009 | trace_xfs_buf_bdwrite(bp, _RET_IP_); |
| 1042 | 1010 | ||
| 1043 | bp->b_strat = xfs_bdstrat_cb; | ||
| 1044 | bp->b_mount = mp; | 1011 | bp->b_mount = mp; |
| 1045 | 1012 | ||
| 1046 | bp->b_flags &= ~XBF_READ; | 1013 | bp->b_flags &= ~XBF_READ; |
| @@ -1075,7 +1042,6 @@ xfs_bioerror( | |||
| 1075 | XFS_BUF_UNDONE(bp); | 1042 | XFS_BUF_UNDONE(bp); |
| 1076 | XFS_BUF_STALE(bp); | 1043 | XFS_BUF_STALE(bp); |
| 1077 | 1044 | ||
| 1078 | XFS_BUF_CLR_BDSTRAT_FUNC(bp); | ||
| 1079 | xfs_biodone(bp); | 1045 | xfs_biodone(bp); |
| 1080 | 1046 | ||
| 1081 | return EIO; | 1047 | return EIO; |
| @@ -1105,7 +1071,6 @@ xfs_bioerror_relse( | |||
| 1105 | XFS_BUF_DONE(bp); | 1071 | XFS_BUF_DONE(bp); |
| 1106 | XFS_BUF_STALE(bp); | 1072 | XFS_BUF_STALE(bp); |
| 1107 | XFS_BUF_CLR_IODONE_FUNC(bp); | 1073 | XFS_BUF_CLR_IODONE_FUNC(bp); |
| 1108 | XFS_BUF_CLR_BDSTRAT_FUNC(bp); | ||
| 1109 | if (!(fl & XBF_ASYNC)) { | 1074 | if (!(fl & XBF_ASYNC)) { |
| 1110 | /* | 1075 | /* |
| 1111 | * Mark b_error and B_ERROR _both_. | 1076 | * Mark b_error and B_ERROR _both_. |
| @@ -1311,8 +1276,19 @@ submit_io: | |||
| 1311 | if (size) | 1276 | if (size) |
| 1312 | goto next_chunk; | 1277 | goto next_chunk; |
| 1313 | } else { | 1278 | } else { |
| 1314 | bio_put(bio); | 1279 | /* |
| 1280 | * if we get here, no pages were added to the bio. However, | ||
| 1281 | * we can't just error out here - if the pages are locked then | ||
| 1282 | * we have to unlock them otherwise we can hang on a later | ||
| 1283 | * access to the page. | ||
| 1284 | */ | ||
| 1315 | xfs_buf_ioerror(bp, EIO); | 1285 | xfs_buf_ioerror(bp, EIO); |
| 1286 | if (bp->b_flags & _XBF_PAGE_LOCKED) { | ||
| 1287 | int i; | ||
| 1288 | for (i = 0; i < bp->b_page_count; i++) | ||
| 1289 | unlock_page(bp->b_pages[i]); | ||
| 1290 | } | ||
| 1291 | bio_put(bio); | ||
| 1316 | } | 1292 | } |
| 1317 | } | 1293 | } |
| 1318 | 1294 | ||
| @@ -1804,7 +1780,7 @@ xfs_buf_delwri_split( | |||
| 1804 | trace_xfs_buf_delwri_split(bp, _RET_IP_); | 1780 | trace_xfs_buf_delwri_split(bp, _RET_IP_); |
| 1805 | ASSERT(bp->b_flags & XBF_DELWRI); | 1781 | ASSERT(bp->b_flags & XBF_DELWRI); |
| 1806 | 1782 | ||
| 1807 | if (!xfs_buf_ispin(bp) && !xfs_buf_cond_lock(bp)) { | 1783 | if (!XFS_BUF_ISPINNED(bp) && !xfs_buf_cond_lock(bp)) { |
| 1808 | if (!force && | 1784 | if (!force && |
| 1809 | time_before(jiffies, bp->b_queuetime + age)) { | 1785 | time_before(jiffies, bp->b_queuetime + age)) { |
| 1810 | xfs_buf_unlock(bp); | 1786 | xfs_buf_unlock(bp); |
| @@ -1889,7 +1865,7 @@ xfsbufd( | |||
| 1889 | struct xfs_buf *bp; | 1865 | struct xfs_buf *bp; |
| 1890 | bp = list_first_entry(&tmp, struct xfs_buf, b_list); | 1866 | bp = list_first_entry(&tmp, struct xfs_buf, b_list); |
| 1891 | list_del_init(&bp->b_list); | 1867 | list_del_init(&bp->b_list); |
| 1892 | xfs_buf_iostrategy(bp); | 1868 | xfs_bdstrat_cb(bp); |
| 1893 | count++; | 1869 | count++; |
| 1894 | } | 1870 | } |
| 1895 | if (count) | 1871 | if (count) |
| @@ -1936,7 +1912,7 @@ xfs_flush_buftarg( | |||
| 1936 | bp->b_flags &= ~XBF_ASYNC; | 1912 | bp->b_flags &= ~XBF_ASYNC; |
| 1937 | list_add(&bp->b_list, &wait_list); | 1913 | list_add(&bp->b_list, &wait_list); |
| 1938 | } | 1914 | } |
| 1939 | xfs_buf_iostrategy(bp); | 1915 | xfs_bdstrat_cb(bp); |
| 1940 | } | 1916 | } |
| 1941 | 1917 | ||
| 1942 | if (wait) { | 1918 | if (wait) { |
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 5fbecefa5dfd..d072e5ff923b 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
| @@ -44,57 +44,57 @@ typedef enum { | |||
| 44 | XBRW_ZERO = 3, /* Zero target memory */ | 44 | XBRW_ZERO = 3, /* Zero target memory */ |
| 45 | } xfs_buf_rw_t; | 45 | } xfs_buf_rw_t; |
| 46 | 46 | ||
| 47 | typedef enum { | 47 | #define XBF_READ (1 << 0) /* buffer intended for reading from device */ |
| 48 | XBF_READ = (1 << 0), /* buffer intended for reading from device */ | 48 | #define XBF_WRITE (1 << 1) /* buffer intended for writing to device */ |
| 49 | XBF_WRITE = (1 << 1), /* buffer intended for writing to device */ | 49 | #define XBF_MAPPED (1 << 2) /* buffer mapped (b_addr valid) */ |
| 50 | XBF_MAPPED = (1 << 2), /* buffer mapped (b_addr valid) */ | 50 | #define XBF_ASYNC (1 << 4) /* initiator will not wait for completion */ |
| 51 | XBF_ASYNC = (1 << 4), /* initiator will not wait for completion */ | 51 | #define XBF_DONE (1 << 5) /* all pages in the buffer uptodate */ |
| 52 | XBF_DONE = (1 << 5), /* all pages in the buffer uptodate */ | 52 | #define XBF_DELWRI (1 << 6) /* buffer has dirty pages */ |
| 53 | XBF_DELWRI = (1 << 6), /* buffer has dirty pages */ | 53 | #define XBF_STALE (1 << 7) /* buffer has been staled, do not find it */ |
| 54 | XBF_STALE = (1 << 7), /* buffer has been staled, do not find it */ | 54 | #define XBF_FS_MANAGED (1 << 8) /* filesystem controls freeing memory */ |
| 55 | XBF_FS_MANAGED = (1 << 8), /* filesystem controls freeing memory */ | 55 | #define XBF_ORDERED (1 << 11)/* use ordered writes */ |
| 56 | XBF_ORDERED = (1 << 11), /* use ordered writes */ | 56 | #define XBF_READ_AHEAD (1 << 12)/* asynchronous read-ahead */ |
| 57 | XBF_READ_AHEAD = (1 << 12), /* asynchronous read-ahead */ | 57 | #define XBF_LOG_BUFFER (1 << 13)/* this is a buffer used for the log */ |
| 58 | XBF_LOG_BUFFER = (1 << 13), /* this is a buffer used for the log */ | 58 | |
| 59 | 59 | /* flags used only as arguments to access routines */ | |
| 60 | /* flags used only as arguments to access routines */ | 60 | #define XBF_LOCK (1 << 14)/* lock requested */ |
| 61 | XBF_LOCK = (1 << 14), /* lock requested */ | 61 | #define XBF_TRYLOCK (1 << 15)/* lock requested, but do not wait */ |
| 62 | XBF_TRYLOCK = (1 << 15), /* lock requested, but do not wait */ | 62 | #define XBF_DONT_BLOCK (1 << 16)/* do not block in current thread */ |
| 63 | XBF_DONT_BLOCK = (1 << 16), /* do not block in current thread */ | 63 | |
| 64 | 64 | /* flags used only internally */ | |
| 65 | /* flags used only internally */ | 65 | #define _XBF_PAGE_CACHE (1 << 17)/* backed by pagecache */ |
| 66 | _XBF_PAGE_CACHE = (1 << 17),/* backed by pagecache */ | 66 | #define _XBF_PAGES (1 << 18)/* backed by refcounted pages */ |
| 67 | _XBF_PAGES = (1 << 18), /* backed by refcounted pages */ | 67 | #define _XBF_RUN_QUEUES (1 << 19)/* run block device task queue */ |
| 68 | _XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */ | 68 | #define _XBF_DELWRI_Q (1 << 21)/* buffer on delwri queue */ |
| 69 | _XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */ | 69 | |
| 70 | 70 | /* | |
| 71 | /* | 71 | * Special flag for supporting metadata blocks smaller than a FSB. |
| 72 | * Special flag for supporting metadata blocks smaller than a FSB. | 72 | * |
| 73 | * | 73 | * In this case we can have multiple xfs_buf_t on a single page and |
| 74 | * In this case we can have multiple xfs_buf_t on a single page and | 74 | * need to lock out concurrent xfs_buf_t readers as they only |
| 75 | * need to lock out concurrent xfs_buf_t readers as they only | 75 | * serialise access to the buffer. |
| 76 | * serialise access to the buffer. | 76 | * |
| 77 | * | 77 | * If the FSB size >= PAGE_CACHE_SIZE case, we have no serialisation |
| 78 | * If the FSB size >= PAGE_CACHE_SIZE case, we have no serialisation | 78 | * between reads of the page. Hence we can have one thread read the |
| 79 | * between reads of the page. Hence we can have one thread read the | 79 | * page and modify it, but then race with another thread that thinks |
| 80 | * page and modify it, but then race with another thread that thinks | 80 | * the page is not up-to-date and hence reads it again. |
| 81 | * the page is not up-to-date and hence reads it again. | 81 | * |
| 82 | * | 82 | * The result is that the first modifcation to the page is lost. |
| 83 | * The result is that the first modifcation to the page is lost. | 83 | * This sort of AGF/AGI reading race can happen when unlinking inodes |
| 84 | * This sort of AGF/AGI reading race can happen when unlinking inodes | 84 | * that require truncation and results in the AGI unlinked list |
| 85 | * that require truncation and results in the AGI unlinked list | 85 | * modifications being lost. |
| 86 | * modifications being lost. | 86 | */ |
| 87 | */ | 87 | #define _XBF_PAGE_LOCKED (1 << 22) |
| 88 | _XBF_PAGE_LOCKED = (1 << 22), | 88 | |
| 89 | 89 | /* | |
| 90 | /* | 90 | * If we try a barrier write, but it fails we have to communicate |
| 91 | * If we try a barrier write, but it fails we have to communicate | 91 | * this to the upper layers. Unfortunately b_error gets overwritten |
| 92 | * this to the upper layers. Unfortunately b_error gets overwritten | 92 | * when the buffer is re-issued so we have to add another flag to |
| 93 | * when the buffer is re-issued so we have to add another flag to | 93 | * keep this information. |
| 94 | * keep this information. | 94 | */ |
| 95 | */ | 95 | #define _XFS_BARRIER_FAILED (1 << 23) |
| 96 | _XFS_BARRIER_FAILED = (1 << 23), | 96 | |
| 97 | } xfs_buf_flags_t; | 97 | typedef unsigned int xfs_buf_flags_t; |
| 98 | 98 | ||
| 99 | #define XFS_BUF_FLAGS \ | 99 | #define XFS_BUF_FLAGS \ |
| 100 | { XBF_READ, "READ" }, \ | 100 | { XBF_READ, "READ" }, \ |
| @@ -187,7 +187,6 @@ typedef struct xfs_buf { | |||
| 187 | atomic_t b_io_remaining; /* #outstanding I/O requests */ | 187 | atomic_t b_io_remaining; /* #outstanding I/O requests */ |
| 188 | xfs_buf_iodone_t b_iodone; /* I/O completion function */ | 188 | xfs_buf_iodone_t b_iodone; /* I/O completion function */ |
| 189 | xfs_buf_relse_t b_relse; /* releasing function */ | 189 | xfs_buf_relse_t b_relse; /* releasing function */ |
| 190 | xfs_buf_bdstrat_t b_strat; /* pre-write function */ | ||
| 191 | struct completion b_iowait; /* queue for I/O waiters */ | 190 | struct completion b_iowait; /* queue for I/O waiters */ |
| 192 | void *b_fspriv; | 191 | void *b_fspriv; |
| 193 | void *b_fspriv2; | 192 | void *b_fspriv2; |
| @@ -245,11 +244,6 @@ extern int xfs_buf_iowait(xfs_buf_t *); | |||
| 245 | extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, | 244 | extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, |
| 246 | xfs_buf_rw_t); | 245 | xfs_buf_rw_t); |
| 247 | 246 | ||
| 248 | static inline int xfs_buf_iostrategy(xfs_buf_t *bp) | ||
| 249 | { | ||
| 250 | return bp->b_strat ? bp->b_strat(bp) : xfs_buf_iorequest(bp); | ||
| 251 | } | ||
| 252 | |||
| 253 | static inline int xfs_buf_geterror(xfs_buf_t *bp) | 247 | static inline int xfs_buf_geterror(xfs_buf_t *bp) |
| 254 | { | 248 | { |
| 255 | return bp ? bp->b_error : ENOMEM; | 249 | return bp ? bp->b_error : ENOMEM; |
| @@ -258,11 +252,6 @@ static inline int xfs_buf_geterror(xfs_buf_t *bp) | |||
| 258 | /* Buffer Utility Routines */ | 252 | /* Buffer Utility Routines */ |
| 259 | extern xfs_caddr_t xfs_buf_offset(xfs_buf_t *, size_t); | 253 | extern xfs_caddr_t xfs_buf_offset(xfs_buf_t *, size_t); |
| 260 | 254 | ||
| 261 | /* Pinning Buffer Storage in Memory */ | ||
| 262 | extern void xfs_buf_pin(xfs_buf_t *); | ||
| 263 | extern void xfs_buf_unpin(xfs_buf_t *); | ||
| 264 | extern int xfs_buf_ispin(xfs_buf_t *); | ||
| 265 | |||
| 266 | /* Delayed Write Buffer Routines */ | 255 | /* Delayed Write Buffer Routines */ |
| 267 | extern void xfs_buf_delwri_dequeue(xfs_buf_t *); | 256 | extern void xfs_buf_delwri_dequeue(xfs_buf_t *); |
| 268 | extern void xfs_buf_delwri_promote(xfs_buf_t *); | 257 | extern void xfs_buf_delwri_promote(xfs_buf_t *); |
| @@ -326,8 +315,6 @@ extern void xfs_buf_terminate(void); | |||
| 326 | #define XFS_BUF_IODONE_FUNC(bp) ((bp)->b_iodone) | 315 | #define XFS_BUF_IODONE_FUNC(bp) ((bp)->b_iodone) |
| 327 | #define XFS_BUF_SET_IODONE_FUNC(bp, func) ((bp)->b_iodone = (func)) | 316 | #define XFS_BUF_SET_IODONE_FUNC(bp, func) ((bp)->b_iodone = (func)) |
| 328 | #define XFS_BUF_CLR_IODONE_FUNC(bp) ((bp)->b_iodone = NULL) | 317 | #define XFS_BUF_CLR_IODONE_FUNC(bp) ((bp)->b_iodone = NULL) |
| 329 | #define XFS_BUF_SET_BDSTRAT_FUNC(bp, func) ((bp)->b_strat = (func)) | ||
| 330 | #define XFS_BUF_CLR_BDSTRAT_FUNC(bp) ((bp)->b_strat = NULL) | ||
| 331 | 318 | ||
| 332 | #define XFS_BUF_FSPRIVATE(bp, type) ((type)(bp)->b_fspriv) | 319 | #define XFS_BUF_FSPRIVATE(bp, type) ((type)(bp)->b_fspriv) |
| 333 | #define XFS_BUF_SET_FSPRIVATE(bp, val) ((bp)->b_fspriv = (void*)(val)) | 320 | #define XFS_BUF_SET_FSPRIVATE(bp, val) ((bp)->b_fspriv = (void*)(val)) |
| @@ -351,7 +338,7 @@ extern void xfs_buf_terminate(void); | |||
| 351 | #define XFS_BUF_SET_VTYPE(bp, type) do { } while (0) | 338 | #define XFS_BUF_SET_VTYPE(bp, type) do { } while (0) |
| 352 | #define XFS_BUF_SET_REF(bp, ref) do { } while (0) | 339 | #define XFS_BUF_SET_REF(bp, ref) do { } while (0) |
| 353 | 340 | ||
| 354 | #define XFS_BUF_ISPINNED(bp) xfs_buf_ispin(bp) | 341 | #define XFS_BUF_ISPINNED(bp) atomic_read(&((bp)->b_pin_count)) |
| 355 | 342 | ||
| 356 | #define XFS_BUF_VALUSEMA(bp) xfs_buf_lock_value(bp) | 343 | #define XFS_BUF_VALUSEMA(bp) xfs_buf_lock_value(bp) |
| 357 | #define XFS_BUF_CPSEMA(bp) (xfs_buf_cond_lock(bp) == 0) | 344 | #define XFS_BUF_CPSEMA(bp) (xfs_buf_cond_lock(bp) == 0) |
| @@ -370,8 +357,6 @@ static inline void xfs_buf_relse(xfs_buf_t *bp) | |||
| 370 | xfs_buf_rele(bp); | 357 | xfs_buf_rele(bp); |
| 371 | } | 358 | } |
| 372 | 359 | ||
| 373 | #define xfs_bpin(bp) xfs_buf_pin(bp) | ||
| 374 | #define xfs_bunpin(bp) xfs_buf_unpin(bp) | ||
| 375 | #define xfs_biodone(bp) xfs_buf_ioend(bp, 0) | 360 | #define xfs_biodone(bp) xfs_buf_ioend(bp, 0) |
| 376 | 361 | ||
| 377 | #define xfs_biomove(bp, off, len, data, rw) \ | 362 | #define xfs_biomove(bp, off, len, data, rw) \ |
diff --git a/fs/xfs/linux-2.6/xfs_dmapi_priv.h b/fs/xfs/linux-2.6/xfs_dmapi_priv.h deleted file mode 100644 index a8b0b1685eed..000000000000 --- a/fs/xfs/linux-2.6/xfs_dmapi_priv.h +++ /dev/null | |||
| @@ -1,28 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. | ||
| 3 | * All Rights Reserved. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it would be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write the Free Software Foundation, | ||
| 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | #ifndef __XFS_DMAPI_PRIV_H__ | ||
| 19 | #define __XFS_DMAPI_PRIV_H__ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * Based on IO_ISDIRECT, decide which i_ flag is set. | ||
| 23 | */ | ||
| 24 | #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ | ||
| 25 | DM_FLAGS_IMUX : 0) | ||
| 26 | #define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX) | ||
| 27 | |||
| 28 | #endif /*__XFS_DMAPI_PRIV_H__*/ | ||
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c index e7839ee49e43..3764d74790ec 100644 --- a/fs/xfs/linux-2.6/xfs_export.c +++ b/fs/xfs/linux-2.6/xfs_export.c | |||
| @@ -23,13 +23,13 @@ | |||
| 23 | #include "xfs_sb.h" | 23 | #include "xfs_sb.h" |
| 24 | #include "xfs_ag.h" | 24 | #include "xfs_ag.h" |
| 25 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
| 26 | #include "xfs_dmapi.h" | ||
| 27 | #include "xfs_mount.h" | 26 | #include "xfs_mount.h" |
| 28 | #include "xfs_export.h" | 27 | #include "xfs_export.h" |
| 29 | #include "xfs_vnodeops.h" | 28 | #include "xfs_vnodeops.h" |
| 30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
| 31 | #include "xfs_inode.h" | 30 | #include "xfs_inode.h" |
| 32 | #include "xfs_inode_item.h" | 31 | #include "xfs_inode_item.h" |
| 32 | #include "xfs_trace.h" | ||
| 33 | 33 | ||
| 34 | /* | 34 | /* |
| 35 | * Note that we only accept fileids which are long enough rather than allow | 35 | * Note that we only accept fileids which are long enough rather than allow |
| @@ -132,8 +132,7 @@ xfs_nfs_get_inode( | |||
| 132 | * fine and not an indication of a corrupted filesystem as clients can | 132 | * fine and not an indication of a corrupted filesystem as clients can |
| 133 | * send invalid file handles and we have to handle it gracefully.. | 133 | * send invalid file handles and we have to handle it gracefully.. |
| 134 | */ | 134 | */ |
| 135 | error = xfs_iget(mp, NULL, ino, XFS_IGET_UNTRUSTED, | 135 | error = xfs_iget(mp, NULL, ino, XFS_IGET_UNTRUSTED, 0, &ip); |
| 136 | XFS_ILOCK_SHARED, &ip); | ||
| 137 | if (error) { | 136 | if (error) { |
| 138 | /* | 137 | /* |
| 139 | * EINVAL means the inode cluster doesn't exist anymore. | 138 | * EINVAL means the inode cluster doesn't exist anymore. |
| @@ -148,11 +147,10 @@ xfs_nfs_get_inode( | |||
| 148 | } | 147 | } |
| 149 | 148 | ||
| 150 | if (ip->i_d.di_gen != generation) { | 149 | if (ip->i_d.di_gen != generation) { |
| 151 | xfs_iput_new(ip, XFS_ILOCK_SHARED); | 150 | IRELE(ip); |
| 152 | return ERR_PTR(-ENOENT); | 151 | return ERR_PTR(-ENOENT); |
| 153 | } | 152 | } |
| 154 | 153 | ||
| 155 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
| 156 | return VFS_I(ip); | 154 | return VFS_I(ip); |
| 157 | } | 155 | } |
| 158 | 156 | ||
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 257a56b127cf..ba8ad422a165 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
| @@ -22,23 +22,15 @@ | |||
| 22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
| 23 | #include "xfs_sb.h" | 23 | #include "xfs_sb.h" |
| 24 | #include "xfs_ag.h" | 24 | #include "xfs_ag.h" |
| 25 | #include "xfs_dir2.h" | ||
| 26 | #include "xfs_trans.h" | 25 | #include "xfs_trans.h" |
| 27 | #include "xfs_dmapi.h" | ||
| 28 | #include "xfs_mount.h" | 26 | #include "xfs_mount.h" |
| 29 | #include "xfs_bmap_btree.h" | 27 | #include "xfs_bmap_btree.h" |
| 30 | #include "xfs_alloc_btree.h" | ||
| 31 | #include "xfs_ialloc_btree.h" | ||
| 32 | #include "xfs_alloc.h" | 28 | #include "xfs_alloc.h" |
| 33 | #include "xfs_btree.h" | ||
| 34 | #include "xfs_attr_sf.h" | ||
| 35 | #include "xfs_dir2_sf.h" | ||
| 36 | #include "xfs_dinode.h" | 29 | #include "xfs_dinode.h" |
| 37 | #include "xfs_inode.h" | 30 | #include "xfs_inode.h" |
| 38 | #include "xfs_inode_item.h" | 31 | #include "xfs_inode_item.h" |
| 39 | #include "xfs_bmap.h" | 32 | #include "xfs_bmap.h" |
| 40 | #include "xfs_error.h" | 33 | #include "xfs_error.h" |
| 41 | #include "xfs_rw.h" | ||
| 42 | #include "xfs_vnodeops.h" | 34 | #include "xfs_vnodeops.h" |
| 43 | #include "xfs_da_btree.h" | 35 | #include "xfs_da_btree.h" |
| 44 | #include "xfs_ioctl.h" | 36 | #include "xfs_ioctl.h" |
| @@ -108,7 +100,7 @@ xfs_file_fsync( | |||
| 108 | int error = 0; | 100 | int error = 0; |
| 109 | int log_flushed = 0; | 101 | int log_flushed = 0; |
| 110 | 102 | ||
| 111 | xfs_itrace_entry(ip); | 103 | trace_xfs_file_fsync(ip); |
| 112 | 104 | ||
| 113 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 105 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
| 114 | return -XFS_ERROR(EIO); | 106 | return -XFS_ERROR(EIO); |
| @@ -166,8 +158,7 @@ xfs_file_fsync( | |||
| 166 | * transaction. So we play it safe and fire off the | 158 | * transaction. So we play it safe and fire off the |
| 167 | * transaction anyway. | 159 | * transaction anyway. |
| 168 | */ | 160 | */ |
| 169 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | 161 | xfs_trans_ijoin(tp, ip); |
| 170 | xfs_trans_ihold(tp, ip); | ||
| 171 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 162 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
| 172 | xfs_trans_set_sync(tp); | 163 | xfs_trans_set_sync(tp); |
| 173 | error = _xfs_trans_commit(tp, 0, &log_flushed); | 164 | error = _xfs_trans_commit(tp, 0, &log_flushed); |
| @@ -275,20 +266,6 @@ xfs_file_aio_read( | |||
| 275 | mutex_lock(&inode->i_mutex); | 266 | mutex_lock(&inode->i_mutex); |
| 276 | xfs_ilock(ip, XFS_IOLOCK_SHARED); | 267 | xfs_ilock(ip, XFS_IOLOCK_SHARED); |
| 277 | 268 | ||
| 278 | if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) { | ||
| 279 | int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); | ||
| 280 | int iolock = XFS_IOLOCK_SHARED; | ||
| 281 | |||
| 282 | ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, ip, iocb->ki_pos, size, | ||
| 283 | dmflags, &iolock); | ||
| 284 | if (ret) { | ||
| 285 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | ||
| 286 | if (unlikely(ioflags & IO_ISDIRECT)) | ||
| 287 | mutex_unlock(&inode->i_mutex); | ||
| 288 | return ret; | ||
| 289 | } | ||
| 290 | } | ||
| 291 | |||
| 292 | if (unlikely(ioflags & IO_ISDIRECT)) { | 269 | if (unlikely(ioflags & IO_ISDIRECT)) { |
| 293 | if (inode->i_mapping->nrpages) { | 270 | if (inode->i_mapping->nrpages) { |
| 294 | ret = -xfs_flushinval_pages(ip, | 271 | ret = -xfs_flushinval_pages(ip, |
| @@ -321,7 +298,6 @@ xfs_file_splice_read( | |||
| 321 | unsigned int flags) | 298 | unsigned int flags) |
| 322 | { | 299 | { |
| 323 | struct xfs_inode *ip = XFS_I(infilp->f_mapping->host); | 300 | struct xfs_inode *ip = XFS_I(infilp->f_mapping->host); |
| 324 | struct xfs_mount *mp = ip->i_mount; | ||
| 325 | int ioflags = 0; | 301 | int ioflags = 0; |
| 326 | ssize_t ret; | 302 | ssize_t ret; |
| 327 | 303 | ||
| @@ -335,18 +311,6 @@ xfs_file_splice_read( | |||
| 335 | 311 | ||
| 336 | xfs_ilock(ip, XFS_IOLOCK_SHARED); | 312 | xfs_ilock(ip, XFS_IOLOCK_SHARED); |
| 337 | 313 | ||
| 338 | if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) { | ||
| 339 | int iolock = XFS_IOLOCK_SHARED; | ||
| 340 | int error; | ||
| 341 | |||
| 342 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, *ppos, count, | ||
| 343 | FILP_DELAY_FLAG(infilp), &iolock); | ||
| 344 | if (error) { | ||
| 345 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | ||
| 346 | return -error; | ||
| 347 | } | ||
| 348 | } | ||
| 349 | |||
| 350 | trace_xfs_file_splice_read(ip, count, *ppos, ioflags); | 314 | trace_xfs_file_splice_read(ip, count, *ppos, ioflags); |
| 351 | 315 | ||
| 352 | ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); | 316 | ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); |
| @@ -367,7 +331,6 @@ xfs_file_splice_write( | |||
| 367 | { | 331 | { |
| 368 | struct inode *inode = outfilp->f_mapping->host; | 332 | struct inode *inode = outfilp->f_mapping->host; |
| 369 | struct xfs_inode *ip = XFS_I(inode); | 333 | struct xfs_inode *ip = XFS_I(inode); |
| 370 | struct xfs_mount *mp = ip->i_mount; | ||
| 371 | xfs_fsize_t isize, new_size; | 334 | xfs_fsize_t isize, new_size; |
| 372 | int ioflags = 0; | 335 | int ioflags = 0; |
| 373 | ssize_t ret; | 336 | ssize_t ret; |
| @@ -382,18 +345,6 @@ xfs_file_splice_write( | |||
| 382 | 345 | ||
| 383 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 346 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
| 384 | 347 | ||
| 385 | if (DM_EVENT_ENABLED(ip, DM_EVENT_WRITE) && !(ioflags & IO_INVIS)) { | ||
| 386 | int iolock = XFS_IOLOCK_EXCL; | ||
| 387 | int error; | ||
| 388 | |||
| 389 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, ip, *ppos, count, | ||
| 390 | FILP_DELAY_FLAG(outfilp), &iolock); | ||
| 391 | if (error) { | ||
| 392 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
| 393 | return -error; | ||
| 394 | } | ||
| 395 | } | ||
| 396 | |||
| 397 | new_size = *ppos + count; | 348 | new_size = *ppos + count; |
| 398 | 349 | ||
| 399 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 350 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
| @@ -463,7 +414,7 @@ xfs_zero_last_block( | |||
| 463 | last_fsb = XFS_B_TO_FSBT(mp, isize); | 414 | last_fsb = XFS_B_TO_FSBT(mp, isize); |
| 464 | nimaps = 1; | 415 | nimaps = 1; |
| 465 | error = xfs_bmapi(NULL, ip, last_fsb, 1, 0, NULL, 0, &imap, | 416 | error = xfs_bmapi(NULL, ip, last_fsb, 1, 0, NULL, 0, &imap, |
| 466 | &nimaps, NULL, NULL); | 417 | &nimaps, NULL); |
| 467 | if (error) { | 418 | if (error) { |
| 468 | return error; | 419 | return error; |
| 469 | } | 420 | } |
| @@ -558,7 +509,7 @@ xfs_zero_eof( | |||
| 558 | nimaps = 1; | 509 | nimaps = 1; |
| 559 | zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; | 510 | zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; |
| 560 | error = xfs_bmapi(NULL, ip, start_zero_fsb, zero_count_fsb, | 511 | error = xfs_bmapi(NULL, ip, start_zero_fsb, zero_count_fsb, |
| 561 | 0, NULL, 0, &imap, &nimaps, NULL, NULL); | 512 | 0, NULL, 0, &imap, &nimaps, NULL); |
| 562 | if (error) { | 513 | if (error) { |
| 563 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); | 514 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); |
| 564 | return error; | 515 | return error; |
| @@ -627,7 +578,6 @@ xfs_file_aio_write( | |||
| 627 | int ioflags = 0; | 578 | int ioflags = 0; |
| 628 | xfs_fsize_t isize, new_size; | 579 | xfs_fsize_t isize, new_size; |
| 629 | int iolock; | 580 | int iolock; |
| 630 | int eventsent = 0; | ||
| 631 | size_t ocount = 0, count; | 581 | size_t ocount = 0, count; |
| 632 | int need_i_mutex; | 582 | int need_i_mutex; |
| 633 | 583 | ||
| @@ -673,33 +623,6 @@ start: | |||
| 673 | goto out_unlock_mutex; | 623 | goto out_unlock_mutex; |
| 674 | } | 624 | } |
| 675 | 625 | ||
| 676 | if ((DM_EVENT_ENABLED(ip, DM_EVENT_WRITE) && | ||
| 677 | !(ioflags & IO_INVIS) && !eventsent)) { | ||
| 678 | int dmflags = FILP_DELAY_FLAG(file); | ||
| 679 | |||
| 680 | if (need_i_mutex) | ||
| 681 | dmflags |= DM_FLAGS_IMUX; | ||
| 682 | |||
| 683 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
| 684 | error = XFS_SEND_DATA(ip->i_mount, DM_EVENT_WRITE, ip, | ||
| 685 | pos, count, dmflags, &iolock); | ||
| 686 | if (error) { | ||
| 687 | goto out_unlock_internal; | ||
| 688 | } | ||
| 689 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
| 690 | eventsent = 1; | ||
| 691 | |||
| 692 | /* | ||
| 693 | * The iolock was dropped and reacquired in XFS_SEND_DATA | ||
| 694 | * so we have to recheck the size when appending. | ||
| 695 | * We will only "goto start;" once, since having sent the | ||
| 696 | * event prevents another call to XFS_SEND_DATA, which is | ||
| 697 | * what allows the size to change in the first place. | ||
| 698 | */ | ||
| 699 | if ((file->f_flags & O_APPEND) && pos != ip->i_size) | ||
| 700 | goto start; | ||
| 701 | } | ||
| 702 | |||
| 703 | if (ioflags & IO_ISDIRECT) { | 626 | if (ioflags & IO_ISDIRECT) { |
| 704 | xfs_buftarg_t *target = | 627 | xfs_buftarg_t *target = |
| 705 | XFS_IS_REALTIME_INODE(ip) ? | 628 | XFS_IS_REALTIME_INODE(ip) ? |
| @@ -830,22 +753,6 @@ write_retry: | |||
| 830 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 753 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
| 831 | } | 754 | } |
| 832 | 755 | ||
| 833 | if (ret == -ENOSPC && | ||
| 834 | DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE) && !(ioflags & IO_INVIS)) { | ||
| 835 | xfs_iunlock(ip, iolock); | ||
| 836 | if (need_i_mutex) | ||
| 837 | mutex_unlock(&inode->i_mutex); | ||
| 838 | error = XFS_SEND_NAMESP(ip->i_mount, DM_EVENT_NOSPACE, ip, | ||
| 839 | DM_RIGHT_NULL, ip, DM_RIGHT_NULL, NULL, NULL, | ||
| 840 | 0, 0, 0); /* Delay flag intentionally unused */ | ||
| 841 | if (need_i_mutex) | ||
| 842 | mutex_lock(&inode->i_mutex); | ||
| 843 | xfs_ilock(ip, iolock); | ||
| 844 | if (error) | ||
| 845 | goto out_unlock_internal; | ||
| 846 | goto start; | ||
| 847 | } | ||
| 848 | |||
| 849 | error = -ret; | 756 | error = -ret; |
| 850 | if (ret <= 0) | 757 | if (ret <= 0) |
| 851 | goto out_unlock_internal; | 758 | goto out_unlock_internal; |
| @@ -1014,9 +921,6 @@ const struct file_operations xfs_file_operations = { | |||
| 1014 | .open = xfs_file_open, | 921 | .open = xfs_file_open, |
| 1015 | .release = xfs_file_release, | 922 | .release = xfs_file_release, |
| 1016 | .fsync = xfs_file_fsync, | 923 | .fsync = xfs_file_fsync, |
| 1017 | #ifdef HAVE_FOP_OPEN_EXEC | ||
| 1018 | .open_exec = xfs_file_open_exec, | ||
| 1019 | #endif | ||
| 1020 | }; | 924 | }; |
| 1021 | 925 | ||
| 1022 | const struct file_operations xfs_dir_file_operations = { | 926 | const struct file_operations xfs_dir_file_operations = { |
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c index b6918d76bc7b..1f279b012f94 100644 --- a/fs/xfs/linux-2.6/xfs_fs_subr.c +++ b/fs/xfs/linux-2.6/xfs_fs_subr.c | |||
| @@ -21,10 +21,6 @@ | |||
| 21 | #include "xfs_inode.h" | 21 | #include "xfs_inode.h" |
| 22 | #include "xfs_trace.h" | 22 | #include "xfs_trace.h" |
| 23 | 23 | ||
| 24 | int fs_noerr(void) { return 0; } | ||
| 25 | int fs_nosys(void) { return ENOSYS; } | ||
| 26 | void fs_noval(void) { return; } | ||
| 27 | |||
| 28 | /* | 24 | /* |
| 29 | * note: all filemap functions return negative error codes. These | 25 | * note: all filemap functions return negative error codes. These |
| 30 | * need to be inverted before returning to the xfs core functions. | 26 | * need to be inverted before returning to the xfs core functions. |
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.h b/fs/xfs/linux-2.6/xfs_fs_subr.h deleted file mode 100644 index 82bb19b2599e..000000000000 --- a/fs/xfs/linux-2.6/xfs_fs_subr.h +++ /dev/null | |||
| @@ -1,25 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. | ||
| 3 | * All Rights Reserved. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it would be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write the Free Software Foundation, | ||
| 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | #ifndef __XFS_FS_SUBR_H__ | ||
| 19 | #define __XFS_FS_SUBR_H__ | ||
| 20 | |||
| 21 | extern int fs_noerr(void); | ||
| 22 | extern int fs_nosys(void); | ||
| 23 | extern void fs_noval(void); | ||
| 24 | |||
| 25 | #endif /* __XFS_FS_SUBR_H__ */ | ||
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index e59a81062830..237f5ffb2ee8 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
| @@ -23,24 +23,15 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir2.h" | ||
| 27 | #include "xfs_alloc.h" | 26 | #include "xfs_alloc.h" |
| 28 | #include "xfs_dmapi.h" | ||
| 29 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
| 30 | #include "xfs_bmap_btree.h" | 28 | #include "xfs_bmap_btree.h" |
| 31 | #include "xfs_alloc_btree.h" | ||
| 32 | #include "xfs_ialloc_btree.h" | ||
| 33 | #include "xfs_attr_sf.h" | ||
| 34 | #include "xfs_dir2_sf.h" | ||
| 35 | #include "xfs_dinode.h" | 29 | #include "xfs_dinode.h" |
| 36 | #include "xfs_inode.h" | 30 | #include "xfs_inode.h" |
| 37 | #include "xfs_ioctl.h" | 31 | #include "xfs_ioctl.h" |
| 38 | #include "xfs_btree.h" | ||
| 39 | #include "xfs_ialloc.h" | ||
| 40 | #include "xfs_rtalloc.h" | 32 | #include "xfs_rtalloc.h" |
| 41 | #include "xfs_itable.h" | 33 | #include "xfs_itable.h" |
| 42 | #include "xfs_error.h" | 34 | #include "xfs_error.h" |
| 43 | #include "xfs_rw.h" | ||
| 44 | #include "xfs_attr.h" | 35 | #include "xfs_attr.h" |
| 45 | #include "xfs_bmap.h" | 36 | #include "xfs_bmap.h" |
| 46 | #include "xfs_buf_item.h" | 37 | #include "xfs_buf_item.h" |
| @@ -908,7 +899,7 @@ xfs_ioctl_setattr( | |||
| 908 | struct xfs_dquot *olddquot = NULL; | 899 | struct xfs_dquot *olddquot = NULL; |
| 909 | int code; | 900 | int code; |
| 910 | 901 | ||
| 911 | xfs_itrace_entry(ip); | 902 | trace_xfs_ioctl_setattr(ip); |
| 912 | 903 | ||
| 913 | if (mp->m_flags & XFS_MOUNT_RDONLY) | 904 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
| 914 | return XFS_ERROR(EROFS); | 905 | return XFS_ERROR(EROFS); |
| @@ -1043,8 +1034,7 @@ xfs_ioctl_setattr( | |||
| 1043 | } | 1034 | } |
| 1044 | } | 1035 | } |
| 1045 | 1036 | ||
| 1046 | xfs_trans_ijoin(tp, ip, lock_flags); | 1037 | xfs_trans_ijoin(tp, ip); |
| 1047 | xfs_trans_ihold(tp, ip); | ||
| 1048 | 1038 | ||
| 1049 | /* | 1039 | /* |
| 1050 | * Change file ownership. Must be the owner or privileged. | 1040 | * Change file ownership. Must be the owner or privileged. |
| @@ -1116,16 +1106,7 @@ xfs_ioctl_setattr( | |||
| 1116 | xfs_qm_dqrele(udqp); | 1106 | xfs_qm_dqrele(udqp); |
| 1117 | xfs_qm_dqrele(gdqp); | 1107 | xfs_qm_dqrele(gdqp); |
| 1118 | 1108 | ||
| 1119 | if (code) | 1109 | return code; |
| 1120 | return code; | ||
| 1121 | |||
| 1122 | if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE)) { | ||
| 1123 | XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, ip, DM_RIGHT_NULL, | ||
| 1124 | NULL, DM_RIGHT_NULL, NULL, NULL, 0, 0, | ||
| 1125 | (mask & FSX_NONBLOCK) ? DM_FLAGS_NDELAY : 0); | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | return 0; | ||
| 1129 | 1110 | ||
| 1130 | error_return: | 1111 | error_return: |
| 1131 | xfs_qm_dqrele(udqp); | 1112 | xfs_qm_dqrele(udqp); |
| @@ -1301,7 +1282,7 @@ xfs_file_ioctl( | |||
| 1301 | if (filp->f_mode & FMODE_NOCMTIME) | 1282 | if (filp->f_mode & FMODE_NOCMTIME) |
| 1302 | ioflags |= IO_INVIS; | 1283 | ioflags |= IO_INVIS; |
| 1303 | 1284 | ||
| 1304 | xfs_itrace_entry(ip); | 1285 | trace_xfs_file_ioctl(ip); |
| 1305 | 1286 | ||
| 1306 | switch (cmd) { | 1287 | switch (cmd) { |
| 1307 | case XFS_IOC_ALLOCSP: | 1288 | case XFS_IOC_ALLOCSP: |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index 52ed49e6465c..6c83f7f62dc9 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c | |||
| @@ -28,12 +28,8 @@ | |||
| 28 | #include "xfs_trans.h" | 28 | #include "xfs_trans.h" |
| 29 | #include "xfs_sb.h" | 29 | #include "xfs_sb.h" |
| 30 | #include "xfs_ag.h" | 30 | #include "xfs_ag.h" |
| 31 | #include "xfs_dir2.h" | ||
| 32 | #include "xfs_dmapi.h" | ||
| 33 | #include "xfs_mount.h" | 31 | #include "xfs_mount.h" |
| 34 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
| 35 | #include "xfs_attr_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | ||
| 37 | #include "xfs_vnode.h" | 33 | #include "xfs_vnode.h" |
| 38 | #include "xfs_dinode.h" | 34 | #include "xfs_dinode.h" |
| 39 | #include "xfs_inode.h" | 35 | #include "xfs_inode.h" |
| @@ -544,7 +540,7 @@ xfs_file_compat_ioctl( | |||
| 544 | if (filp->f_mode & FMODE_NOCMTIME) | 540 | if (filp->f_mode & FMODE_NOCMTIME) |
| 545 | ioflags |= IO_INVIS; | 541 | ioflags |= IO_INVIS; |
| 546 | 542 | ||
| 547 | xfs_itrace_entry(ip); | 543 | trace_xfs_file_compat_ioctl(ip); |
| 548 | 544 | ||
| 549 | switch (cmd) { | 545 | switch (cmd) { |
| 550 | /* No size or alignment issues on any arch */ | 546 | /* No size or alignment issues on any arch */ |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 44f0b2de153e..536b81e63a3d 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
| @@ -24,21 +24,13 @@ | |||
| 24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
| 25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
| 26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
| 27 | #include "xfs_dir2.h" | ||
| 28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
| 29 | #include "xfs_dmapi.h" | ||
| 30 | #include "xfs_quota.h" | 28 | #include "xfs_quota.h" |
| 31 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
| 32 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_alloc_btree.h" | ||
| 34 | #include "xfs_ialloc_btree.h" | ||
| 35 | #include "xfs_dir2_sf.h" | ||
| 36 | #include "xfs_attr_sf.h" | ||
| 37 | #include "xfs_dinode.h" | 31 | #include "xfs_dinode.h" |
| 38 | #include "xfs_inode.h" | 32 | #include "xfs_inode.h" |
| 39 | #include "xfs_bmap.h" | 33 | #include "xfs_bmap.h" |
| 40 | #include "xfs_btree.h" | ||
| 41 | #include "xfs_ialloc.h" | ||
| 42 | #include "xfs_rtalloc.h" | 34 | #include "xfs_rtalloc.h" |
| 43 | #include "xfs_error.h" | 35 | #include "xfs_error.h" |
| 44 | #include "xfs_itable.h" | 36 | #include "xfs_itable.h" |
| @@ -496,7 +488,7 @@ xfs_vn_getattr( | |||
| 496 | struct xfs_inode *ip = XFS_I(inode); | 488 | struct xfs_inode *ip = XFS_I(inode); |
| 497 | struct xfs_mount *mp = ip->i_mount; | 489 | struct xfs_mount *mp = ip->i_mount; |
| 498 | 490 | ||
| 499 | xfs_itrace_entry(ip); | 491 | trace_xfs_getattr(ip); |
| 500 | 492 | ||
| 501 | if (XFS_FORCED_SHUTDOWN(mp)) | 493 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 502 | return XFS_ERROR(EIO); | 494 | return XFS_ERROR(EIO); |
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index facfb323a706..998a9d7fb9c8 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h | |||
| @@ -87,7 +87,6 @@ | |||
| 87 | #include <xfs_aops.h> | 87 | #include <xfs_aops.h> |
| 88 | #include <xfs_super.h> | 88 | #include <xfs_super.h> |
| 89 | #include <xfs_globals.h> | 89 | #include <xfs_globals.h> |
| 90 | #include <xfs_fs_subr.h> | ||
| 91 | #include <xfs_buf.h> | 90 | #include <xfs_buf.h> |
| 92 | 91 | ||
| 93 | /* | 92 | /* |
diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c index 067cafbfc635..bfd5ac9d1f6f 100644 --- a/fs/xfs/linux-2.6/xfs_quotaops.c +++ b/fs/xfs/linux-2.6/xfs_quotaops.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 17 | */ | 17 | */ |
| 18 | #include "xfs.h" | 18 | #include "xfs.h" |
| 19 | #include "xfs_dmapi.h" | ||
| 20 | #include "xfs_sb.h" | 19 | #include "xfs_sb.h" |
| 21 | #include "xfs_inum.h" | 20 | #include "xfs_inum.h" |
| 22 | #include "xfs_log.h" | 21 | #include "xfs_log.h" |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 80938c736c27..758df94690ed 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
| @@ -25,14 +25,11 @@ | |||
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 27 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
| 28 | #include "xfs_dmapi.h" | ||
| 29 | #include "xfs_quota.h" | 28 | #include "xfs_quota.h" |
| 30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
| 31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
| 32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
| 33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
| 34 | #include "xfs_dir2_sf.h" | ||
| 35 | #include "xfs_attr_sf.h" | ||
| 36 | #include "xfs_dinode.h" | 33 | #include "xfs_dinode.h" |
| 37 | #include "xfs_inode.h" | 34 | #include "xfs_inode.h" |
| 38 | #include "xfs_btree.h" | 35 | #include "xfs_btree.h" |
| @@ -43,7 +40,6 @@ | |||
| 43 | #include "xfs_error.h" | 40 | #include "xfs_error.h" |
| 44 | #include "xfs_itable.h" | 41 | #include "xfs_itable.h" |
| 45 | #include "xfs_fsops.h" | 42 | #include "xfs_fsops.h" |
| 46 | #include "xfs_rw.h" | ||
| 47 | #include "xfs_attr.h" | 43 | #include "xfs_attr.h" |
| 48 | #include "xfs_buf_item.h" | 44 | #include "xfs_buf_item.h" |
| 49 | #include "xfs_utils.h" | 45 | #include "xfs_utils.h" |
| @@ -94,7 +90,6 @@ mempool_t *xfs_ioend_pool; | |||
| 94 | #define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and | 90 | #define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and |
| 95 | * unwritten extent conversion */ | 91 | * unwritten extent conversion */ |
| 96 | #define MNTOPT_NOBARRIER "nobarrier" /* .. disable */ | 92 | #define MNTOPT_NOBARRIER "nobarrier" /* .. disable */ |
| 97 | #define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */ | ||
| 98 | #define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ | 93 | #define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ |
| 99 | #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ | 94 | #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ |
| 100 | #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ | 95 | #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ |
| @@ -116,9 +111,6 @@ mempool_t *xfs_ioend_pool; | |||
| 116 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ | 111 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ |
| 117 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ | 112 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ |
| 118 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ | 113 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ |
| 119 | #define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */ | ||
| 120 | #define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */ | ||
| 121 | #define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */ | ||
| 122 | #define MNTOPT_DELAYLOG "delaylog" /* Delayed loging enabled */ | 114 | #define MNTOPT_DELAYLOG "delaylog" /* Delayed loging enabled */ |
| 123 | #define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed loging disabled */ | 115 | #define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed loging disabled */ |
| 124 | 116 | ||
| @@ -172,15 +164,13 @@ suffix_strtoul(char *s, char **endp, unsigned int base) | |||
| 172 | STATIC int | 164 | STATIC int |
| 173 | xfs_parseargs( | 165 | xfs_parseargs( |
| 174 | struct xfs_mount *mp, | 166 | struct xfs_mount *mp, |
| 175 | char *options, | 167 | char *options) |
| 176 | char **mtpt) | ||
| 177 | { | 168 | { |
| 178 | struct super_block *sb = mp->m_super; | 169 | struct super_block *sb = mp->m_super; |
| 179 | char *this_char, *value, *eov; | 170 | char *this_char, *value, *eov; |
| 180 | int dsunit = 0; | 171 | int dsunit = 0; |
| 181 | int dswidth = 0; | 172 | int dswidth = 0; |
| 182 | int iosize = 0; | 173 | int iosize = 0; |
| 183 | int dmapi_implies_ikeep = 1; | ||
| 184 | __uint8_t iosizelog = 0; | 174 | __uint8_t iosizelog = 0; |
| 185 | 175 | ||
| 186 | /* | 176 | /* |
| @@ -243,15 +233,10 @@ xfs_parseargs( | |||
| 243 | if (!mp->m_logname) | 233 | if (!mp->m_logname) |
| 244 | return ENOMEM; | 234 | return ENOMEM; |
| 245 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { | 235 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { |
| 246 | if (!value || !*value) { | 236 | cmn_err(CE_WARN, |
| 247 | cmn_err(CE_WARN, | 237 | "XFS: %s option not allowed on this system", |
| 248 | "XFS: %s option requires an argument", | 238 | this_char); |
| 249 | this_char); | 239 | return EINVAL; |
| 250 | return EINVAL; | ||
| 251 | } | ||
| 252 | *mtpt = kstrndup(value, MAXNAMELEN, GFP_KERNEL); | ||
| 253 | if (!*mtpt) | ||
| 254 | return ENOMEM; | ||
| 255 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { | 240 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { |
| 256 | if (!value || !*value) { | 241 | if (!value || !*value) { |
| 257 | cmn_err(CE_WARN, | 242 | cmn_err(CE_WARN, |
| @@ -288,8 +273,6 @@ xfs_parseargs( | |||
| 288 | mp->m_flags &= ~XFS_MOUNT_GRPID; | 273 | mp->m_flags &= ~XFS_MOUNT_GRPID; |
| 289 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { | 274 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { |
| 290 | mp->m_flags |= XFS_MOUNT_WSYNC; | 275 | mp->m_flags |= XFS_MOUNT_WSYNC; |
| 291 | } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) { | ||
| 292 | mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC; | ||
| 293 | } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { | 276 | } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { |
| 294 | mp->m_flags |= XFS_MOUNT_NORECOVERY; | 277 | mp->m_flags |= XFS_MOUNT_NORECOVERY; |
| 295 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { | 278 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { |
| @@ -329,7 +312,6 @@ xfs_parseargs( | |||
| 329 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { | 312 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { |
| 330 | mp->m_flags |= XFS_MOUNT_IKEEP; | 313 | mp->m_flags |= XFS_MOUNT_IKEEP; |
| 331 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { | 314 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { |
| 332 | dmapi_implies_ikeep = 0; | ||
| 333 | mp->m_flags &= ~XFS_MOUNT_IKEEP; | 315 | mp->m_flags &= ~XFS_MOUNT_IKEEP; |
| 334 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { | 316 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { |
| 335 | mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; | 317 | mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; |
| @@ -370,12 +352,6 @@ xfs_parseargs( | |||
| 370 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { | 352 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { |
| 371 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); | 353 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); |
| 372 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; | 354 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; |
| 373 | } else if (!strcmp(this_char, MNTOPT_DMAPI)) { | ||
| 374 | mp->m_flags |= XFS_MOUNT_DMAPI; | ||
| 375 | } else if (!strcmp(this_char, MNTOPT_XDSM)) { | ||
| 376 | mp->m_flags |= XFS_MOUNT_DMAPI; | ||
| 377 | } else if (!strcmp(this_char, MNTOPT_DMI)) { | ||
| 378 | mp->m_flags |= XFS_MOUNT_DMAPI; | ||
| 379 | } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) { | 355 | } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) { |
| 380 | mp->m_flags |= XFS_MOUNT_DELAYLOG; | 356 | mp->m_flags |= XFS_MOUNT_DELAYLOG; |
| 381 | cmn_err(CE_WARN, | 357 | cmn_err(CE_WARN, |
| @@ -387,9 +363,11 @@ xfs_parseargs( | |||
| 387 | cmn_err(CE_WARN, | 363 | cmn_err(CE_WARN, |
| 388 | "XFS: ihashsize no longer used, option is deprecated."); | 364 | "XFS: ihashsize no longer used, option is deprecated."); |
| 389 | } else if (!strcmp(this_char, "osyncisdsync")) { | 365 | } else if (!strcmp(this_char, "osyncisdsync")) { |
| 390 | /* no-op, this is now the default */ | ||
| 391 | cmn_err(CE_WARN, | 366 | cmn_err(CE_WARN, |
| 392 | "XFS: osyncisdsync is now the default, option is deprecated."); | 367 | "XFS: osyncisdsync has no effect, option is deprecated."); |
| 368 | } else if (!strcmp(this_char, "osyncisosync")) { | ||
| 369 | cmn_err(CE_WARN, | ||
| 370 | "XFS: osyncisosync has no effect, option is deprecated."); | ||
| 393 | } else if (!strcmp(this_char, "irixsgid")) { | 371 | } else if (!strcmp(this_char, "irixsgid")) { |
| 394 | cmn_err(CE_WARN, | 372 | cmn_err(CE_WARN, |
| 395 | "XFS: irixsgid is now a sysctl(2) variable, option is deprecated."); | 373 | "XFS: irixsgid is now a sysctl(2) variable, option is deprecated."); |
| @@ -430,12 +408,6 @@ xfs_parseargs( | |||
| 430 | return EINVAL; | 408 | return EINVAL; |
| 431 | } | 409 | } |
| 432 | 410 | ||
| 433 | if ((mp->m_flags & XFS_MOUNT_DMAPI) && (!*mtpt || *mtpt[0] == '\0')) { | ||
| 434 | printk("XFS: %s option needs the mount point option as well\n", | ||
| 435 | MNTOPT_DMAPI); | ||
| 436 | return EINVAL; | ||
| 437 | } | ||
| 438 | |||
| 439 | if ((dsunit && !dswidth) || (!dsunit && dswidth)) { | 411 | if ((dsunit && !dswidth) || (!dsunit && dswidth)) { |
| 440 | cmn_err(CE_WARN, | 412 | cmn_err(CE_WARN, |
| 441 | "XFS: sunit and swidth must be specified together"); | 413 | "XFS: sunit and swidth must be specified together"); |
| @@ -449,18 +421,6 @@ xfs_parseargs( | |||
| 449 | return EINVAL; | 421 | return EINVAL; |
| 450 | } | 422 | } |
| 451 | 423 | ||
| 452 | /* | ||
| 453 | * Applications using DMI filesystems often expect the | ||
| 454 | * inode generation number to be monotonically increasing. | ||
| 455 | * If we delete inode chunks we break this assumption, so | ||
| 456 | * keep unused inode chunks on disk for DMI filesystems | ||
| 457 | * until we come up with a better solution. | ||
| 458 | * Note that if "ikeep" or "noikeep" mount options are | ||
| 459 | * supplied, then they are honored. | ||
| 460 | */ | ||
| 461 | if ((mp->m_flags & XFS_MOUNT_DMAPI) && dmapi_implies_ikeep) | ||
| 462 | mp->m_flags |= XFS_MOUNT_IKEEP; | ||
| 463 | |||
| 464 | done: | 424 | done: |
| 465 | if (!(mp->m_flags & XFS_MOUNT_NOALIGN)) { | 425 | if (!(mp->m_flags & XFS_MOUNT_NOALIGN)) { |
| 466 | /* | 426 | /* |
| @@ -539,10 +499,8 @@ xfs_showargs( | |||
| 539 | { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC }, | 499 | { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC }, |
| 540 | { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, | 500 | { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, |
| 541 | { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY }, | 501 | { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY }, |
| 542 | { XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC }, | ||
| 543 | { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 }, | 502 | { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 }, |
| 544 | { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, | 503 | { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, |
| 545 | { XFS_MOUNT_DMAPI, "," MNTOPT_DMAPI }, | ||
| 546 | { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, | 504 | { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, |
| 547 | { XFS_MOUNT_DELAYLOG, "," MNTOPT_DELAYLOG }, | 505 | { XFS_MOUNT_DELAYLOG, "," MNTOPT_DELAYLOG }, |
| 548 | { 0, NULL } | 506 | { 0, NULL } |
| @@ -947,7 +905,7 @@ xfs_fs_destroy_inode( | |||
| 947 | { | 905 | { |
| 948 | struct xfs_inode *ip = XFS_I(inode); | 906 | struct xfs_inode *ip = XFS_I(inode); |
| 949 | 907 | ||
| 950 | xfs_itrace_entry(ip); | 908 | trace_xfs_destroy_inode(ip); |
| 951 | 909 | ||
| 952 | XFS_STATS_INC(vn_reclaim); | 910 | XFS_STATS_INC(vn_reclaim); |
| 953 | 911 | ||
| @@ -1063,10 +1021,8 @@ xfs_log_inode( | |||
| 1063 | * an inode in another recent transaction. So we play it safe and | 1021 | * an inode in another recent transaction. So we play it safe and |
| 1064 | * fire off the transaction anyway. | 1022 | * fire off the transaction anyway. |
| 1065 | */ | 1023 | */ |
| 1066 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | 1024 | xfs_trans_ijoin(tp, ip); |
| 1067 | xfs_trans_ihold(tp, ip); | ||
| 1068 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 1025 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
| 1069 | xfs_trans_set_sync(tp); | ||
| 1070 | error = xfs_trans_commit(tp, 0); | 1026 | error = xfs_trans_commit(tp, 0); |
| 1071 | xfs_ilock_demote(ip, XFS_ILOCK_EXCL); | 1027 | xfs_ilock_demote(ip, XFS_ILOCK_EXCL); |
| 1072 | 1028 | ||
| @@ -1082,27 +1038,18 @@ xfs_fs_write_inode( | |||
| 1082 | struct xfs_mount *mp = ip->i_mount; | 1038 | struct xfs_mount *mp = ip->i_mount; |
| 1083 | int error = EAGAIN; | 1039 | int error = EAGAIN; |
| 1084 | 1040 | ||
| 1085 | xfs_itrace_entry(ip); | 1041 | trace_xfs_write_inode(ip); |
| 1086 | 1042 | ||
| 1087 | if (XFS_FORCED_SHUTDOWN(mp)) | 1043 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 1088 | return XFS_ERROR(EIO); | 1044 | return XFS_ERROR(EIO); |
| 1089 | 1045 | ||
| 1090 | if (wbc->sync_mode == WB_SYNC_ALL) { | 1046 | if (wbc->sync_mode == WB_SYNC_ALL) { |
| 1091 | /* | 1047 | /* |
| 1092 | * Make sure the inode has hit stable storage. By using the | 1048 | * Make sure the inode has made it it into the log. Instead |
| 1093 | * log and the fsync transactions we reduce the IOs we have | 1049 | * of forcing it all the way to stable storage using a |
| 1094 | * to do here from two (log and inode) to just the log. | 1050 | * synchronous transaction we let the log force inside the |
| 1095 | * | 1051 | * ->sync_fs call do that for thus, which reduces the number |
| 1096 | * Note: We still need to do a delwri write of the inode after | 1052 | * of synchronous log foces dramatically. |
| 1097 | * this to flush it to the backing buffer so that bulkstat | ||
| 1098 | * works properly if this is the first time the inode has been | ||
| 1099 | * written. Because we hold the ilock atomically over the | ||
| 1100 | * transaction commit and the inode flush we are guaranteed | ||
| 1101 | * that the inode is not pinned when it returns. If the flush | ||
| 1102 | * lock is already held, then the inode has already been | ||
| 1103 | * flushed once and we don't need to flush it again. Hence | ||
| 1104 | * the code will only flush the inode if it isn't already | ||
| 1105 | * being flushed. | ||
| 1106 | */ | 1053 | */ |
| 1107 | xfs_ioend_wait(ip); | 1054 | xfs_ioend_wait(ip); |
| 1108 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 1055 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
| @@ -1116,27 +1063,29 @@ xfs_fs_write_inode( | |||
| 1116 | * We make this non-blocking if the inode is contended, return | 1063 | * We make this non-blocking if the inode is contended, return |
| 1117 | * EAGAIN to indicate to the caller that they did not succeed. | 1064 | * EAGAIN to indicate to the caller that they did not succeed. |
| 1118 | * This prevents the flush path from blocking on inodes inside | 1065 | * This prevents the flush path from blocking on inodes inside |
| 1119 | * another operation right now, they get caught later by xfs_sync. | 1066 | * another operation right now, they get caught later by |
| 1067 | * xfs_sync. | ||
| 1120 | */ | 1068 | */ |
| 1121 | if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) | 1069 | if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) |
| 1122 | goto out; | 1070 | goto out; |
| 1123 | } | ||
| 1124 | 1071 | ||
| 1125 | if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) | 1072 | if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) |
| 1126 | goto out_unlock; | 1073 | goto out_unlock; |
| 1127 | 1074 | ||
| 1128 | /* | 1075 | /* |
| 1129 | * Now we have the flush lock and the inode is not pinned, we can check | 1076 | * Now we have the flush lock and the inode is not pinned, we |
| 1130 | * if the inode is really clean as we know that there are no pending | 1077 | * can check if the inode is really clean as we know that |
| 1131 | * transaction completions, it is not waiting on the delayed write | 1078 | * there are no pending transaction completions, it is not |
| 1132 | * queue and there is no IO in progress. | 1079 | * waiting on the delayed write queue and there is no IO in |
| 1133 | */ | 1080 | * progress. |
| 1134 | if (xfs_inode_clean(ip)) { | 1081 | */ |
| 1135 | xfs_ifunlock(ip); | 1082 | if (xfs_inode_clean(ip)) { |
| 1136 | error = 0; | 1083 | xfs_ifunlock(ip); |
| 1137 | goto out_unlock; | 1084 | error = 0; |
| 1085 | goto out_unlock; | ||
| 1086 | } | ||
| 1087 | error = xfs_iflush(ip, 0); | ||
| 1138 | } | 1088 | } |
| 1139 | error = xfs_iflush(ip, 0); | ||
| 1140 | 1089 | ||
| 1141 | out_unlock: | 1090 | out_unlock: |
| 1142 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 1091 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
| @@ -1156,7 +1105,8 @@ xfs_fs_clear_inode( | |||
| 1156 | { | 1105 | { |
| 1157 | xfs_inode_t *ip = XFS_I(inode); | 1106 | xfs_inode_t *ip = XFS_I(inode); |
| 1158 | 1107 | ||
| 1159 | xfs_itrace_entry(ip); | 1108 | trace_xfs_clear_inode(ip); |
| 1109 | |||
| 1160 | XFS_STATS_INC(vn_rele); | 1110 | XFS_STATS_INC(vn_rele); |
| 1161 | XFS_STATS_INC(vn_remove); | 1111 | XFS_STATS_INC(vn_remove); |
| 1162 | XFS_STATS_DEC(vn_active); | 1112 | XFS_STATS_DEC(vn_active); |
| @@ -1193,22 +1143,13 @@ xfs_fs_put_super( | |||
| 1193 | { | 1143 | { |
| 1194 | struct xfs_mount *mp = XFS_M(sb); | 1144 | struct xfs_mount *mp = XFS_M(sb); |
| 1195 | 1145 | ||
| 1146 | /* | ||
| 1147 | * Unregister the memory shrinker before we tear down the mount | ||
| 1148 | * structure so we don't have memory reclaim racing with us here. | ||
| 1149 | */ | ||
| 1150 | xfs_inode_shrinker_unregister(mp); | ||
| 1196 | xfs_syncd_stop(mp); | 1151 | xfs_syncd_stop(mp); |
| 1197 | 1152 | ||
| 1198 | if (!(sb->s_flags & MS_RDONLY)) { | ||
| 1199 | /* | ||
| 1200 | * XXX(hch): this should be SYNC_WAIT. | ||
| 1201 | * | ||
| 1202 | * Or more likely not needed at all because the VFS is already | ||
| 1203 | * calling ->sync_fs after shutting down all filestem | ||
| 1204 | * operations and just before calling ->put_super. | ||
| 1205 | */ | ||
| 1206 | xfs_sync_data(mp, 0); | ||
| 1207 | xfs_sync_attr(mp, 0); | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | XFS_SEND_PREUNMOUNT(mp); | ||
| 1211 | |||
| 1212 | /* | 1153 | /* |
| 1213 | * Blow away any referenced inode in the filestreams cache. | 1154 | * Blow away any referenced inode in the filestreams cache. |
| 1214 | * This can and will cause log traffic as inodes go inactive | 1155 | * This can and will cause log traffic as inodes go inactive |
| @@ -1218,14 +1159,10 @@ xfs_fs_put_super( | |||
| 1218 | 1159 | ||
| 1219 | XFS_bflush(mp->m_ddev_targp); | 1160 | XFS_bflush(mp->m_ddev_targp); |
| 1220 | 1161 | ||
| 1221 | XFS_SEND_UNMOUNT(mp); | ||
| 1222 | |||
| 1223 | xfs_unmountfs(mp); | 1162 | xfs_unmountfs(mp); |
| 1224 | xfs_freesb(mp); | 1163 | xfs_freesb(mp); |
| 1225 | xfs_inode_shrinker_unregister(mp); | ||
| 1226 | xfs_icsb_destroy_counters(mp); | 1164 | xfs_icsb_destroy_counters(mp); |
| 1227 | xfs_close_devices(mp); | 1165 | xfs_close_devices(mp); |
| 1228 | xfs_dmops_put(mp); | ||
| 1229 | xfs_free_fsname(mp); | 1166 | xfs_free_fsname(mp); |
| 1230 | kfree(mp); | 1167 | kfree(mp); |
| 1231 | } | 1168 | } |
| @@ -1543,7 +1480,6 @@ xfs_fs_fill_super( | |||
| 1543 | struct inode *root; | 1480 | struct inode *root; |
| 1544 | struct xfs_mount *mp = NULL; | 1481 | struct xfs_mount *mp = NULL; |
| 1545 | int flags = 0, error = ENOMEM; | 1482 | int flags = 0, error = ENOMEM; |
| 1546 | char *mtpt = NULL; | ||
| 1547 | 1483 | ||
| 1548 | mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); | 1484 | mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); |
| 1549 | if (!mp) | 1485 | if (!mp) |
| @@ -1559,7 +1495,7 @@ xfs_fs_fill_super( | |||
| 1559 | mp->m_super = sb; | 1495 | mp->m_super = sb; |
| 1560 | sb->s_fs_info = mp; | 1496 | sb->s_fs_info = mp; |
| 1561 | 1497 | ||
| 1562 | error = xfs_parseargs(mp, (char *)data, &mtpt); | 1498 | error = xfs_parseargs(mp, (char *)data); |
| 1563 | if (error) | 1499 | if (error) |
| 1564 | goto out_free_fsname; | 1500 | goto out_free_fsname; |
| 1565 | 1501 | ||
| @@ -1571,16 +1507,12 @@ xfs_fs_fill_super( | |||
| 1571 | #endif | 1507 | #endif |
| 1572 | sb->s_op = &xfs_super_operations; | 1508 | sb->s_op = &xfs_super_operations; |
| 1573 | 1509 | ||
| 1574 | error = xfs_dmops_get(mp); | ||
| 1575 | if (error) | ||
| 1576 | goto out_free_fsname; | ||
| 1577 | |||
| 1578 | if (silent) | 1510 | if (silent) |
| 1579 | flags |= XFS_MFSI_QUIET; | 1511 | flags |= XFS_MFSI_QUIET; |
| 1580 | 1512 | ||
| 1581 | error = xfs_open_devices(mp); | 1513 | error = xfs_open_devices(mp); |
| 1582 | if (error) | 1514 | if (error) |
| 1583 | goto out_put_dmops; | 1515 | goto out_free_fsname; |
| 1584 | 1516 | ||
| 1585 | if (xfs_icsb_init_counters(mp)) | 1517 | if (xfs_icsb_init_counters(mp)) |
| 1586 | mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB; | 1518 | mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB; |
| @@ -1608,8 +1540,6 @@ xfs_fs_fill_super( | |||
| 1608 | if (error) | 1540 | if (error) |
| 1609 | goto out_filestream_unmount; | 1541 | goto out_filestream_unmount; |
| 1610 | 1542 | ||
| 1611 | XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, mtpt, mp->m_fsname); | ||
| 1612 | |||
| 1613 | sb->s_magic = XFS_SB_MAGIC; | 1543 | sb->s_magic = XFS_SB_MAGIC; |
| 1614 | sb->s_blocksize = mp->m_sb.sb_blocksize; | 1544 | sb->s_blocksize = mp->m_sb.sb_blocksize; |
| 1615 | sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; | 1545 | sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; |
| @@ -1638,7 +1568,6 @@ xfs_fs_fill_super( | |||
| 1638 | 1568 | ||
| 1639 | xfs_inode_shrinker_register(mp); | 1569 | xfs_inode_shrinker_register(mp); |
| 1640 | 1570 | ||
| 1641 | kfree(mtpt); | ||
| 1642 | return 0; | 1571 | return 0; |
| 1643 | 1572 | ||
| 1644 | out_filestream_unmount: | 1573 | out_filestream_unmount: |
| @@ -1648,11 +1577,8 @@ xfs_fs_fill_super( | |||
| 1648 | out_destroy_counters: | 1577 | out_destroy_counters: |
| 1649 | xfs_icsb_destroy_counters(mp); | 1578 | xfs_icsb_destroy_counters(mp); |
| 1650 | xfs_close_devices(mp); | 1579 | xfs_close_devices(mp); |
| 1651 | out_put_dmops: | ||
| 1652 | xfs_dmops_put(mp); | ||
| 1653 | out_free_fsname: | 1580 | out_free_fsname: |
| 1654 | xfs_free_fsname(mp); | 1581 | xfs_free_fsname(mp); |
| 1655 | kfree(mtpt); | ||
| 1656 | kfree(mp); | 1582 | kfree(mp); |
| 1657 | out: | 1583 | out: |
| 1658 | return -error; | 1584 | return -error; |
| @@ -1759,6 +1685,12 @@ xfs_init_zones(void) | |||
| 1759 | if (!xfs_trans_zone) | 1685 | if (!xfs_trans_zone) |
| 1760 | goto out_destroy_ifork_zone; | 1686 | goto out_destroy_ifork_zone; |
| 1761 | 1687 | ||
| 1688 | xfs_log_item_desc_zone = | ||
| 1689 | kmem_zone_init(sizeof(struct xfs_log_item_desc), | ||
| 1690 | "xfs_log_item_desc"); | ||
| 1691 | if (!xfs_log_item_desc_zone) | ||
| 1692 | goto out_destroy_trans_zone; | ||
| 1693 | |||
| 1762 | /* | 1694 | /* |
| 1763 | * The size of the zone allocated buf log item is the maximum | 1695 | * The size of the zone allocated buf log item is the maximum |
| 1764 | * size possible under XFS. This wastes a little bit of memory, | 1696 | * size possible under XFS. This wastes a little bit of memory, |
| @@ -1768,7 +1700,7 @@ xfs_init_zones(void) | |||
| 1768 | (((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) / | 1700 | (((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) / |
| 1769 | NBWORD) * sizeof(int))), "xfs_buf_item"); | 1701 | NBWORD) * sizeof(int))), "xfs_buf_item"); |
| 1770 | if (!xfs_buf_item_zone) | 1702 | if (!xfs_buf_item_zone) |
| 1771 | goto out_destroy_trans_zone; | 1703 | goto out_destroy_log_item_desc_zone; |
| 1772 | 1704 | ||
| 1773 | xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) + | 1705 | xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) + |
| 1774 | ((XFS_EFD_MAX_FAST_EXTENTS - 1) * | 1706 | ((XFS_EFD_MAX_FAST_EXTENTS - 1) * |
| @@ -1805,6 +1737,8 @@ xfs_init_zones(void) | |||
| 1805 | kmem_zone_destroy(xfs_efd_zone); | 1737 | kmem_zone_destroy(xfs_efd_zone); |
| 1806 | out_destroy_buf_item_zone: | 1738 | out_destroy_buf_item_zone: |
| 1807 | kmem_zone_destroy(xfs_buf_item_zone); | 1739 | kmem_zone_destroy(xfs_buf_item_zone); |
| 1740 | out_destroy_log_item_desc_zone: | ||
| 1741 | kmem_zone_destroy(xfs_log_item_desc_zone); | ||
| 1808 | out_destroy_trans_zone: | 1742 | out_destroy_trans_zone: |
| 1809 | kmem_zone_destroy(xfs_trans_zone); | 1743 | kmem_zone_destroy(xfs_trans_zone); |
| 1810 | out_destroy_ifork_zone: | 1744 | out_destroy_ifork_zone: |
| @@ -1835,6 +1769,7 @@ xfs_destroy_zones(void) | |||
| 1835 | kmem_zone_destroy(xfs_efi_zone); | 1769 | kmem_zone_destroy(xfs_efi_zone); |
| 1836 | kmem_zone_destroy(xfs_efd_zone); | 1770 | kmem_zone_destroy(xfs_efd_zone); |
| 1837 | kmem_zone_destroy(xfs_buf_item_zone); | 1771 | kmem_zone_destroy(xfs_buf_item_zone); |
| 1772 | kmem_zone_destroy(xfs_log_item_desc_zone); | ||
| 1838 | kmem_zone_destroy(xfs_trans_zone); | 1773 | kmem_zone_destroy(xfs_trans_zone); |
| 1839 | kmem_zone_destroy(xfs_ifork_zone); | 1774 | kmem_zone_destroy(xfs_ifork_zone); |
| 1840 | kmem_zone_destroy(xfs_dabuf_zone); | 1775 | kmem_zone_destroy(xfs_dabuf_zone); |
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h index 519618e9279e..1ef4a4d2d997 100644 --- a/fs/xfs/linux-2.6/xfs_super.h +++ b/fs/xfs/linux-2.6/xfs_super.h | |||
| @@ -56,12 +56,6 @@ extern void xfs_qm_exit(void); | |||
| 56 | # define XFS_BIGFS_STRING | 56 | # define XFS_BIGFS_STRING |
| 57 | #endif | 57 | #endif |
| 58 | 58 | ||
| 59 | #ifdef CONFIG_XFS_DMAPI | ||
| 60 | # define XFS_DMAPI_STRING "dmapi support, " | ||
| 61 | #else | ||
| 62 | # define XFS_DMAPI_STRING | ||
| 63 | #endif | ||
| 64 | |||
| 65 | #ifdef DEBUG | 59 | #ifdef DEBUG |
| 66 | # define XFS_DBG_STRING "debug" | 60 | # define XFS_DBG_STRING "debug" |
| 67 | #else | 61 | #else |
| @@ -72,7 +66,6 @@ extern void xfs_qm_exit(void); | |||
| 72 | XFS_SECURITY_STRING \ | 66 | XFS_SECURITY_STRING \ |
| 73 | XFS_REALTIME_STRING \ | 67 | XFS_REALTIME_STRING \ |
| 74 | XFS_BIGFS_STRING \ | 68 | XFS_BIGFS_STRING \ |
| 75 | XFS_DMAPI_STRING \ | ||
| 76 | XFS_DBG_STRING /* DBG must be last */ | 69 | XFS_DBG_STRING /* DBG must be last */ |
| 77 | 70 | ||
| 78 | struct xfs_inode; | 71 | struct xfs_inode; |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index a51a07c3a70c..dfcbd98d1599 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
| @@ -24,25 +24,14 @@ | |||
| 24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
| 25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
| 26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
| 27 | #include "xfs_dir2.h" | ||
| 28 | #include "xfs_dmapi.h" | ||
| 29 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
| 30 | #include "xfs_bmap_btree.h" | 28 | #include "xfs_bmap_btree.h" |
| 31 | #include "xfs_alloc_btree.h" | ||
| 32 | #include "xfs_ialloc_btree.h" | ||
| 33 | #include "xfs_btree.h" | ||
| 34 | #include "xfs_dir2_sf.h" | ||
| 35 | #include "xfs_attr_sf.h" | ||
| 36 | #include "xfs_inode.h" | 29 | #include "xfs_inode.h" |
| 37 | #include "xfs_dinode.h" | 30 | #include "xfs_dinode.h" |
| 38 | #include "xfs_error.h" | 31 | #include "xfs_error.h" |
| 39 | #include "xfs_mru_cache.h" | ||
| 40 | #include "xfs_filestream.h" | 32 | #include "xfs_filestream.h" |
| 41 | #include "xfs_vnodeops.h" | 33 | #include "xfs_vnodeops.h" |
| 42 | #include "xfs_utils.h" | ||
| 43 | #include "xfs_buf_item.h" | ||
| 44 | #include "xfs_inode_item.h" | 34 | #include "xfs_inode_item.h" |
| 45 | #include "xfs_rw.h" | ||
| 46 | #include "xfs_quota.h" | 35 | #include "xfs_quota.h" |
| 47 | #include "xfs_trace.h" | 36 | #include "xfs_trace.h" |
| 48 | 37 | ||
| @@ -319,7 +308,7 @@ xfs_sync_inode_attr( | |||
| 319 | /* | 308 | /* |
| 320 | * Write out pagecache data for the whole filesystem. | 309 | * Write out pagecache data for the whole filesystem. |
| 321 | */ | 310 | */ |
| 322 | int | 311 | STATIC int |
| 323 | xfs_sync_data( | 312 | xfs_sync_data( |
| 324 | struct xfs_mount *mp, | 313 | struct xfs_mount *mp, |
| 325 | int flags) | 314 | int flags) |
| @@ -340,7 +329,7 @@ xfs_sync_data( | |||
| 340 | /* | 329 | /* |
| 341 | * Write out inode metadata (attributes) for the whole filesystem. | 330 | * Write out inode metadata (attributes) for the whole filesystem. |
| 342 | */ | 331 | */ |
| 343 | int | 332 | STATIC int |
| 344 | xfs_sync_attr( | 333 | xfs_sync_attr( |
| 345 | struct xfs_mount *mp, | 334 | struct xfs_mount *mp, |
| 346 | int flags) | 335 | int flags) |
| @@ -373,8 +362,7 @@ xfs_commit_dummy_trans( | |||
| 373 | 362 | ||
| 374 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 363 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
| 375 | 364 | ||
| 376 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | 365 | xfs_trans_ijoin(tp, ip); |
| 377 | xfs_trans_ihold(tp, ip); | ||
| 378 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 366 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
| 379 | error = xfs_trans_commit(tp, 0); | 367 | error = xfs_trans_commit(tp, 0); |
| 380 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 368 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
| @@ -867,7 +855,36 @@ out: | |||
| 867 | reclaim: | 855 | reclaim: |
| 868 | xfs_ifunlock(ip); | 856 | xfs_ifunlock(ip); |
| 869 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 857 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
| 870 | xfs_ireclaim(ip); | 858 | |
| 859 | XFS_STATS_INC(xs_ig_reclaims); | ||
| 860 | /* | ||
| 861 | * Remove the inode from the per-AG radix tree. | ||
| 862 | * | ||
| 863 | * Because radix_tree_delete won't complain even if the item was never | ||
| 864 | * added to the tree assert that it's been there before to catch | ||
| 865 | * problems with the inode life time early on. | ||
| 866 | */ | ||
| 867 | write_lock(&pag->pag_ici_lock); | ||
| 868 | if (!radix_tree_delete(&pag->pag_ici_root, | ||
| 869 | XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino))) | ||
| 870 | ASSERT(0); | ||
| 871 | write_unlock(&pag->pag_ici_lock); | ||
| 872 | |||
| 873 | /* | ||
| 874 | * Here we do an (almost) spurious inode lock in order to coordinate | ||
| 875 | * with inode cache radix tree lookups. This is because the lookup | ||
| 876 | * can reference the inodes in the cache without taking references. | ||
| 877 | * | ||
| 878 | * We make that OK here by ensuring that we wait until the inode is | ||
| 879 | * unlocked after the lookup before we go ahead and free it. We get | ||
| 880 | * both the ilock and the iolock because the code may need to drop the | ||
| 881 | * ilock one but will still hold the iolock. | ||
| 882 | */ | ||
| 883 | xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
| 884 | xfs_qm_dqdetach(ip); | ||
| 885 | xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
| 886 | |||
| 887 | xfs_inode_free(ip); | ||
| 871 | return error; | 888 | return error; |
| 872 | 889 | ||
| 873 | } | 890 | } |
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index e28139aaa4aa..fe78726196f8 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h | |||
| @@ -35,9 +35,6 @@ typedef struct xfs_sync_work { | |||
| 35 | int xfs_syncd_init(struct xfs_mount *mp); | 35 | int xfs_syncd_init(struct xfs_mount *mp); |
| 36 | void xfs_syncd_stop(struct xfs_mount *mp); | 36 | void xfs_syncd_stop(struct xfs_mount *mp); |
| 37 | 37 | ||
| 38 | int xfs_sync_attr(struct xfs_mount *mp, int flags); | ||
| 39 | int xfs_sync_data(struct xfs_mount *mp, int flags); | ||
| 40 | |||
| 41 | int xfs_quiesce_data(struct xfs_mount *mp); | 38 | int xfs_quiesce_data(struct xfs_mount *mp); |
| 42 | void xfs_quiesce_attr(struct xfs_mount *mp); | 39 | void xfs_quiesce_attr(struct xfs_mount *mp); |
| 43 | 40 | ||
diff --git a/fs/xfs/linux-2.6/xfs_trace.c b/fs/xfs/linux-2.6/xfs_trace.c index d12be8470cba..88d25d4aa56e 100644 --- a/fs/xfs/linux-2.6/xfs_trace.c +++ b/fs/xfs/linux-2.6/xfs_trace.c | |||
| @@ -24,17 +24,13 @@ | |||
| 24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
| 25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
| 26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
| 27 | #include "xfs_dir2.h" | ||
| 28 | #include "xfs_da_btree.h" | 27 | #include "xfs_da_btree.h" |
| 29 | #include "xfs_bmap_btree.h" | 28 | #include "xfs_bmap_btree.h" |
| 30 | #include "xfs_alloc_btree.h" | 29 | #include "xfs_alloc_btree.h" |
| 31 | #include "xfs_ialloc_btree.h" | 30 | #include "xfs_ialloc_btree.h" |
| 32 | #include "xfs_dir2_sf.h" | ||
| 33 | #include "xfs_attr_sf.h" | ||
| 34 | #include "xfs_dinode.h" | 31 | #include "xfs_dinode.h" |
| 35 | #include "xfs_inode.h" | 32 | #include "xfs_inode.h" |
| 36 | #include "xfs_btree.h" | 33 | #include "xfs_btree.h" |
| 37 | #include "xfs_dmapi.h" | ||
| 38 | #include "xfs_mount.h" | 34 | #include "xfs_mount.h" |
| 39 | #include "xfs_ialloc.h" | 35 | #include "xfs_ialloc.h" |
| 40 | #include "xfs_itable.h" | 36 | #include "xfs_itable.h" |
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index 302820690904..c657cdca2cd2 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h | |||
| @@ -317,8 +317,6 @@ DEFINE_BUF_EVENT(xfs_buf_init); | |||
| 317 | DEFINE_BUF_EVENT(xfs_buf_free); | 317 | DEFINE_BUF_EVENT(xfs_buf_free); |
| 318 | DEFINE_BUF_EVENT(xfs_buf_hold); | 318 | DEFINE_BUF_EVENT(xfs_buf_hold); |
| 319 | DEFINE_BUF_EVENT(xfs_buf_rele); | 319 | DEFINE_BUF_EVENT(xfs_buf_rele); |
| 320 | DEFINE_BUF_EVENT(xfs_buf_pin); | ||
| 321 | DEFINE_BUF_EVENT(xfs_buf_unpin); | ||
| 322 | DEFINE_BUF_EVENT(xfs_buf_iodone); | 320 | DEFINE_BUF_EVENT(xfs_buf_iodone); |
| 323 | DEFINE_BUF_EVENT(xfs_buf_iorequest); | 321 | DEFINE_BUF_EVENT(xfs_buf_iorequest); |
| 324 | DEFINE_BUF_EVENT(xfs_buf_bawrite); | 322 | DEFINE_BUF_EVENT(xfs_buf_bawrite); |
| @@ -541,7 +539,7 @@ DEFINE_LOCK_EVENT(xfs_ilock_nowait); | |||
| 541 | DEFINE_LOCK_EVENT(xfs_ilock_demote); | 539 | DEFINE_LOCK_EVENT(xfs_ilock_demote); |
| 542 | DEFINE_LOCK_EVENT(xfs_iunlock); | 540 | DEFINE_LOCK_EVENT(xfs_iunlock); |
| 543 | 541 | ||
| 544 | DECLARE_EVENT_CLASS(xfs_iget_class, | 542 | DECLARE_EVENT_CLASS(xfs_inode_class, |
| 545 | TP_PROTO(struct xfs_inode *ip), | 543 | TP_PROTO(struct xfs_inode *ip), |
| 546 | TP_ARGS(ip), | 544 | TP_ARGS(ip), |
| 547 | TP_STRUCT__entry( | 545 | TP_STRUCT__entry( |
| @@ -557,16 +555,38 @@ DECLARE_EVENT_CLASS(xfs_iget_class, | |||
| 557 | __entry->ino) | 555 | __entry->ino) |
| 558 | ) | 556 | ) |
| 559 | 557 | ||
| 560 | #define DEFINE_IGET_EVENT(name) \ | 558 | #define DEFINE_INODE_EVENT(name) \ |
| 561 | DEFINE_EVENT(xfs_iget_class, name, \ | 559 | DEFINE_EVENT(xfs_inode_class, name, \ |
| 562 | TP_PROTO(struct xfs_inode *ip), \ | 560 | TP_PROTO(struct xfs_inode *ip), \ |
| 563 | TP_ARGS(ip)) | 561 | TP_ARGS(ip)) |
| 564 | DEFINE_IGET_EVENT(xfs_iget_skip); | 562 | DEFINE_INODE_EVENT(xfs_iget_skip); |
| 565 | DEFINE_IGET_EVENT(xfs_iget_reclaim); | 563 | DEFINE_INODE_EVENT(xfs_iget_reclaim); |
| 566 | DEFINE_IGET_EVENT(xfs_iget_found); | 564 | DEFINE_INODE_EVENT(xfs_iget_reclaim_fail); |
| 567 | DEFINE_IGET_EVENT(xfs_iget_alloc); | 565 | DEFINE_INODE_EVENT(xfs_iget_hit); |
| 568 | 566 | DEFINE_INODE_EVENT(xfs_iget_miss); | |
| 569 | DECLARE_EVENT_CLASS(xfs_inode_class, | 567 | |
| 568 | DEFINE_INODE_EVENT(xfs_getattr); | ||
| 569 | DEFINE_INODE_EVENT(xfs_setattr); | ||
| 570 | DEFINE_INODE_EVENT(xfs_readlink); | ||
| 571 | DEFINE_INODE_EVENT(xfs_alloc_file_space); | ||
| 572 | DEFINE_INODE_EVENT(xfs_free_file_space); | ||
| 573 | DEFINE_INODE_EVENT(xfs_readdir); | ||
| 574 | #ifdef CONFIG_XFS_POSIX_ACL | ||
| 575 | DEFINE_INODE_EVENT(xfs_check_acl); | ||
| 576 | #endif | ||
| 577 | DEFINE_INODE_EVENT(xfs_vm_bmap); | ||
| 578 | DEFINE_INODE_EVENT(xfs_file_ioctl); | ||
| 579 | DEFINE_INODE_EVENT(xfs_file_compat_ioctl); | ||
| 580 | DEFINE_INODE_EVENT(xfs_ioctl_setattr); | ||
| 581 | DEFINE_INODE_EVENT(xfs_file_fsync); | ||
| 582 | DEFINE_INODE_EVENT(xfs_destroy_inode); | ||
| 583 | DEFINE_INODE_EVENT(xfs_write_inode); | ||
| 584 | DEFINE_INODE_EVENT(xfs_clear_inode); | ||
| 585 | |||
| 586 | DEFINE_INODE_EVENT(xfs_dquot_dqalloc); | ||
| 587 | DEFINE_INODE_EVENT(xfs_dquot_dqdetach); | ||
| 588 | |||
| 589 | DECLARE_EVENT_CLASS(xfs_iref_class, | ||
| 570 | TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), | 590 | TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), |
| 571 | TP_ARGS(ip, caller_ip), | 591 | TP_ARGS(ip, caller_ip), |
| 572 | TP_STRUCT__entry( | 592 | TP_STRUCT__entry( |
| @@ -591,20 +611,71 @@ DECLARE_EVENT_CLASS(xfs_inode_class, | |||
| 591 | (char *)__entry->caller_ip) | 611 | (char *)__entry->caller_ip) |
| 592 | ) | 612 | ) |
| 593 | 613 | ||
| 594 | #define DEFINE_INODE_EVENT(name) \ | 614 | #define DEFINE_IREF_EVENT(name) \ |
| 595 | DEFINE_EVENT(xfs_inode_class, name, \ | 615 | DEFINE_EVENT(xfs_iref_class, name, \ |
| 596 | TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), \ | 616 | TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), \ |
| 597 | TP_ARGS(ip, caller_ip)) | 617 | TP_ARGS(ip, caller_ip)) |
| 598 | DEFINE_INODE_EVENT(xfs_ihold); | 618 | DEFINE_IREF_EVENT(xfs_ihold); |
| 599 | DEFINE_INODE_EVENT(xfs_irele); | 619 | DEFINE_IREF_EVENT(xfs_irele); |
| 600 | DEFINE_INODE_EVENT(xfs_inode_pin); | 620 | DEFINE_IREF_EVENT(xfs_inode_pin); |
| 601 | DEFINE_INODE_EVENT(xfs_inode_unpin); | 621 | DEFINE_IREF_EVENT(xfs_inode_unpin); |
| 602 | DEFINE_INODE_EVENT(xfs_inode_unpin_nowait); | 622 | DEFINE_IREF_EVENT(xfs_inode_unpin_nowait); |
| 623 | |||
| 624 | DECLARE_EVENT_CLASS(xfs_namespace_class, | ||
| 625 | TP_PROTO(struct xfs_inode *dp, struct xfs_name *name), | ||
| 626 | TP_ARGS(dp, name), | ||
| 627 | TP_STRUCT__entry( | ||
| 628 | __field(dev_t, dev) | ||
| 629 | __field(xfs_ino_t, dp_ino) | ||
| 630 | __dynamic_array(char, name, name->len) | ||
| 631 | ), | ||
| 632 | TP_fast_assign( | ||
| 633 | __entry->dev = VFS_I(dp)->i_sb->s_dev; | ||
| 634 | __entry->dp_ino = dp->i_ino; | ||
| 635 | memcpy(__get_str(name), name->name, name->len); | ||
| 636 | ), | ||
| 637 | TP_printk("dev %d:%d dp ino 0x%llx name %s", | ||
| 638 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
| 639 | __entry->dp_ino, | ||
| 640 | __get_str(name)) | ||
| 641 | ) | ||
| 603 | 642 | ||
| 604 | /* the old xfs_itrace_entry tracer - to be replaced by s.th. in the VFS */ | 643 | #define DEFINE_NAMESPACE_EVENT(name) \ |
| 605 | DEFINE_INODE_EVENT(xfs_inode); | 644 | DEFINE_EVENT(xfs_namespace_class, name, \ |
| 606 | #define xfs_itrace_entry(ip) \ | 645 | TP_PROTO(struct xfs_inode *dp, struct xfs_name *name), \ |
| 607 | trace_xfs_inode(ip, _THIS_IP_) | 646 | TP_ARGS(dp, name)) |
| 647 | DEFINE_NAMESPACE_EVENT(xfs_remove); | ||
| 648 | DEFINE_NAMESPACE_EVENT(xfs_link); | ||
| 649 | DEFINE_NAMESPACE_EVENT(xfs_lookup); | ||
| 650 | DEFINE_NAMESPACE_EVENT(xfs_create); | ||
| 651 | DEFINE_NAMESPACE_EVENT(xfs_symlink); | ||
| 652 | |||
| 653 | TRACE_EVENT(xfs_rename, | ||
| 654 | TP_PROTO(struct xfs_inode *src_dp, struct xfs_inode *target_dp, | ||
| 655 | struct xfs_name *src_name, struct xfs_name *target_name), | ||
| 656 | TP_ARGS(src_dp, target_dp, src_name, target_name), | ||
| 657 | TP_STRUCT__entry( | ||
| 658 | __field(dev_t, dev) | ||
| 659 | __field(xfs_ino_t, src_dp_ino) | ||
| 660 | __field(xfs_ino_t, target_dp_ino) | ||
| 661 | __dynamic_array(char, src_name, src_name->len) | ||
| 662 | __dynamic_array(char, target_name, target_name->len) | ||
| 663 | ), | ||
| 664 | TP_fast_assign( | ||
| 665 | __entry->dev = VFS_I(src_dp)->i_sb->s_dev; | ||
| 666 | __entry->src_dp_ino = src_dp->i_ino; | ||
| 667 | __entry->target_dp_ino = target_dp->i_ino; | ||
| 668 | memcpy(__get_str(src_name), src_name->name, src_name->len); | ||
| 669 | memcpy(__get_str(target_name), target_name->name, target_name->len); | ||
| 670 | ), | ||
| 671 | TP_printk("dev %d:%d src dp ino 0x%llx target dp ino 0x%llx" | ||
| 672 | " src name %s target name %s", | ||
| 673 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
| 674 | __entry->src_dp_ino, | ||
| 675 | __entry->target_dp_ino, | ||
| 676 | __get_str(src_name), | ||
| 677 | __get_str(target_name)) | ||
| 678 | ) | ||
| 608 | 679 | ||
| 609 | DECLARE_EVENT_CLASS(xfs_dquot_class, | 680 | DECLARE_EVENT_CLASS(xfs_dquot_class, |
| 610 | TP_PROTO(struct xfs_dquot *dqp), | 681 | TP_PROTO(struct xfs_dquot *dqp), |
| @@ -684,9 +755,6 @@ DEFINE_DQUOT_EVENT(xfs_dqrele); | |||
| 684 | DEFINE_DQUOT_EVENT(xfs_dqflush); | 755 | DEFINE_DQUOT_EVENT(xfs_dqflush); |
| 685 | DEFINE_DQUOT_EVENT(xfs_dqflush_force); | 756 | DEFINE_DQUOT_EVENT(xfs_dqflush_force); |
| 686 | DEFINE_DQUOT_EVENT(xfs_dqflush_done); | 757 | DEFINE_DQUOT_EVENT(xfs_dqflush_done); |
| 687 | /* not really iget events, but we re-use the format */ | ||
| 688 | DEFINE_IGET_EVENT(xfs_dquot_dqalloc); | ||
| 689 | DEFINE_IGET_EVENT(xfs_dquot_dqdetach); | ||
| 690 | 758 | ||
| 691 | DECLARE_EVENT_CLASS(xfs_loggrant_class, | 759 | DECLARE_EVENT_CLASS(xfs_loggrant_class, |
| 692 | TP_PROTO(struct log *log, struct xlog_ticket *tic), | 760 | TP_PROTO(struct log *log, struct xlog_ticket *tic), |
| @@ -834,33 +902,29 @@ DECLARE_EVENT_CLASS(xfs_page_class, | |||
| 834 | __field(loff_t, size) | 902 | __field(loff_t, size) |
| 835 | __field(unsigned long, offset) | 903 | __field(unsigned long, offset) |
| 836 | __field(int, delalloc) | 904 | __field(int, delalloc) |
| 837 | __field(int, unmapped) | ||
| 838 | __field(int, unwritten) | 905 | __field(int, unwritten) |
| 839 | ), | 906 | ), |
| 840 | TP_fast_assign( | 907 | TP_fast_assign( |
| 841 | int delalloc = -1, unmapped = -1, unwritten = -1; | 908 | int delalloc = -1, unwritten = -1; |
| 842 | 909 | ||
| 843 | if (page_has_buffers(page)) | 910 | if (page_has_buffers(page)) |
| 844 | xfs_count_page_state(page, &delalloc, | 911 | xfs_count_page_state(page, &delalloc, &unwritten); |
| 845 | &unmapped, &unwritten); | ||
| 846 | __entry->dev = inode->i_sb->s_dev; | 912 | __entry->dev = inode->i_sb->s_dev; |
| 847 | __entry->ino = XFS_I(inode)->i_ino; | 913 | __entry->ino = XFS_I(inode)->i_ino; |
| 848 | __entry->pgoff = page_offset(page); | 914 | __entry->pgoff = page_offset(page); |
| 849 | __entry->size = i_size_read(inode); | 915 | __entry->size = i_size_read(inode); |
| 850 | __entry->offset = off; | 916 | __entry->offset = off; |
| 851 | __entry->delalloc = delalloc; | 917 | __entry->delalloc = delalloc; |
| 852 | __entry->unmapped = unmapped; | ||
| 853 | __entry->unwritten = unwritten; | 918 | __entry->unwritten = unwritten; |
| 854 | ), | 919 | ), |
| 855 | TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx " | 920 | TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx " |
| 856 | "delalloc %d unmapped %d unwritten %d", | 921 | "delalloc %d unwritten %d", |
| 857 | MAJOR(__entry->dev), MINOR(__entry->dev), | 922 | MAJOR(__entry->dev), MINOR(__entry->dev), |
| 858 | __entry->ino, | 923 | __entry->ino, |
| 859 | __entry->pgoff, | 924 | __entry->pgoff, |
| 860 | __entry->size, | 925 | __entry->size, |
| 861 | __entry->offset, | 926 | __entry->offset, |
| 862 | __entry->delalloc, | 927 | __entry->delalloc, |
| 863 | __entry->unmapped, | ||
| 864 | __entry->unwritten) | 928 | __entry->unwritten) |
| 865 | ) | 929 | ) |
| 866 | 930 | ||
