aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c68
-rw-r--r--fs/xfs/xfs_iomap.c20
-rw-r--r--fs/xfs/xfs_iomap.h7
-rw-r--r--fs/xfs/xfs_mount.h7
4 files changed, 56 insertions, 46 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 1edd3b694332..9278e9aba9ba 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -558,7 +558,8 @@ xfs_submit_page(
558 int i; 558 int i;
559 559
560 BUG_ON(PageWriteback(page)); 560 BUG_ON(PageWriteback(page));
561 set_page_writeback(page); 561 if (bh_count)
562 set_page_writeback(page);
562 if (clear_dirty) 563 if (clear_dirty)
563 clear_page_dirty(page); 564 clear_page_dirty(page);
564 unlock_page(page); 565 unlock_page(page);
@@ -578,9 +579,6 @@ xfs_submit_page(
578 579
579 if (probed_page && clear_dirty) 580 if (probed_page && clear_dirty)
580 wbc->nr_to_write--; /* Wrote an "extra" page */ 581 wbc->nr_to_write--; /* Wrote an "extra" page */
581 } else {
582 end_page_writeback(page);
583 wbc->pages_skipped++; /* We didn't write this page */
584 } 582 }
585} 583}
586 584
@@ -602,21 +600,26 @@ xfs_convert_page(
602{ 600{
603 struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head; 601 struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
604 xfs_iomap_t *mp = iomapp, *tmp; 602 xfs_iomap_t *mp = iomapp, *tmp;
605 unsigned long end, offset; 603 unsigned long offset, end_offset;
606 pgoff_t end_index; 604 int index = 0;
607 int i = 0, index = 0;
608 int bbits = inode->i_blkbits; 605 int bbits = inode->i_blkbits;
606 int len, page_dirty;
609 607
610 end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT; 608 end_offset = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1));
611 if (page->index < end_index) { 609
612 end = PAGE_CACHE_SIZE; 610 /*
613 } else { 611 * page_dirty is initially a count of buffers on the page before
614 end = i_size_read(inode) & (PAGE_CACHE_SIZE-1); 612 * EOF and is decrememted as we move each into a cleanable state.
615 } 613 */
614 len = 1 << inode->i_blkbits;
615 end_offset = max(end_offset, PAGE_CACHE_SIZE);
616 end_offset = roundup(end_offset, len);
617 page_dirty = end_offset / len;
618
619 offset = 0;
616 bh = head = page_buffers(page); 620 bh = head = page_buffers(page);
617 do { 621 do {
618 offset = i << bbits; 622 if (offset >= end_offset)
619 if (offset >= end)
620 break; 623 break;
621 if (!(PageUptodate(page) || buffer_uptodate(bh))) 624 if (!(PageUptodate(page) || buffer_uptodate(bh)))
622 continue; 625 continue;
@@ -625,6 +628,7 @@ xfs_convert_page(
625 if (startio) { 628 if (startio) {
626 lock_buffer(bh); 629 lock_buffer(bh);
627 bh_arr[index++] = bh; 630 bh_arr[index++] = bh;
631 page_dirty--;
628 } 632 }
629 continue; 633 continue;
630 } 634 }
@@ -657,10 +661,11 @@ xfs_convert_page(
657 unlock_buffer(bh); 661 unlock_buffer(bh);
658 mark_buffer_dirty(bh); 662 mark_buffer_dirty(bh);
659 } 663 }
660 } while (i++, (bh = bh->b_this_page) != head); 664 page_dirty--;
665 } while (offset += len, (bh = bh->b_this_page) != head);
661 666
662 if (startio) { 667 if (startio && index) {
663 xfs_submit_page(page, wbc, bh_arr, index, 1, index == i); 668 xfs_submit_page(page, wbc, bh_arr, index, 1, !page_dirty);
664 } else { 669 } else {
665 unlock_page(page); 670 unlock_page(page);
666 } 671 }
@@ -743,19 +748,22 @@ xfs_page_state_convert(
743 } 748 }
744 } 749 }
745 750
746 offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
747 end_offset = min_t(unsigned long long, 751 end_offset = min_t(unsigned long long,
748 offset + PAGE_CACHE_SIZE, i_size_read(inode)); 752 (loff_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset);
749 753 offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
750 bh = head = page_buffers(page);
751 iomp = NULL;
752 754
753 /* 755 /*
754 * page_dirty is initially a count of buffers on the page and 756 * page_dirty is initially a count of buffers on the page before
755 * is decrememted as we move each into a cleanable state. 757 * EOF and is decrememted as we move each into a cleanable state.
756 */ 758 */
757 len = bh->b_size; 759 len = 1 << inode->i_blkbits;
758 page_dirty = PAGE_CACHE_SIZE / len; 760 p_offset = max(p_offset, PAGE_CACHE_SIZE);
761 p_offset = roundup(p_offset, len);
762 page_dirty = p_offset / len;
763
764 iomp = NULL;
765 p_offset = 0;
766 bh = head = page_buffers(page);
759 767
760 do { 768 do {
761 if (offset >= end_offset) 769 if (offset >= end_offset)
@@ -877,8 +885,10 @@ xfs_page_state_convert(
877 if (uptodate && bh == head) 885 if (uptodate && bh == head)
878 SetPageUptodate(page); 886 SetPageUptodate(page);
879 887
880 if (startio) 888 if (startio) {
881 xfs_submit_page(page, wbc, bh_arr, cnt, 0, 1); 889 WARN_ON(page_dirty);
890 xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty);
891 }
882 892
883 if (iomp) { 893 if (iomp) {
884 offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >> 894 offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >>
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 3826e8f0e28a..b291a2b53579 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -308,7 +308,8 @@ phase2:
308 break; 308 break;
309 } 309 }
310 310
311 error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps); 311 error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count,
312 &imap, &nimaps);
312 break; 313 break;
313 case BMAPI_UNWRITTEN: 314 case BMAPI_UNWRITTEN:
314 lockmode = 0; 315 lockmode = 0;
@@ -746,6 +747,8 @@ write_map:
746int 747int
747xfs_iomap_write_allocate( 748xfs_iomap_write_allocate(
748 xfs_inode_t *ip, 749 xfs_inode_t *ip,
750 loff_t offset,
751 size_t count,
749 xfs_bmbt_irec_t *map, 752 xfs_bmbt_irec_t *map,
750 int *retmap) 753 int *retmap)
751{ 754{
@@ -770,9 +773,9 @@ xfs_iomap_write_allocate(
770 if ((error = XFS_QM_DQATTACH(mp, ip, 0))) 773 if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
771 return XFS_ERROR(error); 774 return XFS_ERROR(error);
772 775
773 offset_fsb = map->br_startoff; 776 offset_fsb = XFS_B_TO_FSBT(mp, offset);
774 count_fsb = map->br_blockcount; 777 count_fsb = map->br_blockcount;
775 map_start_fsb = offset_fsb; 778 map_start_fsb = map->br_startoff;
776 779
777 XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); 780 XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
778 781
@@ -868,9 +871,9 @@ xfs_iomap_write_allocate(
868 imap[i].br_startoff, 871 imap[i].br_startoff,
869 imap[i].br_blockcount,imap[i].br_state); 872 imap[i].br_blockcount,imap[i].br_state);
870 } 873 }
871 if ((map->br_startoff >= imap[i].br_startoff) && 874 if ((offset_fsb >= imap[i].br_startoff) &&
872 (map->br_startoff < (imap[i].br_startoff + 875 (offset_fsb < (imap[i].br_startoff +
873 imap[i].br_blockcount))) { 876 imap[i].br_blockcount))) {
874 *map = imap[i]; 877 *map = imap[i];
875 *retmap = 1; 878 *retmap = 1;
876 XFS_STATS_INC(xs_xstrat_quick); 879 XFS_STATS_INC(xs_xstrat_quick);
@@ -883,9 +886,8 @@ xfs_iomap_write_allocate(
883 * file, just surrounding data, try again. 886 * file, just surrounding data, try again.
884 */ 887 */
885 nimaps--; 888 nimaps--;
886 offset_fsb = imap[nimaps].br_startoff + 889 map_start_fsb = imap[nimaps].br_startoff +
887 imap[nimaps].br_blockcount; 890 imap[nimaps].br_blockcount;
888 map_start_fsb = offset_fsb;
889 } 891 }
890 892
891trans_cancel: 893trans_cancel:
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index 31c91087cb33..287895a3adc1 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -29,9 +29,6 @@
29 * 29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ 30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */ 31 */
32
33
34
35#ifndef __XFS_IOMAP_H__ 32#ifndef __XFS_IOMAP_H__
36#define __XFS_IOMAP_H__ 33#define __XFS_IOMAP_H__
37 34
@@ -56,7 +53,7 @@ typedef enum {
56 BMAPI_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */ 53 BMAPI_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */
57 /* modifiers */ 54 /* modifiers */
58 BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */ 55 BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */
59 BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ 56 BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */
60 BMAPI_MMAP = (1 << 6), /* allocate for mmap write */ 57 BMAPI_MMAP = (1 << 6), /* allocate for mmap write */
61 BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */ 58 BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */
62 BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */ 59 BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */
@@ -100,7 +97,7 @@ extern int xfs_iomap_write_direct(struct xfs_inode *, loff_t, size_t,
100 int, struct xfs_bmbt_irec *, int *, int); 97 int, struct xfs_bmbt_irec *, int *, int);
101extern int xfs_iomap_write_delay(struct xfs_inode *, loff_t, size_t, int, 98extern int xfs_iomap_write_delay(struct xfs_inode *, loff_t, size_t, int,
102 struct xfs_bmbt_irec *, int *); 99 struct xfs_bmbt_irec *, int *);
103extern int xfs_iomap_write_allocate(struct xfs_inode *, 100extern int xfs_iomap_write_allocate(struct xfs_inode *, loff_t, size_t,
104 struct xfs_bmbt_irec *, int *); 101 struct xfs_bmbt_irec *, int *);
105extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t); 102extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t);
106 103
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 1b968471ec8b..8ffb65dc110d 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -216,7 +216,8 @@ typedef int (*xfs_iomap_write_delay_t)(
216 void *, loff_t, size_t, int, 216 void *, loff_t, size_t, int,
217 struct xfs_bmbt_irec *, int *); 217 struct xfs_bmbt_irec *, int *);
218typedef int (*xfs_iomap_write_allocate_t)( 218typedef int (*xfs_iomap_write_allocate_t)(
219 void *, struct xfs_bmbt_irec *, int *); 219 void *, loff_t, size_t,
220 struct xfs_bmbt_irec *, int *);
220typedef int (*xfs_iomap_write_unwritten_t)( 221typedef int (*xfs_iomap_write_unwritten_t)(
221 void *, loff_t, size_t); 222 void *, loff_t, size_t);
222typedef uint (*xfs_lck_map_shared_t)(void *); 223typedef uint (*xfs_lck_map_shared_t)(void *);
@@ -258,9 +259,9 @@ typedef struct xfs_ioops {
258#define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \ 259#define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \
259 (*(mp)->m_io_ops.xfs_iomap_write_delay) \ 260 (*(mp)->m_io_ops.xfs_iomap_write_delay) \
260 ((io)->io_obj, offset, count, flags, mval, nmap) 261 ((io)->io_obj, offset, count, flags, mval, nmap)
261#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, mval, nmap) \ 262#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, mval, nmap) \
262 (*(mp)->m_io_ops.xfs_iomap_write_allocate) \ 263 (*(mp)->m_io_ops.xfs_iomap_write_allocate) \
263 ((io)->io_obj, mval, nmap) 264 ((io)->io_obj, offset, count, mval, nmap)
264#define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \ 265#define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \
265 (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \ 266 (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \
266 ((io)->io_obj, offset, count) 267 ((io)->io_obj, offset, count)