Commit 6c2689a5 authored by Trond Myklebust's avatar Trond Myklebust

NFSv2/v3/v4: Prepare the nfs_page struct to allow for short reads.

parent 196c4ebd
...@@ -88,6 +88,7 @@ nfs_create_request(struct file *file, struct inode *inode, ...@@ -88,6 +88,7 @@ nfs_create_request(struct file *file, struct inode *inode,
* long write-back delay. This will be adjusted in * long write-back delay. This will be adjusted in
* update_nfs_request below if the region is not locked. */ * update_nfs_request below if the region is not locked. */
req->wb_page = page; req->wb_page = page;
atomic_set(&req->wb_complete, 0);
req->wb_index = page->index; req->wb_index = page->index;
page_cache_get(page); page_cache_get(page);
req->wb_offset = offset; req->wb_offset = offset;
......
...@@ -17,10 +17,14 @@ ...@@ -17,10 +17,14 @@
#include <linux/sunrpc/auth.h> #include <linux/sunrpc/auth.h>
#include <linux/nfs_xdr.h> #include <linux/nfs_xdr.h>
#include <asm/atomic.h>
/* /*
* Valid flags for a dirty buffer * Valid flags for a dirty buffer
*/ */
#define PG_BUSY 0 #define PG_BUSY 0
#define PG_NEED_COMMIT 1
#define PG_NEED_RESCHED 2
struct nfs_page { struct nfs_page {
struct list_head wb_list, /* Defines state of page: */ struct list_head wb_list, /* Defines state of page: */
...@@ -31,6 +35,7 @@ struct nfs_page { ...@@ -31,6 +35,7 @@ struct nfs_page {
struct rpc_cred *wb_cred; struct rpc_cred *wb_cred;
struct nfs4_state *wb_state; struct nfs4_state *wb_state;
struct page *wb_page; /* page to read in/write out */ struct page *wb_page; /* page to read in/write out */
atomic_t wb_complete; /* i/os we're waiting for */
wait_queue_head_t wb_wait; /* wait queue */ wait_queue_head_t wb_wait; /* wait queue */
unsigned long wb_index; /* Offset >> PAGE_CACHE_SHIFT */ unsigned long wb_index; /* Offset >> PAGE_CACHE_SHIFT */
unsigned int wb_offset, /* Offset & ~PAGE_CACHE_MASK */ unsigned int wb_offset, /* Offset & ~PAGE_CACHE_MASK */
...@@ -42,6 +47,8 @@ struct nfs_page { ...@@ -42,6 +47,8 @@ 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 file *, struct inode *, extern struct nfs_page *nfs_create_request(struct file *, struct inode *,
struct page *, struct page *,
...@@ -115,6 +122,38 @@ nfs_list_remove_request(struct nfs_page *req) ...@@ -115,6 +122,38 @@ 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)
{
if (test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags))
return 0;
return 1;
}
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)
{
if (test_and_set_bit(PG_NEED_RESCHED, &req->wb_flags))
return 0;
return 1;
}
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)
{ {
......
...@@ -656,6 +656,8 @@ struct nfs4_compound { ...@@ -656,6 +656,8 @@ struct nfs4_compound {
#endif /* CONFIG_NFS_V4 */ #endif /* CONFIG_NFS_V4 */
struct nfs_page;
struct nfs_read_data { struct nfs_read_data {
int flags; int flags;
struct rpc_task task; struct rpc_task task;
...@@ -664,12 +666,14 @@ struct nfs_read_data { ...@@ -664,12 +666,14 @@ struct nfs_read_data {
fl_owner_t lockowner; fl_owner_t lockowner;
struct nfs_fattr fattr; /* fattr storage */ struct nfs_fattr fattr; /* fattr storage */
struct list_head pages; /* Coalesced read requests */ struct list_head pages; /* Coalesced read requests */
struct nfs_page *req; /* multi ops per nfs_page */
struct page *pagevec[NFS_READ_MAXIOV]; struct page *pagevec[NFS_READ_MAXIOV];
struct nfs_readargs args; struct nfs_readargs args;
struct nfs_readres res; struct nfs_readres res;
#ifdef CONFIG_NFS_V4 #ifdef CONFIG_NFS_V4
unsigned long timestamp; /* For lease renewal */ unsigned long timestamp; /* For lease renewal */
#endif #endif
void (*complete) (struct nfs_read_data *, int);
}; };
struct nfs_write_data { struct nfs_write_data {
...@@ -681,16 +685,16 @@ struct nfs_write_data { ...@@ -681,16 +685,16 @@ struct nfs_write_data {
struct nfs_fattr fattr; struct nfs_fattr fattr;
struct nfs_writeverf verf; struct nfs_writeverf verf;
struct list_head pages; /* Coalesced requests we wish to flush */ struct list_head pages; /* Coalesced requests we wish to flush */
struct nfs_page *req; /* multi ops per nfs_page */
struct page *pagevec[NFS_WRITE_MAXIOV]; struct page *pagevec[NFS_WRITE_MAXIOV];
struct nfs_writeargs args; /* argument struct */ struct nfs_writeargs args; /* argument struct */
struct nfs_writeres res; /* result struct */ struct nfs_writeres res; /* result struct */
#ifdef CONFIG_NFS_V4 #ifdef CONFIG_NFS_V4
unsigned long timestamp; /* For lease renewal */ unsigned long timestamp; /* For lease renewal */
#endif #endif
void (*complete) (struct nfs_write_data *, int);
}; };
struct nfs_page;
/* /*
* RPC procedure vector for NFSv2/NFSv3 demuxing * RPC procedure vector for NFSv2/NFSv3 demuxing
*/ */
......
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