Loading fs/nfs/file.c +1 −5 Original line number Diff line number Diff line Loading @@ -307,14 +307,10 @@ static int nfs_commit_write(struct file *file, struct page *page, unsigned offse static void nfs_invalidate_page(struct page *page, unsigned long offset) { loff_t range_start, range_end; if (offset != 0) return; /* Cancel any unstarted writes on this page */ range_start = page_offset(page); range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1); nfs_sync_mapping_range(page->mapping, range_start, range_end, FLUSH_INVALIDATE); nfs_wb_page_priority(page->mapping->host, page, FLUSH_INVALIDATE); } static int nfs_release_page(struct page *page, gfp_t gfp) Loading fs/nfs/write.c +28 −10 Original line number Diff line number Diff line Loading @@ -81,7 +81,6 @@ static void nfs_mark_request_dirty(struct nfs_page *req); static int nfs_wait_on_write_congestion(struct address_space *, int); static int nfs_wait_on_requests(struct inode *, unsigned long, unsigned int); static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); static int nfs_wb_page_priority(struct inode *inode, struct page *page, int how); static const struct rpc_call_ops nfs_write_partial_ops; static const struct rpc_call_ops nfs_write_full_ops; static const struct rpc_call_ops nfs_commit_ops; Loading Loading @@ -280,8 +279,10 @@ static int nfs_page_mark_flush(struct page *page) spin_lock(req_lock); } spin_unlock(req_lock); if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) { nfs_mark_request_dirty(req); set_page_writeback(page); } ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); nfs_unlock_request(req); return ret; Loading Loading @@ -443,6 +444,13 @@ nfs_mark_request_dirty(struct nfs_page *req) mark_inode_dirty(inode); } static void nfs_redirty_request(struct nfs_page *req) { clear_bit(PG_FLUSHING, &req->wb_flags); __set_page_dirty_nobuffers(req->wb_page); } /* * Check if a request is dirty */ Loading Loading @@ -777,7 +785,7 @@ static void nfs_writepage_release(struct nfs_page *req) #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) if (!PageError(req->wb_page)) { if (NFS_NEED_RESCHED(req)) { nfs_mark_request_dirty(req); nfs_redirty_request(req); goto out; } else if (NFS_NEED_COMMIT(req)) { nfs_mark_request_commit(req); Loading Loading @@ -893,7 +901,6 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, int how) atomic_set(&req->wb_complete, requests); ClearPageError(page); set_page_writeback(page); offset = 0; nbytes = req->wb_bytes; do { Loading Loading @@ -923,7 +930,7 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, int how) list_del(&data->pages); nfs_writedata_release(data); } nfs_mark_request_dirty(req); nfs_redirty_request(req); nfs_clear_page_writeback(req); return -ENOMEM; } Loading Loading @@ -954,7 +961,6 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, int how) nfs_list_remove_request(req); nfs_list_add_request(req, &data->pages); ClearPageError(req->wb_page); set_page_writeback(req->wb_page); *pages++ = req->wb_page; count += req->wb_bytes; } Loading @@ -969,7 +975,7 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, int how) while (!list_empty(head)) { struct nfs_page *req = nfs_list_entry(head->next); nfs_list_remove_request(req); nfs_mark_request_dirty(req); nfs_redirty_request(req); nfs_clear_page_writeback(req); } return -ENOMEM; Loading Loading @@ -1004,7 +1010,7 @@ static int nfs_flush_list(struct inode *inode, struct list_head *head, int npage while (!list_empty(head)) { req = nfs_list_entry(head->next); nfs_list_remove_request(req); nfs_mark_request_dirty(req); nfs_redirty_request(req); nfs_clear_page_writeback(req); } return error; Loading Loading @@ -1320,7 +1326,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata) } /* We have a mismatch. Write the page again */ dprintk(" mismatch\n"); nfs_mark_request_dirty(req); nfs_redirty_request(req); next: nfs_clear_page_writeback(req); } Loading Loading @@ -1451,13 +1457,18 @@ int nfs_wb_all(struct inode *inode) .bdi = mapping->backing_dev_info, .sync_mode = WB_SYNC_ALL, .nr_to_write = LONG_MAX, .for_writepages = 1, .range_cyclic = 1, }; int ret; ret = generic_writepages(mapping, &wbc); if (ret < 0) goto out; ret = nfs_sync_mapping_wait(mapping, &wbc, 0); if (ret >= 0) return 0; out: return ret; } Loading @@ -1469,16 +1480,23 @@ int nfs_sync_mapping_range(struct address_space *mapping, loff_t range_start, lo .nr_to_write = LONG_MAX, .range_start = range_start, .range_end = range_end, .for_writepages = 1, }; int ret; if (!(how & FLUSH_NOWRITEPAGE)) { ret = generic_writepages(mapping, &wbc); if (ret < 0) goto out; } ret = nfs_sync_mapping_wait(mapping, &wbc, how); if (ret >= 0) return 0; out: return ret; } static int nfs_wb_page_priority(struct inode *inode, struct page *page, int how) int nfs_wb_page_priority(struct inode *inode, struct page *page, int how) { loff_t range_start = page_offset(page); loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1); Loading include/linux/nfs_fs.h +1 −0 Original line number Diff line number Diff line Loading @@ -438,6 +438,7 @@ extern long nfs_sync_mapping_wait(struct address_space *, struct writeback_contr extern int nfs_sync_mapping_range(struct address_space *, loff_t, loff_t, int); extern int nfs_wb_all(struct inode *inode); extern int nfs_wb_page(struct inode *inode, struct page* page); extern int nfs_wb_page_priority(struct inode *inode, struct page* page, int how); #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) extern int nfs_commit_inode(struct inode *, int); extern struct nfs_write_data *nfs_commit_alloc(void); Loading Loading
fs/nfs/file.c +1 −5 Original line number Diff line number Diff line Loading @@ -307,14 +307,10 @@ static int nfs_commit_write(struct file *file, struct page *page, unsigned offse static void nfs_invalidate_page(struct page *page, unsigned long offset) { loff_t range_start, range_end; if (offset != 0) return; /* Cancel any unstarted writes on this page */ range_start = page_offset(page); range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1); nfs_sync_mapping_range(page->mapping, range_start, range_end, FLUSH_INVALIDATE); nfs_wb_page_priority(page->mapping->host, page, FLUSH_INVALIDATE); } static int nfs_release_page(struct page *page, gfp_t gfp) Loading
fs/nfs/write.c +28 −10 Original line number Diff line number Diff line Loading @@ -81,7 +81,6 @@ static void nfs_mark_request_dirty(struct nfs_page *req); static int nfs_wait_on_write_congestion(struct address_space *, int); static int nfs_wait_on_requests(struct inode *, unsigned long, unsigned int); static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); static int nfs_wb_page_priority(struct inode *inode, struct page *page, int how); static const struct rpc_call_ops nfs_write_partial_ops; static const struct rpc_call_ops nfs_write_full_ops; static const struct rpc_call_ops nfs_commit_ops; Loading Loading @@ -280,8 +279,10 @@ static int nfs_page_mark_flush(struct page *page) spin_lock(req_lock); } spin_unlock(req_lock); if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) { nfs_mark_request_dirty(req); set_page_writeback(page); } ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); nfs_unlock_request(req); return ret; Loading Loading @@ -443,6 +444,13 @@ nfs_mark_request_dirty(struct nfs_page *req) mark_inode_dirty(inode); } static void nfs_redirty_request(struct nfs_page *req) { clear_bit(PG_FLUSHING, &req->wb_flags); __set_page_dirty_nobuffers(req->wb_page); } /* * Check if a request is dirty */ Loading Loading @@ -777,7 +785,7 @@ static void nfs_writepage_release(struct nfs_page *req) #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) if (!PageError(req->wb_page)) { if (NFS_NEED_RESCHED(req)) { nfs_mark_request_dirty(req); nfs_redirty_request(req); goto out; } else if (NFS_NEED_COMMIT(req)) { nfs_mark_request_commit(req); Loading Loading @@ -893,7 +901,6 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, int how) atomic_set(&req->wb_complete, requests); ClearPageError(page); set_page_writeback(page); offset = 0; nbytes = req->wb_bytes; do { Loading Loading @@ -923,7 +930,7 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, int how) list_del(&data->pages); nfs_writedata_release(data); } nfs_mark_request_dirty(req); nfs_redirty_request(req); nfs_clear_page_writeback(req); return -ENOMEM; } Loading Loading @@ -954,7 +961,6 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, int how) nfs_list_remove_request(req); nfs_list_add_request(req, &data->pages); ClearPageError(req->wb_page); set_page_writeback(req->wb_page); *pages++ = req->wb_page; count += req->wb_bytes; } Loading @@ -969,7 +975,7 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, int how) while (!list_empty(head)) { struct nfs_page *req = nfs_list_entry(head->next); nfs_list_remove_request(req); nfs_mark_request_dirty(req); nfs_redirty_request(req); nfs_clear_page_writeback(req); } return -ENOMEM; Loading Loading @@ -1004,7 +1010,7 @@ static int nfs_flush_list(struct inode *inode, struct list_head *head, int npage while (!list_empty(head)) { req = nfs_list_entry(head->next); nfs_list_remove_request(req); nfs_mark_request_dirty(req); nfs_redirty_request(req); nfs_clear_page_writeback(req); } return error; Loading Loading @@ -1320,7 +1326,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata) } /* We have a mismatch. Write the page again */ dprintk(" mismatch\n"); nfs_mark_request_dirty(req); nfs_redirty_request(req); next: nfs_clear_page_writeback(req); } Loading Loading @@ -1451,13 +1457,18 @@ int nfs_wb_all(struct inode *inode) .bdi = mapping->backing_dev_info, .sync_mode = WB_SYNC_ALL, .nr_to_write = LONG_MAX, .for_writepages = 1, .range_cyclic = 1, }; int ret; ret = generic_writepages(mapping, &wbc); if (ret < 0) goto out; ret = nfs_sync_mapping_wait(mapping, &wbc, 0); if (ret >= 0) return 0; out: return ret; } Loading @@ -1469,16 +1480,23 @@ int nfs_sync_mapping_range(struct address_space *mapping, loff_t range_start, lo .nr_to_write = LONG_MAX, .range_start = range_start, .range_end = range_end, .for_writepages = 1, }; int ret; if (!(how & FLUSH_NOWRITEPAGE)) { ret = generic_writepages(mapping, &wbc); if (ret < 0) goto out; } ret = nfs_sync_mapping_wait(mapping, &wbc, how); if (ret >= 0) return 0; out: return ret; } static int nfs_wb_page_priority(struct inode *inode, struct page *page, int how) int nfs_wb_page_priority(struct inode *inode, struct page *page, int how) { loff_t range_start = page_offset(page); loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1); Loading
include/linux/nfs_fs.h +1 −0 Original line number Diff line number Diff line Loading @@ -438,6 +438,7 @@ extern long nfs_sync_mapping_wait(struct address_space *, struct writeback_contr extern int nfs_sync_mapping_range(struct address_space *, loff_t, loff_t, int); extern int nfs_wb_all(struct inode *inode); extern int nfs_wb_page(struct inode *inode, struct page* page); extern int nfs_wb_page_priority(struct inode *inode, struct page* page, int how); #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) extern int nfs_commit_inode(struct inode *, int); extern struct nfs_write_data *nfs_commit_alloc(void); Loading