static void gfs2_invalidatepage(struct page *page, unsigned int offset, unsigned int length) { struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); unsigned int stop = offset + length; int partial_page = (offset || length < PAGE_CACHE_SIZE); struct buffer_head *bh, *head; unsigned long pos = 0; BUG_ON(!PageLocked(page)); if (!partial_page) ClearPageChecked(page); if (!page_has_buffers(page)) goto out; bh = head = page_buffers(page); do { if (pos + bh->b_size > stop) return; if (offset <= pos) gfs2_discard(sdp, bh); pos += bh->b_size; bh = bh->b_this_page; } while (bh != head); out: if (!partial_page) try_to_release_page(page, 0); }
/* * after copy_from_user, pages need to be dirtied and we need to make * sure holes are created between the current EOF and the start of * any next extents (if required). * * this also makes the decision about creating an inline extent vs * doing real data extents, marking pages dirty and delalloc as required. */ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct file *file, struct page **pages, size_t num_pages, loff_t pos, size_t write_bytes) { int err = 0; int i; struct inode *inode = fdentry(file)->d_inode; struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; u64 hint_byte; u64 num_bytes; u64 start_pos; u64 end_of_last_block; u64 end_pos = pos + write_bytes; loff_t isize = i_size_read(inode); start_pos = pos & ~((u64)root->sectorsize - 1); num_bytes = (write_bytes + pos - start_pos + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); end_of_last_block = start_pos + num_bytes - 1; lock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS); trans = btrfs_join_transaction(root, 1); if (!trans) { err = -ENOMEM; goto out_unlock; } btrfs_set_trans_block_group(trans, inode); hint_byte = 0; set_extent_uptodate(io_tree, start_pos, end_of_last_block, GFP_NOFS); /* check for reserved extents on each page, we don't want * to reset the delalloc bit on things that already have * extents reserved. */ btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block); for (i = 0; i < num_pages; i++) { struct page *p = pages[i]; SetPageUptodate(p); ClearPageChecked(p); set_page_dirty(p); } if (end_pos > isize) { i_size_write(inode, end_pos); /* we've only changed i_size in ram, and we haven't updated * the disk i_size. There is no need to log the inode * at this time. */ } err = btrfs_end_transaction(trans, root); out_unlock: unlock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS); return err; }
static int __gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc) { struct inode *inode = page->mapping->host; struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_sbd *sdp = GFS2_SB(inode); if (PageChecked(page)) { ClearPageChecked(page); if (!page_has_buffers(page)) { create_empty_buffers(page, inode->i_sb->s_blocksize, (1 << BH_Dirty)|(1 << BH_Uptodate)); } gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize-1); } return block_write_full_page(page, gfs2_get_block_noalloc, wbc); }
/* * unlocks pages after btrfs_file_write is done with them */ static noinline void btrfs_drop_pages(struct page **pages, size_t num_pages) { size_t i; for (i = 0; i < num_pages; i++) { if (!pages[i]) break; /* page checked is some magic around finding pages that * have been modified without going through btrfs_set_page_dirty * clear it here */ ClearPageChecked(pages[i]); unlock_page(pages[i]); mark_page_accessed(pages[i]); page_cache_release(pages[i]); } }
/* * after copy_from_user, pages need to be dirtied and we need to make * sure holes are created between the current EOF and the start of * any next extents (if required). * * this also makes the decision about creating an inline extent vs * doing real data extents, marking pages dirty and delalloc as required. */ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct file *file, struct page **pages, size_t num_pages, loff_t pos, size_t write_bytes) { int err = 0; int i; struct inode *inode = fdentry(file)->d_inode; u64 num_bytes; u64 start_pos; u64 end_of_last_block; u64 end_pos = pos + write_bytes; loff_t isize = i_size_read(inode); start_pos = pos & ~((u64)root->sectorsize - 1); num_bytes = (write_bytes + pos - start_pos + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); end_of_last_block = start_pos + num_bytes - 1; err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block); if (err) return err; for (i = 0; i < num_pages; i++) { struct page *p = pages[i]; SetPageUptodate(p); ClearPageChecked(p); set_page_dirty(p); } if (end_pos > isize) { i_size_write(inode, end_pos); /* we've only changed i_size in ram, and we haven't updated * the disk i_size. There is no need to log the inode * at this time. */ } return err; }
static void gfs2_invalidatepage(struct page *page, unsigned long offset) { struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); struct buffer_head *bh, *head; unsigned long pos = 0; BUG_ON(!PageLocked(page)); if (offset == 0) ClearPageChecked(page); if (!page_has_buffers(page)) goto out; bh = head = page_buffers(page); do { if (offset <= pos) gfs2_discard(sdp, bh); pos += bh->b_size; bh = bh->b_this_page; } while (bh != head); out: if (offset == 0) try_to_release_page(page, 0); }