[PATCH] separate page base and file page offset in NFS client

From: Chuck Lever (cel@citi.umich.edu)
Date: Mon Nov 18 2002 - 16:54:45 EST


a pre-requisite for functioning O_DIRECT support for NFS. with this
patch: for each request, the client now stores the in-memory page offset
in a separate field from the file page offset. this allows direct I/O to
target user buffers at arbitrary offsets.

against 2.5.48.

diff -ruN 02-req_offset/fs/nfs/nfs3proc.c 03-wb_base/fs/nfs/nfs3proc.c
--- 02-req_offset/fs/nfs/nfs3proc.c Mon Nov 18 11:46:05 2002
+++ 03-wb_base/fs/nfs/nfs3proc.c Mon Nov 18 11:50:13 2002
@@ -709,7 +709,7 @@
         req = nfs_list_entry(data->pages.next);
         data->u.v3.args.fh = NFS_FH(inode);
         data->u.v3.args.offset = req_offset(req);
- data->u.v3.args.pgbase = req->wb_offset;
+ data->u.v3.args.pgbase = req->wb_base;
         data->u.v3.args.pages = data->pagevec;
         data->u.v3.args.count = count;
         data->u.v3.res.fattr = &data->fattr;
@@ -765,7 +765,7 @@
         req = nfs_list_entry(data->pages.next);
         data->u.v3.args.fh = NFS_FH(inode);
         data->u.v3.args.offset = req_offset(req);
- data->u.v3.args.pgbase = req->wb_offset;
+ data->u.v3.args.pgbase = req->wb_base;
         data->u.v3.args.count = count;
         data->u.v3.args.stable = stable;
         data->u.v3.args.pages = data->pagevec;
diff -ruN 02-req_offset/fs/nfs/nfs4proc.c 03-wb_base/fs/nfs/nfs4proc.c
--- 02-req_offset/fs/nfs/nfs4proc.c Mon Nov 18 11:46:05 2002
+++ 03-wb_base/fs/nfs/nfs4proc.c Mon Nov 18 11:50:13 2002
@@ -1380,7 +1380,7 @@
         nfs4_setup_compound(cp, data->u.v4.ops, NFS_SERVER(inode), "read [async]");
         nfs4_setup_putfh(cp, NFS_FH(inode));
         nfs4_setup_read(cp, req_offset(req),
- count, data->pagevec, req->wb_offset,
+ count, data->pagevec, req->wb_base,
                         &data->u.v4.res_eof,
                         &data->u.v4.res_count);
 
@@ -1433,7 +1433,7 @@
         nfs4_setup_compound(cp, data->u.v4.ops, NFS_SERVER(inode), "write [async]");
         nfs4_setup_putfh(cp, NFS_FH(inode));
         nfs4_setup_write(cp, req_offset(req),
- count, stable, data->pagevec, req->wb_offset,
+ count, stable, data->pagevec, req->wb_base,
                          &data->u.v4.res_count, &data->verf);
 
         /* Set the initial flags for the task. */
diff -ruN 02-req_offset/fs/nfs/pagelist.c 03-wb_base/fs/nfs/pagelist.c
--- 02-req_offset/fs/nfs/pagelist.c Sun Nov 17 23:29:54 2002
+++ 03-wb_base/fs/nfs/pagelist.c Mon Nov 18 11:50:13 2002
@@ -91,6 +91,7 @@
         req->wb_index = page->index;
         page_cache_get(page);
         req->wb_offset = offset;
+ req->wb_base = offset;
         req->wb_bytes = count;
 
         if (cred)
@@ -277,14 +278,13 @@
                                 break;
                         if (req->wb_index != (prev->wb_index + 1))
                                 break;
-
- if (req->wb_offset != 0)
+ if (req->wb_base != 0)
                                 break;
                 }
                 nfs_list_remove_request(req);
                 nfs_list_add_request(req, dst);
                 npages++;
