Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 242417
b: refs/heads/master
c: a861a1e
h: refs/heads/master
i:
  242415: b3ebe42
v: v3
  • Loading branch information
Fred Isaman authored and Trond Myklebust committed Mar 23, 2011
1 parent 6c440f6 commit 8ac4127
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 425eb736cd905181a4dd4dc8d66342a7c7ab2f27
refs/heads/master: a861a1e1c398fe34701569fd8ac9225dfe0a9a7e
5 changes: 3 additions & 2 deletions trunk/fs/nfs/pagelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ int nfs_scan_list(struct nfs_inode *nfsi,
pgoff_t idx_end;
int found, i;
int res;
struct list_head *list;

res = 0;
if (npages == 0)
Expand All @@ -418,10 +419,10 @@ int nfs_scan_list(struct nfs_inode *nfsi,
idx_start = req->wb_index + 1;
if (nfs_set_page_tag_locked(req)) {
kref_get(&req->wb_kref);
nfs_list_remove_request(req);
radix_tree_tag_clear(&nfsi->nfs_page_tree,
req->wb_index, tag);
nfs_list_add_request(req, dst);
list = pnfs_choose_commit_list(req, dst);
nfs_list_add_request(req, list);
res++;
if (res == INT_MAX)
goto out;
Expand Down
73 changes: 73 additions & 0 deletions trunk/fs/nfs/pnfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ struct pnfs_layoutdriver_type {
/* test for nfs page cache coalescing */
int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *);

/* Returns true if layoutdriver wants to divert this request to
* driver's commit routine.
*/
bool (*mark_pnfs_commit)(struct pnfs_layout_segment *lseg);
struct list_head * (*choose_commit_list) (struct nfs_page *req);
int (*commit_pagelist)(struct inode *inode, struct list_head *mds_pages, int how);

/*
* Return PNFS_ATTEMPTED to indicate the layout code has attempted
* I/O, else return PNFS_NOT_ATTEMPTED to fall back to normal NFS
Expand Down Expand Up @@ -169,6 +176,51 @@ static inline int pnfs_enabled_sb(struct nfs_server *nfss)
return nfss->pnfs_curr_ld != NULL;
}

static inline void
pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg)
{
if (lseg) {
struct pnfs_layoutdriver_type *ld;

ld = NFS_SERVER(req->wb_page->mapping->host)->pnfs_curr_ld;
if (ld->mark_pnfs_commit && ld->mark_pnfs_commit(lseg)) {
set_bit(PG_PNFS_COMMIT, &req->wb_flags);
req->wb_commit_lseg = get_lseg(lseg);
}
}
}

static inline int
pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how)
{
if (!test_and_clear_bit(NFS_INO_PNFS_COMMIT, &NFS_I(inode)->flags))
return PNFS_NOT_ATTEMPTED;
return NFS_SERVER(inode)->pnfs_curr_ld->commit_pagelist(inode, mds_pages, how);
}

static inline struct list_head *
pnfs_choose_commit_list(struct nfs_page *req, struct list_head *mds)
{
struct list_head *rv;

if (test_and_clear_bit(PG_PNFS_COMMIT, &req->wb_flags)) {
struct inode *inode = req->wb_commit_lseg->pls_layout->plh_inode;

set_bit(NFS_INO_PNFS_COMMIT, &NFS_I(inode)->flags);
rv = NFS_SERVER(inode)->pnfs_curr_ld->choose_commit_list(req);
/* matched by ref taken when PG_PNFS_COMMIT is set */
put_lseg(req->wb_commit_lseg);
} else
rv = mds;
return rv;
}

static inline void pnfs_clear_request_commit(struct nfs_page *req)
{
if (test_and_clear_bit(PG_PNFS_COMMIT, &req->wb_flags))
put_lseg(req->wb_commit_lseg);
}

#else /* CONFIG_NFS_V4_1 */

static inline void pnfs_destroy_all_layouts(struct nfs_client *clp)
Expand Down Expand Up @@ -252,6 +304,27 @@ pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *ino)
pgio->pg_test = NULL;
}

static inline void
pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg)
{
}

static inline int
pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how)
{
return PNFS_NOT_ATTEMPTED;
}

static inline struct list_head *
pnfs_choose_commit_list(struct nfs_page *req, struct list_head *mds)
{
return mds;
}

static inline void pnfs_clear_request_commit(struct nfs_page *req)
{
}

#endif /* CONFIG_NFS_V4_1 */

#endif /* FS_NFS_PNFS_H */
41 changes: 26 additions & 15 deletions trunk/fs/nfs/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ nfs_mark_request_dirty(struct nfs_page *req)
* Add a request to the inode's commit list.
*/
static void
nfs_mark_request_commit(struct nfs_page *req)
nfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg)
{
struct inode *inode = req->wb_context->path.dentry->d_inode;
struct nfs_inode *nfsi = NFS_I(inode);
Expand All @@ -453,6 +453,7 @@ nfs_mark_request_commit(struct nfs_page *req)
NFS_PAGE_TAG_COMMIT);
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);
Expand Down Expand Up @@ -481,10 +482,11 @@ int nfs_write_need_commit(struct nfs_write_data *data)
}

