NFS41: send real write size in layoutget
For buffer write, block layout client scan inode mapping to find next hole and use offset-to-hole as layoutget length. Object layout client uses offset-to-isize as layoutget length. For direct write, both block layout and object layout use dreq->bytes_left. Signed-off-by: Peng Tao <tao.peng@emc.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:

committed by
Trond Myklebust

parent
35754bc00e
commit
6296556f0b
@@ -37,6 +37,7 @@
|
||||
#include <linux/bio.h> /* struct bio */
|
||||
#include <linux/buffer_head.h> /* various write calls */
|
||||
#include <linux/prefetch.h>
|
||||
#include <linux/pagevec.h>
|
||||
|
||||
#include "../pnfs.h"
|
||||
#include "../internal.h"
|
||||
@@ -1204,14 +1205,45 @@ bl_pg_test_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
|
||||
return pnfs_generic_pg_test(pgio, prev, req);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of contiguous bytes for a given inode
|
||||
* starting at page frame idx.
|
||||
*/
|
||||
static u64 pnfs_num_cont_bytes(struct inode *inode, pgoff_t idx)
|
||||
{
|
||||
struct address_space *mapping = inode->i_mapping;
|
||||
pgoff_t end;
|
||||
|
||||
/* Optimize common case that writes from 0 to end of file */
|
||||
end = DIV_ROUND_UP(i_size_read(inode), PAGE_CACHE_SIZE);
|
||||
if (end != NFS_I(inode)->npages) {
|
||||
rcu_read_lock();
|
||||
end = radix_tree_next_hole(&mapping->page_tree, idx + 1, ULONG_MAX);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
if (!end)
|
||||
return i_size_read(inode) - (idx << PAGE_CACHE_SHIFT);
|
||||
else
|
||||
return (end - idx) << PAGE_CACHE_SHIFT;
|
||||
}
|
||||
|
||||
static void
|
||||
bl_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
|
||||
{
|
||||
if (pgio->pg_dreq != NULL &&
|
||||
!is_aligned_req(req, PAGE_CACHE_SIZE))
|
||||
!is_aligned_req(req, PAGE_CACHE_SIZE)) {
|
||||
nfs_pageio_reset_write_mds(pgio);
|
||||
else
|
||||
pnfs_generic_pg_init_write(pgio, req);
|
||||
} else {
|
||||
u64 wb_size;
|
||||
if (pgio->pg_dreq == NULL)
|
||||
wb_size = pnfs_num_cont_bytes(pgio->pg_inode,
|
||||
req->wb_index);
|
||||
else
|
||||
wb_size = nfs_dreq_bytes_left(pgio->pg_dreq);
|
||||
|
||||
pnfs_generic_pg_init_write(pgio, req, wb_size);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
|
Reference in New Issue
Block a user