- if (req->wb_offset + req->wb_bytes != PAGE_CACHE_SIZE)
+ if (req->wb_base + req->wb_bytes != PAGE_CACHE_SIZE)
                         break;
                 if (npages >= nmax)
                         break;
diff -ruN 02-req_offset/fs/nfs/proc.c 03-wb_base/fs/nfs/proc.c
--- 02-req_offset/fs/nfs/proc.c Mon Nov 18 11:46:05 2002
+++ 03-wb_base/fs/nfs/proc.c Mon Nov 18 11:50:13 2002
@@ -544,7 +544,7 @@
         req = nfs_list_entry(data->pages.next);
         data->u.v3.args.fh = NFS_FH(inode);
         data->u.v3.args.offset = req_offset(req);
- data->u.v3.args.pgbase = req->wb_offset;
+ data->u.v3.args.pgbase = req->wb_base;
         data->u.v3.args.pages = data->pagevec;
         data->u.v3.args.count = count;
         data->u.v3.res.fattr = &data->fattr;
@@ -590,7 +590,7 @@
         req = nfs_list_entry(data->pages.next);
         data->u.v3.args.fh = NFS_FH(inode);
         data->u.v3.args.offset = req_offset(req);
- data->u.v3.args.pgbase = req->wb_offset;
+ data->u.v3.args.pgbase = req->wb_base;
         data->u.v3.args.count = count;
         data->u.v3.args.stable = NFS_FILE_SYNC;
         data->u.v3.args.pages = data->pagevec;
diff -ruN 02-req_offset/fs/nfs/read.c 03-wb_base/fs/nfs/read.c
--- 02-req_offset/fs/nfs/read.c Mon Nov 18 11:46:05 2002
+++ 03-wb_base/fs/nfs/read.c Mon Nov 18 11:50:13 2002
@@ -269,7 +269,7 @@
                 if (task->tk_status >= 0) {
                         if (count < PAGE_CACHE_SIZE) {
                                 memclear_highpage_flush(page,
- req->wb_offset + count,
+ req->wb_base + count,
                                                         req->wb_bytes - count);
 
                                 if (eof ||
diff -ruN 02-req_offset/fs/nfs/write.c 03-wb_base/fs/nfs/write.c
--- 02-req_offset/fs/nfs/write.c Mon Nov 18 11:46:05 2002
+++ 03-wb_base/fs/nfs/write.c Mon Nov 18 11:50:13 2002
@@ -586,6 +586,7 @@
         /* Okay, the request matches. Update the region */
         if (offset < req->wb_offset) {
                 req->wb_offset = offset;
+ req->wb_base = offset;
                 req->wb_bytes = rqend - req->wb_offset;
         }
 
@@ -718,7 +719,7 @@
          * Call the strategy routine so it can send out a bunch
          * of requests.
          */
- if (req->wb_offset == 0 && req->wb_bytes == PAGE_CACHE_SIZE) {
+ if (req->wb_base == 0 && req->wb_bytes == PAGE_CACHE_SIZE) {
                 SetPageUptodate(page);
                 nfs_unlock_request(req);
                 nfs_strategy(inode);
diff -ruN 02-req_offset/include/linux/nfs_page.h 03-wb_base/include/linux/nfs_page.h
--- 02-req_offset/include/linux/nfs_page.h Sun Nov 17 23:29:22 2002
+++ 03-wb_base/include/linux/nfs_page.h Mon Nov 18 11:50:13 2002
@@ -31,7 +31,8 @@
         struct page *wb_page; /* page to read in/write out */
         wait_queue_head_t wb_wait; /* wait queue */
         unsigned long wb_index; /* Offset within mapping */
- unsigned int wb_offset, /* Offset within page */
+ unsigned int wb_offset, /* Offset within file page */
+ wb_base, /* Offset within buffer page */
                                 wb_bytes, /* Length of request */
                                 wb_count; /* reference count */
         unsigned long wb_flags;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sat Nov 23 2002 - 22:00:24 EST