diff options
Diffstat (limited to 'fs/gfs2/aops.c')
-rw-r--r-- | fs/gfs2/aops.c | 65 |
1 files changed, 25 insertions, 40 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 68ed06962537..f58716567972 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -39,18 +39,21 @@ static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, - unsigned int from, unsigned int to) + unsigned int from, unsigned int len) { struct buffer_head *head = page_buffers(page); unsigned int bsize = head->b_size; struct buffer_head *bh; + unsigned int to = from + len; unsigned int start, end; for (bh = head, start = 0; bh != head || !start; bh = bh->b_this_page, start = end) { end = start + bsize; - if (end <= from || start >= to) + if (end <= from) continue; + if (start >= to) + break; if (gfs2_is_jdata(ip)) set_buffer_uptodate(bh); gfs2_trans_add_data(ip->i_gl, bh); @@ -189,7 +192,7 @@ static int __gfs2_jdata_writepage(struct page *page, struct writeback_control *w create_empty_buffers(page, inode->i_sb->s_blocksize, BIT(BH_Dirty)|BIT(BH_Uptodate)); } - gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize-1); + gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize); } return gfs2_write_full_page(page, gfs2_get_block_noalloc, wbc); } @@ -255,7 +258,6 @@ static int gfs2_writepages(struct address_space *mapping, * @wbc: The writeback control * @pvec: The vector of pages * @nr_pages: The number of pages to write - * @end: End position * @done_index: Page index * * Returns: non-zero if loop should terminate, zero otherwise @@ -264,7 +266,7 @@ static int gfs2_writepages(struct address_space *mapping, static int gfs2_write_jdata_pagevec(struct address_space *mapping, struct writeback_control *wbc, struct pagevec *pvec, - int nr_pages, pgoff_t end, + int nr_pages, pgoff_t *done_index) { struct inode *inode = mapping->host; @@ -280,22 +282,6 @@ static int gfs2_write_jdata_pagevec(struct address_space *mapping, for(i = 0; i < nr_pages; i++) { struct page *page = pvec->pages[i]; - /* - * At this point, the page may be truncated or - * invalidated (changing page->mapping to NULL), or - * even swizzled back from swapper_space to tmpfs file - * mapping. However, page->index will not change - * because we have a reference on the page. - */ - if (page->index > end) { - /* - * can't be range_cyclic (1st pass) because - * end == -1 in that case. - */ - ret = 1; - break; - } - *done_index = page->index; lock_page(page); @@ -387,7 +373,7 @@ static int gfs2_write_cache_jdata(struct address_space *mapping, int range_whole = 0; int tag; - pagevec_init(&pvec, 0); + pagevec_init(&pvec); if (wbc->range_cyclic) { writeback_index = mapping->writeback_index; /* prev offset */ index = writeback_index; @@ -413,12 +399,12 @@ retry: tag_pages_for_writeback(mapping, index, end); done_index = index; while (!done && (index <= end)) { - nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag, - min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1); + nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end, + tag); if (nr_pages == 0) break; - ret = gfs2_write_jdata_pagevec(mapping, wbc, &pvec, nr_pages, end, &done_index); + ret = gfs2_write_jdata_pagevec(mapping, wbc, &pvec, nr_pages, &done_index); if (ret) done = 1; if (ret > 0) @@ -462,7 +448,8 @@ static int gfs2_jdata_writepages(struct address_space *mapping, ret = gfs2_write_cache_jdata(mapping, wbc); if (ret == 0 && wbc->sync_mode == WB_SYNC_ALL) { - gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH); + gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_JDATA_WPAGES); ret = gfs2_write_cache_jdata(mapping, wbc); } return ret; @@ -499,8 +486,8 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) return error; kaddr = kmap_atomic(page); - if (dsize > (dibh->b_size - sizeof(struct gfs2_dinode))) - dsize = (dibh->b_size - sizeof(struct gfs2_dinode)); + if (dsize > gfs2_max_stuffed_size(ip)) + dsize = gfs2_max_stuffed_size(ip); memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize); memset(kaddr + dsize, 0, PAGE_SIZE - dsize); kunmap_atomic(kaddr); @@ -517,10 +504,9 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) * @file: The file to read a page for * @page: The page to read * - * This is the core of gfs2's readpage. Its used by the internal file - * reading code as in that case we already hold the glock. Also its + * This is the core of gfs2's readpage. It's used by the internal file + * reading code as in that case we already hold the glock. Also it's * called by gfs2_readpage() once the required lock has been granted. - * */ static int __gfs2_readpage(void *file, struct page *page) @@ -741,7 +727,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, if (gfs2_is_stuffed(ip)) { error = 0; - if (pos + len > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) { + if (pos + len > gfs2_max_stuffed_size(ip)) { error = gfs2_unstuff_dinode(ip, page); if (error == 0) goto prepare_write; @@ -848,7 +834,8 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh, void *kaddr; unsigned char *buf = dibh->b_data + sizeof(struct gfs2_dinode); - BUG_ON((pos + len) > (dibh->b_size - sizeof(struct gfs2_dinode))); + BUG_ON(pos + len > gfs2_max_stuffed_size(ip)); + kaddr = kmap_atomic(page); memcpy(buf + pos, kaddr + pos, copied); flush_dcache_page(page); @@ -906,8 +893,6 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); struct buffer_head *dibh; - unsigned int from = pos & (PAGE_SIZE - 1); - unsigned int to = from + len; int ret; struct gfs2_trans *tr = current->journal_info; BUG_ON(!tr); @@ -925,7 +910,7 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, return gfs2_stuffed_write_end(inode, dibh, pos, len, copied, page); if (!gfs2_is_writeback(ip)) - gfs2_page_add_databufs(ip, page, from, to); + gfs2_page_add_databufs(ip, page, pos & ~PAGE_MASK, len); ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); if (tr->tr_num_buf_new) @@ -955,13 +940,13 @@ failed: } /** - * gfs2_set_page_dirty - Page dirtying function + * jdata_set_page_dirty - Page dirtying function * @page: The page to dirty * * Returns: 1 if it dirtyed the page, or 0 otherwise */ -static int gfs2_set_page_dirty(struct page *page) +static int jdata_set_page_dirty(struct page *page) { SetPageChecked(page); return __set_page_dirty_buffers(page); @@ -1229,7 +1214,7 @@ static const struct address_space_operations gfs2_ordered_aops = { .readpages = gfs2_readpages, .write_begin = gfs2_write_begin, .write_end = gfs2_write_end, - .set_page_dirty = gfs2_set_page_dirty, + .set_page_dirty = __set_page_dirty_buffers, .bmap = gfs2_bmap, .invalidatepage = gfs2_invalidatepage, .releasepage = gfs2_releasepage, @@ -1246,7 +1231,7 @@ static const struct address_space_operations gfs2_jdata_aops = { .readpages = gfs2_readpages, .write_begin = gfs2_write_begin, .write_end = gfs2_write_end, - .set_page_dirty = gfs2_set_page_dirty, + .set_page_dirty = jdata_set_page_dirty, .bmap = gfs2_bmap, .invalidatepage = gfs2_invalidatepage, .releasepage = gfs2_releasepage, |