static inline
int nfs_reschedule_unstable_write(struct nfs_page *req)
int nfs_reschedule_unstable_write(struct nfs_page *req,
struct nfs_write_data *data)
{
if (test_and_clear_bit(PG_NEED_COMMIT, &req->wb_flags)) {
nfs_mark_request_commit(req);
nfs_mark_request_commit(req, data->lseg);
return 1;
}
if (test_and_clear_bit(PG_NEED_RESCHED, &req->wb_flags)) {
Expand All @@ -495,7 +497,7 @@ int nfs_reschedule_unstable_write(struct nfs_page *req)
}
#else
static inline void
nfs_mark_request_commit(struct nfs_page *req)
nfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg)
{
}

Expand All @@ -512,7 +514,8 @@ int nfs_write_need_commit(struct nfs_write_data *data)
}

static inline
int nfs_reschedule_unstable_write(struct nfs_page *req)
int nfs_reschedule_unstable_write(struct nfs_page *req,
struct nfs_write_data *data)
{
return 0;
}
Expand Down Expand Up @@ -615,9 +618,11 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode,
}

if (nfs_clear_request_commit(req) &&
radix_tree_tag_clear(&NFS_I(inode)->nfs_page_tree,
req->wb_index, NFS_PAGE_TAG_COMMIT) != NULL)
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);
}

/* Okay, the request matches. Update the region */
if (offset < req->wb_offset) {
Expand Down Expand Up @@ -765,11 +770,12 @@ int nfs_updatepage(struct file *file, struct page *page,
return status;
}

static void nfs_writepage_release(struct nfs_page *req)
static void nfs_writepage_release(struct nfs_page *req,
struct nfs_write_data *data)
{
struct page *page = req->wb_page;

if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req))
if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req, data))
nfs_inode_remove_request(req);
nfs_clear_page_tag_locked(req);
nfs_end_page_writeback(page);
Expand Down Expand Up @@ -1087,7 +1093,7 @@ static void nfs_writeback_release_partial(void *calldata)

out:
if (atomic_dec_and_test(&req->wb_complete))
nfs_writepage_release(req);
nfs_writepage_release(req, data);
nfs_writedata_release(calldata);
}

Expand Down Expand Up @@ -1154,7 +1160,7 @@ static void nfs_writeback_release_full(void *calldata)

if (nfs_write_need_commit(data)) {
memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
nfs_mark_request_commit(req);
nfs_mark_request_commit(req, data->lseg);
dprintk(" marked for commit\n");
goto next;
}
Expand Down Expand Up @@ -1357,14 +1363,15 @@ static void nfs_init_commit(struct nfs_write_data *data,
nfs_fattr_init(&data->fattr);
}

static void nfs_retry_commit(struct list_head *page_list)
static void nfs_retry_commit(struct list_head *page_list,
struct pnfs_layout_segment *lseg)
{
struct nfs_page *req;

while (!list_empty(page_list)) {
req = nfs_list_entry(page_list->next);
nfs_list_remove_request(req);
nfs_mark_request_commit(req);
nfs_mark_request_commit(req, lseg);
dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
dec_bdi_stat(req->wb_page->mapping->backing_dev_info,
BDI_RECLAIMABLE);
Expand All @@ -1389,7 +1396,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
nfs_init_commit(data, head);
return nfs_initiate_commit(data, NFS_CLIENT(inode), data->mds_ops, how);
out_bad:
nfs_retry_commit(head);
nfs_retry_commit(head, NULL);
nfs_commit_clear_lock(NFS_I(inode));
return -ENOMEM;
}
Expand Down Expand Up @@ -1477,7 +1484,11 @@ int nfs_commit_inode(struct inode *inode, int how)
res = nfs_scan_commit(inode, &head, 0, 0);
spin_unlock(&inode->i_lock);
if (res) {
int error = nfs_commit_list(inode, &head, how);
int error;

error = pnfs_commit_list(inode, &head, how);
if (error == PNFS_NOT_ATTEMPTED)
error = nfs_commit_list(inode, &head, how);
if (error < 0)
return error;
if (!may_wait)
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/nfs_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ struct nfs_inode {
#define NFS_INO_FSCACHE (5) /* inode can be cached by FS-Cache */
#define NFS_INO_FSCACHE_LOCK (6) /* FS-Cache cookie management lock */
#define NFS_INO_COMMIT (7) /* inode is committing unstable writes */
#define NFS_INO_PNFS_COMMIT (8) /* use pnfs code for commit */

static inline struct nfs_inode *NFS_I(const struct inode *inode)
{
Expand Down
6 changes: 5 additions & 1 deletion trunk/include/linux/nfs_page.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,15 @@ enum {
PG_CLEAN,
PG_NEED_COMMIT,
PG_NEED_RESCHED,
PG_PNFS_COMMIT,
};

struct nfs_inode;
struct nfs_page {
struct list_head wb_list; /* Defines state of page: */
union {
struct list_head wb_list; /* Defines state of page: */
struct pnfs_layout_segment *wb_commit_lseg; /* Used when PG_PNFS_COMMIT set */
};
struct page *wb_page; /* page to read in/write out */
struct nfs_open_context *wb_context; /* File state context info */
struct nfs_lock_context *wb_lock_context; /* lock context info */
Expand Down

0 comments on commit 8ac4127

Please sign in to comment.