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