mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 23:32:14 +00:00
NFS: remove nfs_inode radix tree
The radix tree is only being used to compile lists of reqs needing commit. It is simpler to just put the reqs directly into a list. Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
9994b62b56
commit
d6d6dc7cdf
9 changed files with 208 additions and 194 deletions
120
fs/nfs/write.c
120
fs/nfs/write.c
|
@ -375,21 +375,14 @@ out_err:
|
|||
/*
|
||||
* Insert a write request into an inode
|
||||
*/
|
||||
static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
|
||||
static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
int error;
|
||||
|
||||
error = radix_tree_preload(GFP_NOFS);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
|
||||
/* Lock the request! */
|
||||
nfs_lock_request_dontget(req);
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req);
|
||||
BUG_ON(error);
|
||||
if (!nfsi->npages && nfs_have_delegation(inode, FMODE_WRITE))
|
||||
inode->i_version++;
|
||||
set_bit(PG_MAPPED, &req->wb_flags);
|
||||
|
@ -398,11 +391,10 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
|
|||
nfsi->npages++;
|
||||
kref_get(&req->wb_kref);
|
||||
spin_unlock(&inode->i_lock);
|
||||
radix_tree_preload_end();
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct pnfs_layout_segment *nfs_clear_request_commit(struct nfs_page *req);
|
||||
|
||||
/*
|
||||
* Remove a write request from an inode
|
||||
*/
|
||||
|
@ -410,16 +402,18 @@ static void nfs_inode_remove_request(struct nfs_page *req)
|
|||
{
|
||||
struct inode *inode = req->wb_context->dentry->d_inode;
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
struct pnfs_layout_segment *lseg;
|
||||
|
||||
BUG_ON (!NFS_WBACK_BUSY(req));
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
lseg = nfs_clear_request_commit(req);
|
||||
set_page_private(req->wb_page, 0);
|
||||
ClearPagePrivate(req->wb_page);
|
||||
clear_bit(PG_MAPPED, &req->wb_flags);
|
||||
radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
|
||||
nfsi->npages--;
|
||||
spin_unlock(&inode->i_lock);
|
||||
put_lseg(lseg);
|
||||
nfs_release_request(req);
|
||||
}
|
||||
|
||||
|
@ -438,31 +432,38 @@ nfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg)
|
|||
{
|
||||
struct inode *inode = req->wb_context->dentry->d_inode;
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
struct list_head *clist;
|
||||
|
||||
clist = pnfs_choose_commit_list(req, lseg);
|
||||
spin_lock(&inode->i_lock);
|
||||
set_bit(PG_CLEAN, &(req)->wb_flags);
|
||||
radix_tree_tag_set(&nfsi->nfs_page_tree,
|
||||
req->wb_index,
|
||||
NFS_PAGE_TAG_COMMIT);
|
||||
nfs_list_add_request(req, clist);
|
||||
nfsi->ncommit++;
|
||||
spin_unlock(&inode->i_lock);
|
||||
pnfs_mark_request_commit(req, lseg);
|
||||
inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
|
||||
inc_bdi_stat(req->wb_page->mapping->backing_dev_info, BDI_RECLAIMABLE);
|
||||
__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
nfs_clear_page_commit(struct page *page)
|
||||
{
|
||||
dec_zone_page_state(page, NR_UNSTABLE_NFS);
|
||||
dec_bdi_stat(page->mapping->backing_dev_info, BDI_RECLAIMABLE);
|
||||
}
|
||||
|
||||
static struct pnfs_layout_segment *
|
||||
nfs_clear_request_commit(struct nfs_page *req)
|
||||
{
|
||||
struct page *page = req->wb_page;
|
||||
struct pnfs_layout_segment *lseg = NULL;
|
||||
|
||||
if (test_and_clear_bit(PG_CLEAN, &(req)->wb_flags)) {
|
||||
dec_zone_page_state(page, NR_UNSTABLE_NFS);
|
||||
dec_bdi_stat(page->mapping->backing_dev_info, BDI_RECLAIMABLE);
|
||||
return 1;
|
||||
nfs_clear_page_commit(req->wb_page);
|
||||
lseg = pnfs_clear_request_commit(req);
|
||||
NFS_I(req->wb_context->dentry->d_inode)->ncommit--;
|
||||
list_del(&req->wb_list);
|
||||
}
|
||||
return 0;
|
||||
return lseg;
|
||||
}
|
||||
|
||||
static inline
|
||||
|
@ -494,10 +495,10 @@ nfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg)
|
|||
{
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline struct pnfs_layout_segment *
|
||||
nfs_clear_request_commit(struct nfs_page *req)
|
||||
{
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline
|
||||
|
@ -518,46 +519,67 @@ int nfs_reschedule_unstable_write(struct nfs_page *req,
|
|||
static int
|
||||
nfs_need_commit(struct nfs_inode *nfsi)
|
||||
{
|
||||
return radix_tree_tagged(&nfsi->nfs_page_tree, NFS_PAGE_TAG_COMMIT);
|
||||
return nfsi->ncommit > 0;
|
||||
}
|
||||
|
||||
/* i_lock held by caller */
|
||||
int
|
||||
nfs_scan_commit_list(struct list_head *src, struct list_head *dst, int max)
|
||||
{
|
||||
struct nfs_page *req, *tmp;
|
||||
int ret = 0;
|
||||
|
||||
list_for_each_entry_safe(req, tmp, src, wb_list) {
|
||||
if (nfs_lock_request_dontget(req)) {
|
||||
kref_get(&req->wb_kref);
|
||||
list_move_tail(&req->wb_list, dst);
|
||||
clear_bit(PG_CLEAN, &(req)->wb_flags);
|
||||
ret++;
|
||||
if (ret == max)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_scan_commit_list);
|
||||
|
||||
/*
|
||||
* nfs_scan_commit - Scan an inode for commit requests
|
||||
* @inode: NFS inode to scan
|
||||
* @dst: destination list
|
||||
* @idx_start: lower bound of page->index to scan.
|
||||
* @npages: idx_start + npages sets the upper bound to scan.
|
||||
*
|
||||
* Moves requests from the inode's 'commit' request list.
|
||||
* The requests are *not* checked to ensure that they form a contiguous set.
|
||||
*/
|
||||
static int
|
||||
nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages)
|
||||
nfs_scan_commit(struct inode *inode, struct list_head *dst)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
int ret;
|
||||
|
||||
if (!nfs_need_commit(nfsi))
|
||||
return 0;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
ret = nfs_scan_list(nfsi, dst, idx_start, npages, NFS_PAGE_TAG_COMMIT);
|
||||
if (ret > 0)
|
||||
if (nfsi->ncommit > 0) {
|
||||
int pnfs_ret;
|
||||
|
||||
ret = nfs_scan_commit_list(&nfsi->commit_list, dst, INT_MAX);
|
||||
pnfs_ret = pnfs_scan_commit_lists(inode, INT_MAX - ret);
|
||||
if (pnfs_ret) {
|
||||
ret += pnfs_ret;
|
||||
set_bit(NFS_INO_PNFS_COMMIT, &nfsi->flags);
|
||||
}
|
||||
nfsi->ncommit -= ret;
|
||||
}
|
||||
spin_unlock(&inode->i_lock);
|
||||
|
||||
if (nfs_need_commit(NFS_I(inode)))
|
||||
__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
static inline int nfs_need_commit(struct nfs_inode *nfsi)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages)
|
||||
static inline int nfs_scan_commit(struct inode *inode, struct list_head *dst)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -579,6 +601,7 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode,
|
|||
unsigned int rqend;
|
||||
unsigned int end;
|
||||
int error;
|
||||
struct pnfs_layout_segment *lseg = NULL;
|
||||
|
||||
if (!PagePrivate(page))
|
||||
return NULL;
|
||||
|
@ -614,12 +637,7 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode,
|
|||
spin_lock(&inode->i_lock);
|
||||
}
|
||||
|
||||
if (nfs_clear_request_commit(req) &&
|
||||
radix_tree_tag_clear(&NFS_I(inode)->nfs_page_tree,
|
||||
req->wb_index, NFS_PAGE_TAG_COMMIT) != NULL) {
|
||||
NFS_I(inode)->ncommit--;
|
||||
pnfs_clear_request_commit(req);
|
||||
}
|
||||
lseg = nfs_clear_request_commit(req);
|
||||
|
||||
/* Okay, the request matches. Update the region */
|
||||
if (offset < req->wb_offset) {
|
||||
|
@ -632,6 +650,7 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode,
|
|||
req->wb_bytes = rqend - req->wb_offset;
|
||||
out_unlock:
|
||||
spin_unlock(&inode->i_lock);
|
||||
put_lseg(lseg);
|
||||
return req;
|
||||
out_flushme:
|
||||
spin_unlock(&inode->i_lock);
|
||||
|
@ -653,7 +672,6 @@ static struct nfs_page * nfs_setup_write_request(struct nfs_open_context* ctx,
|
|||
{
|
||||
struct inode *inode = page->mapping->host;
|
||||
struct nfs_page *req;
|
||||
int error;
|
||||
|
||||
req = nfs_try_to_update_request(inode, page, offset, bytes);
|
||||
if (req != NULL)
|
||||
|
@ -661,11 +679,7 @@ static struct nfs_page * nfs_setup_write_request(struct nfs_open_context* ctx,
|
|||
req = nfs_create_request(ctx, inode, page, offset, bytes);
|
||||
if (IS_ERR(req))
|
||||
goto out;
|
||||
error = nfs_inode_add_request(inode, req);
|
||||
if (error != 0) {
|
||||
nfs_release_request(req);
|
||||
req = ERR_PTR(error);
|
||||
}
|
||||
nfs_inode_add_request(inode, req);
|
||||
out:
|
||||
return req;
|
||||
}
|
||||
|
@ -1458,7 +1472,7 @@ void nfs_commit_release_pages(struct nfs_write_data *data)
|
|||
while (!list_empty(&data->pages)) {
|
||||
req = nfs_list_entry(data->pages.next);
|
||||
nfs_list_remove_request(req);
|
||||
nfs_clear_request_commit(req);
|
||||
nfs_clear_page_commit(req->wb_page);
|
||||
|
||||
dprintk("NFS: commit (%s/%lld %d@%lld)",
|
||||
req->wb_context->dentry->d_sb->s_id,
|
||||
|
@ -1515,7 +1529,7 @@ int nfs_commit_inode(struct inode *inode, int how)
|
|||
res = nfs_commit_set_lock(NFS_I(inode), may_wait);
|
||||
if (res <= 0)
|
||||
goto out_mark_dirty;
|
||||
res = nfs_scan_commit(inode, &head, 0, 0);
|
||||
res = nfs_scan_commit(inode, &head);
|
||||
if (res) {
|
||||
int error;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue