Loading fs/nfs/write.c +33 −33 Original line number Diff line number Diff line Loading @@ -155,6 +155,29 @@ void nfs_writedata_release(void *wdata) nfs_writedata_free(wdata); } static struct nfs_page *nfs_page_find_request_locked(struct page *page) { struct nfs_page *req = NULL; if (PagePrivate(page)) { req = (struct nfs_page *)page_private(page); if (req != NULL) atomic_inc(&req->wb_count); } return req; } static struct nfs_page *nfs_page_find_request(struct page *page) { struct nfs_page *req = NULL; spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; spin_lock(req_lock); req = nfs_page_find_request_locked(page); spin_unlock(req_lock); return req; } /* Adjust the file length if we're writing beyond the end */ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count) { Loading Loading @@ -429,6 +452,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) nfsi->change_attr++; } SetPagePrivate(req->wb_page); set_page_private(req->wb_page, (unsigned long)req); nfsi->npages++; atomic_inc(&req->wb_count); return 0; Loading @@ -445,6 +469,7 @@ static void nfs_inode_remove_request(struct nfs_page *req) BUG_ON (!NFS_WBACK_BUSY(req)); spin_lock(&nfsi->req_lock); set_page_private(req->wb_page, 0); ClearPagePrivate(req->wb_page); radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); nfsi->npages--; Loading @@ -458,33 +483,6 @@ static void nfs_inode_remove_request(struct nfs_page *req) nfs_release_request(req); } /* * Find a request */ static inline struct nfs_page * _nfs_find_request(struct inode *inode, unsigned long index) { struct nfs_inode *nfsi = NFS_I(inode); struct nfs_page *req; req = (struct nfs_page*)radix_tree_lookup(&nfsi->nfs_page_tree, index); if (req) atomic_inc(&req->wb_count); return req; } static struct nfs_page * nfs_find_request(struct inode *inode, unsigned long index) { struct nfs_page *req; struct nfs_inode *nfsi = NFS_I(inode); spin_lock(&nfsi->req_lock); req = _nfs_find_request(inode, index); spin_unlock(&nfsi->req_lock); return req; } /* * Add a request to the inode's dirty list. */ Loading Loading @@ -699,10 +697,11 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, * A request for the page we wish to update */ spin_lock(&nfsi->req_lock); req = _nfs_find_request(inode, page->index); req = nfs_page_find_request_locked(page); if (req) { if (!nfs_lock_request_dontget(req)) { int error; spin_unlock(&nfsi->req_lock); error = nfs_wait_on_request(req); nfs_release_request(req); Loading Loading @@ -770,7 +769,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, int nfs_flush_incompatible(struct file *file, struct page *page) { struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; struct inode *inode = page->mapping->host; struct nfs_page *req; int status = 0; /* Loading @@ -781,11 +779,13 @@ int nfs_flush_incompatible(struct file *file, struct page *page) * Also do the same if we find a request from an existing * dropped page. */ req = nfs_find_request(inode, page->index); if (req) { if (req->wb_page != page || ctx != req->wb_context) status = nfs_wb_page(inode, page); req = nfs_page_find_request(page); if (req != NULL) { int do_flush = req->wb_page != page || req->wb_context != ctx; nfs_release_request(req); if (do_flush) status = nfs_wb_page(page->mapping->host, page); } return (status < 0) ? status : 0; } Loading Loading
fs/nfs/write.c +33 −33 Original line number Diff line number Diff line Loading @@ -155,6 +155,29 @@ void nfs_writedata_release(void *wdata) nfs_writedata_free(wdata); } static struct nfs_page *nfs_page_find_request_locked(struct page *page) { struct nfs_page *req = NULL; if (PagePrivate(page)) { req = (struct nfs_page *)page_private(page); if (req != NULL) atomic_inc(&req->wb_count); } return req; } static struct nfs_page *nfs_page_find_request(struct page *page) { struct nfs_page *req = NULL; spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; spin_lock(req_lock); req = nfs_page_find_request_locked(page); spin_unlock(req_lock); return req; } /* Adjust the file length if we're writing beyond the end */ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count) { Loading Loading @@ -429,6 +452,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) nfsi->change_attr++; } SetPagePrivate(req->wb_page); set_page_private(req->wb_page, (unsigned long)req); nfsi->npages++; atomic_inc(&req->wb_count); return 0; Loading @@ -445,6 +469,7 @@ static void nfs_inode_remove_request(struct nfs_page *req) BUG_ON (!NFS_WBACK_BUSY(req)); spin_lock(&nfsi->req_lock); set_page_private(req->wb_page, 0); ClearPagePrivate(req->wb_page); radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); nfsi->npages--; Loading @@ -458,33 +483,6 @@ static void nfs_inode_remove_request(struct nfs_page *req) nfs_release_request(req); } /* * Find a request */ static inline struct nfs_page * _nfs_find_request(struct inode *inode, unsigned long index) { struct nfs_inode *nfsi = NFS_I(inode); struct nfs_page *req; req = (struct nfs_page*)radix_tree_lookup(&nfsi->nfs_page_tree, index); if (req) atomic_inc(&req->wb_count); return req; } static struct nfs_page * nfs_find_request(struct inode *inode, unsigned long index) { struct nfs_page *req; struct nfs_inode *nfsi = NFS_I(inode); spin_lock(&nfsi->req_lock); req = _nfs_find_request(inode, index); spin_unlock(&nfsi->req_lock); return req; } /* * Add a request to the inode's dirty list. */ Loading Loading @@ -699,10 +697,11 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, * A request for the page we wish to update */ spin_lock(&nfsi->req_lock); req = _nfs_find_request(inode, page->index); req = nfs_page_find_request_locked(page); if (req) { if (!nfs_lock_request_dontget(req)) { int error; spin_unlock(&nfsi->req_lock); error = nfs_wait_on_request(req); nfs_release_request(req); Loading Loading @@ -770,7 +769,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, int nfs_flush_incompatible(struct file *file, struct page *page) { struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; struct inode *inode = page->mapping->host; struct nfs_page *req; int status = 0; /* Loading @@ -781,11 +779,13 @@ int nfs_flush_incompatible(struct file *file, struct page *page) * Also do the same if we find a request from an existing * dropped page. */ req = nfs_find_request(inode, page->index); if (req) { if (req->wb_page != page || ctx != req->wb_context) status = nfs_wb_page(inode, page); req = nfs_page_find_request(page); if (req != NULL) { int do_flush = req->wb_page != page || req->wb_context != ctx; nfs_release_request(req); if (do_flush) status = nfs_wb_page(page->mapping->host, page); } return (status < 0) ? status : 0; } Loading