Commit 8e821cad authored by Trond Myklebust's avatar Trond Myklebust Committed by Linus Torvalds

NFS: clean up the unstable write code

Get rid of the inlined #ifdefs.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 7ab77e03
...@@ -460,6 +460,43 @@ nfs_mark_request_commit(struct nfs_page *req) ...@@ -460,6 +460,43 @@ nfs_mark_request_commit(struct nfs_page *req)
inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
__mark_inode_dirty(inode, I_DIRTY_DATASYNC); __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
} }
static inline
int nfs_write_need_commit(struct nfs_write_data *data)
{
return data->verf.committed != NFS_FILE_SYNC;
}
static inline
int nfs_reschedule_unstable_write(struct nfs_page *req)
{
if (test_and_clear_bit(PG_NEED_COMMIT, &req->wb_flags)) {
nfs_mark_request_commit(req);
return 1;
}
if (test_and_clear_bit(PG_NEED_RESCHED, &req->wb_flags)) {
nfs_redirty_request(req);
return 1;
}
return 0;
}
#else
static inline void
nfs_mark_request_commit(struct nfs_page *req)
{
}
static inline
int nfs_write_need_commit(struct nfs_write_data *data)
{
return 0;
}
static inline
int nfs_reschedule_unstable_write(struct nfs_page *req)
{
return 0;
}
#endif #endif
/* /*
...@@ -746,26 +783,12 @@ int nfs_updatepage(struct file *file, struct page *page, ...@@ -746,26 +783,12 @@ int nfs_updatepage(struct file *file, struct page *page,
static void nfs_writepage_release(struct nfs_page *req) static void nfs_writepage_release(struct nfs_page *req)
{ {
nfs_end_page_writeback(req->wb_page);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) {
if (!PageError(req->wb_page)) { nfs_end_page_writeback(req->wb_page);
if (NFS_NEED_RESCHED(req)) { nfs_inode_remove_request(req);
nfs_redirty_request(req); } else
goto out; nfs_end_page_writeback(req->wb_page);
} else if (NFS_NEED_COMMIT(req)) {
nfs_mark_request_commit(req);
goto out;
}
}
nfs_inode_remove_request(req);
out:
nfs_clear_commit(req);
nfs_clear_reschedule(req);
#else
nfs_inode_remove_request(req);
#endif
nfs_clear_page_writeback(req); nfs_clear_page_writeback(req);
} }
...@@ -1008,22 +1031,28 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata) ...@@ -1008,22 +1031,28 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
nfs_set_pageerror(page); nfs_set_pageerror(page);
req->wb_context->error = task->tk_status; req->wb_context->error = task->tk_status;
dprintk(", error = %d\n", task->tk_status); dprintk(", error = %d\n", task->tk_status);
} else { goto out;
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
if (data->verf.committed < NFS_FILE_SYNC) {
if (!NFS_NEED_COMMIT(req)) {
nfs_defer_commit(req);
memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
dprintk(" defer commit\n");
} else if (memcmp(&req->wb_verf, &data->verf, sizeof(req->wb_verf))) {
nfs_defer_reschedule(req);
dprintk(" server reboot detected\n");
}
} else
#endif
dprintk(" OK\n");
} }
if (nfs_write_need_commit(data)) {
spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock;
spin_lock(req_lock);
if (test_bit(PG_NEED_RESCHED, &req->wb_flags)) {
/* Do nothing we need to resend the writes */
} else if (!test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags)) {
memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
dprintk(" defer commit\n");
} else if (memcmp(&req->wb_verf, &data->verf, sizeof(req->wb_verf))) {
set_bit(PG_NEED_RESCHED, &req->wb_flags);
clear_bit(PG_NEED_COMMIT, &req->wb_flags);
dprintk(" server reboot detected\n");
}
spin_unlock(req_lock);
} else
dprintk(" OK\n");
out:
if (atomic_dec_and_test(&req->wb_complete)) if (atomic_dec_and_test(&req->wb_complete))
nfs_writepage_release(req); nfs_writepage_release(req);
} }
...@@ -1064,25 +1093,21 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata) ...@@ -1064,25 +1093,21 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
if (task->tk_status < 0) { if (task->tk_status < 0) {
nfs_set_pageerror(page); nfs_set_pageerror(page);
req->wb_context->error = task->tk_status; req->wb_context->error = task->tk_status;
nfs_end_page_writeback(page);
nfs_inode_remove_request(req);
dprintk(", error = %d\n", task->tk_status); dprintk(", error = %d\n", task->tk_status);
goto next; goto remove_request;
} }
nfs_end_page_writeback(page);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) if (nfs_write_need_commit(data)) {
if (data->args.stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) { memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
nfs_inode_remove_request(req); nfs_mark_request_commit(req);
dprintk(" OK\n"); nfs_end_page_writeback(page);
dprintk(" marked for commit\n");
goto next; goto next;
} }
memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); dprintk(" OK\n");
nfs_mark_request_commit(req); remove_request:
dprintk(" marked for commit\n"); nfs_end_page_writeback(page);
#else
nfs_inode_remove_request(req); nfs_inode_remove_request(req);
#endif
next: next:
nfs_clear_page_writeback(req); nfs_clear_page_writeback(req);
} }
......
...@@ -49,8 +49,6 @@ struct nfs_page { ...@@ -49,8 +49,6 @@ struct nfs_page {
}; };
#define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags))
#define NFS_NEED_COMMIT(req) (test_bit(PG_NEED_COMMIT,&(req)->wb_flags))
#define NFS_NEED_RESCHED(req) (test_bit(PG_NEED_RESCHED,&(req)->wb_flags))
extern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx, extern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx,
struct inode *inode, struct inode *inode,
...@@ -121,34 +119,6 @@ nfs_list_remove_request(struct nfs_page *req) ...@@ -121,34 +119,6 @@ nfs_list_remove_request(struct nfs_page *req)
req->wb_list_head = NULL; req->wb_list_head = NULL;
} }
static inline int
nfs_defer_commit(struct nfs_page *req)
{
return !test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags);
}
static inline void
nfs_clear_commit(struct nfs_page *req)
{
smp_mb__before_clear_bit();
clear_bit(PG_NEED_COMMIT, &req->wb_flags);
smp_mb__after_clear_bit();
}
static inline int
nfs_defer_reschedule(struct nfs_page *req)
{
return !test_and_set_bit(PG_NEED_RESCHED, &req->wb_flags);
}
static inline void
nfs_clear_reschedule(struct nfs_page *req)
{
smp_mb__before_clear_bit();
clear_bit(PG_NEED_RESCHED, &req->wb_flags);
smp_mb__after_clear_bit();
}
static inline struct nfs_page * static inline struct nfs_page *
nfs_list_entry(struct list_head *head) nfs_list_entry(struct list_head *head)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment