Commit e2c63e09 authored by Trond Myklebust's avatar Trond Myklebust

Merge branch 'flexfiles'

* flexfiles: (53 commits)
  pnfs: lookup new lseg at lseg boundary
  nfs41: .init_read and .init_write can be called with valid pg_lseg
  pnfs: Update documentation on the Layout Drivers
  pnfs/flexfiles: Add the FlexFile Layout Driver
  nfs: count DIO good bytes correctly with mirroring
  nfs41: wait for LAYOUTRETURN before retrying LAYOUTGET
  nfs: add a helper to set NFS_ODIRECT_RESCHED_WRITES to direct writes
  nfs41: add NFS_LAYOUT_RETRY_LAYOUTGET to layout header flags
  nfs/flexfiles: send layoutreturn before freeing lseg
  nfs41: introduce NFS_LAYOUT_RETURN_BEFORE_CLOSE
  nfs41: allow async version layoutreturn
  nfs41: add range to layoutreturn args
  pnfs: allow LD to ask to resend read through pnfs
  nfs: add nfs_pgio_current_mirror helper
  nfs: only reset desc->pg_mirror_idx when mirroring is supported
  nfs41: add a debug warning if we destroy an unempty layout
  pnfs: fail comparison when bucket verifier not set
  nfs: mirroring support for direct io
  nfs: add mirroring support to pgio layer
  pnfs: pass ds_commit_idx through the commit path
  ...

Conflicts:
	fs/nfs/pnfs.c
	fs/nfs/pnfs.h
parents cc3ea893 7c13789e
...@@ -57,15 +57,16 @@ bit is set, preventing any new lsegs from being added. ...@@ -57,15 +57,16 @@ bit is set, preventing any new lsegs from being added.
layout drivers layout drivers
-------------- --------------
PNFS utilizes what is called layout drivers. The STD defines 3 basic PNFS utilizes what is called layout drivers. The STD defines 4 basic
layout types: "files" "objects" and "blocks". For each of these types layout types: "files", "objects", "blocks", and "flexfiles". For each
there is a layout-driver with a common function-vectors table which of these types there is a layout-driver with a common function-vectors
are called by the nfs-client pnfs-core to implement the different layout table which are called by the nfs-client pnfs-core to implement the
types. different layout types.
Files-layout-driver code is in: fs/nfs/nfs4filelayout.c && nfs4filelayoutdev.c Files-layout-driver code is in: fs/nfs/filelayout/.. directory
Objects-layout-deriver code is in: fs/nfs/objlayout/.. directory Objects-layout-deriver code is in: fs/nfs/objlayout/.. directory
Blocks-layout-deriver code is in: fs/nfs/blocklayout/.. directory Blocks-layout-deriver code is in: fs/nfs/blocklayout/.. directory
Flexfiles-layout-driver code is in: fs/nfs/flexfilelayout/.. directory
objects-layout setup objects-layout setup
-------------------- --------------------
......
...@@ -128,6 +128,11 @@ config PNFS_OBJLAYOUT ...@@ -128,6 +128,11 @@ config PNFS_OBJLAYOUT
depends on NFS_V4_1 && SCSI_OSD_ULD depends on NFS_V4_1 && SCSI_OSD_ULD
default NFS_V4 default NFS_V4
config PNFS_FLEXFILE_LAYOUT
tristate
depends on NFS_V4_1 && NFS_V3
default m
config NFS_V4_1_IMPLEMENTATION_ID_DOMAIN config NFS_V4_1_IMPLEMENTATION_ID_DOMAIN
string "NFSv4.1 Implementation ID Domain" string "NFSv4.1 Implementation ID Domain"
depends on NFS_V4_1 depends on NFS_V4_1
......
...@@ -27,9 +27,10 @@ nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o ...@@ -27,9 +27,10 @@ nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o
dns_resolve.o nfs4trace.o dns_resolve.o nfs4trace.o
nfsv4-$(CONFIG_NFS_USE_LEGACY_DNS) += cache_lib.o nfsv4-$(CONFIG_NFS_USE_LEGACY_DNS) += cache_lib.o
nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o
nfsv4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o nfsv4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o pnfs_nfs.o
nfsv4-$(CONFIG_NFS_V4_2) += nfs42proc.o nfsv4-$(CONFIG_NFS_V4_2) += nfs42proc.o
obj-$(CONFIG_PNFS_FILE_LAYOUT) += filelayout/ obj-$(CONFIG_PNFS_FILE_LAYOUT) += filelayout/
obj-$(CONFIG_PNFS_OBJLAYOUT) += objlayout/ obj-$(CONFIG_PNFS_OBJLAYOUT) += objlayout/
obj-$(CONFIG_PNFS_BLOCK) += blocklayout/ obj-$(CONFIG_PNFS_BLOCK) += blocklayout/
obj-$(CONFIG_PNFS_FLEXFILE_LAYOUT) += flexfilelayout/
...@@ -860,12 +860,14 @@ static const struct nfs_pageio_ops bl_pg_read_ops = { ...@@ -860,12 +860,14 @@ static const struct nfs_pageio_ops bl_pg_read_ops = {
.pg_init = bl_pg_init_read, .pg_init = bl_pg_init_read,
.pg_test = bl_pg_test_read, .pg_test = bl_pg_test_read,
.pg_doio = pnfs_generic_pg_readpages, .pg_doio = pnfs_generic_pg_readpages,
.pg_cleanup = pnfs_generic_pg_cleanup,
}; };
static const struct nfs_pageio_ops bl_pg_write_ops = { static const struct nfs_pageio_ops bl_pg_write_ops = {
.pg_init = bl_pg_init_write, .pg_init = bl_pg_init_write,
.pg_test = bl_pg_test_write, .pg_test = bl_pg_test_write,
.pg_doio = pnfs_generic_pg_writepages, .pg_doio = pnfs_generic_pg_writepages,
.pg_cleanup = pnfs_generic_pg_cleanup,
}; };
static struct pnfs_layoutdriver_type blocklayout_type = { static struct pnfs_layoutdriver_type blocklayout_type = {
......
...@@ -66,6 +66,10 @@ static struct kmem_cache *nfs_direct_cachep; ...@@ -66,6 +66,10 @@ static struct kmem_cache *nfs_direct_cachep;
/* /*
* This represents a set of asynchronous requests that we're waiting on * This represents a set of asynchronous requests that we're waiting on
*/ */
struct nfs_direct_mirror {
ssize_t count;
};
struct nfs_direct_req { struct nfs_direct_req {
struct kref kref; /* release manager */ struct kref kref; /* release manager */
...@@ -78,8 +82,13 @@ struct nfs_direct_req { ...@@ -78,8 +82,13 @@ struct nfs_direct_req {
/* completion state */ /* completion state */
atomic_t io_count; /* i/os we're waiting for */ atomic_t io_count; /* i/os we're waiting for */
spinlock_t lock; /* protect completion state */ spinlock_t lock; /* protect completion state */
struct nfs_direct_mirror mirrors[NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX];
int mirror_count;
ssize_t count, /* bytes actually processed */ ssize_t count, /* bytes actually processed */
bytes_left, /* bytes left to be sent */ bytes_left, /* bytes left to be sent */
io_start, /* start of IO */
error; /* any reported error */ error; /* any reported error */
struct completion completion; /* wait for i/o completion */ struct completion completion; /* wait for i/o completion */
...@@ -108,26 +117,56 @@ static inline int put_dreq(struct nfs_direct_req *dreq) ...@@ -108,26 +117,56 @@ static inline int put_dreq(struct nfs_direct_req *dreq)
return atomic_dec_and_test(&dreq->io_count); return atomic_dec_and_test(&dreq->io_count);
} }
void nfs_direct_set_resched_writes(struct nfs_direct_req *dreq)
{
dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
}
EXPORT_SYMBOL_GPL(nfs_direct_set_resched_writes);
static void
nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr)
{
int i;
ssize_t count;
WARN_ON_ONCE(hdr->pgio_mirror_idx >= dreq->mirror_count);
count = dreq->mirrors[hdr->pgio_mirror_idx].count;
if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) {
count = hdr->io_start + hdr->good_bytes - dreq->io_start;
dreq->mirrors[hdr->pgio_mirror_idx].count = count;
}
/* update the dreq->count by finding the minimum agreed count from all
* mirrors */
count = dreq->mirrors[0].count;
for (i = 1; i < dreq->mirror_count; i++)
count = min(count, dreq->mirrors[i].count);
dreq->count = count;
}
/* /*
* nfs_direct_select_verf - select the right verifier * nfs_direct_select_verf - select the right verifier
* @dreq - direct request possibly spanning multiple servers * @dreq - direct request possibly spanning multiple servers
* @ds_clp - nfs_client of data server or NULL if MDS / non-pnfs * @ds_clp - nfs_client of data server or NULL if MDS / non-pnfs
* @ds_idx - index of data server in data server list, only valid if ds_clp set * @commit_idx - commit bucket index for the DS
* *
* returns the correct verifier to use given the role of the server * returns the correct verifier to use given the role of the server
*/ */
static struct nfs_writeverf * static struct nfs_writeverf *
nfs_direct_select_verf(struct nfs_direct_req *dreq, nfs_direct_select_verf(struct nfs_direct_req *dreq,
struct nfs_client *ds_clp, struct nfs_client *ds_clp,
int ds_idx) int commit_idx)
{ {
struct nfs_writeverf *verfp = &dreq->verf; struct nfs_writeverf *verfp = &dreq->verf;
#ifdef CONFIG_NFS_V4_1 #ifdef CONFIG_NFS_V4_1
if (ds_clp) { if (ds_clp) {
/* pNFS is in use, use the DS verf */ /* pNFS is in use, use the DS verf */
if (ds_idx >= 0 && ds_idx < dreq->ds_cinfo.nbuckets) if (commit_idx >= 0 && commit_idx < dreq->ds_cinfo.nbuckets)
verfp = &dreq->ds_cinfo.buckets[ds_idx].direct_verf; verfp = &dreq->ds_cinfo.buckets[commit_idx].direct_verf;
else else
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
} }
...@@ -148,8 +187,7 @@ static void nfs_direct_set_hdr_verf(struct nfs_direct_req *dreq, ...@@ -148,8 +187,7 @@ static void nfs_direct_set_hdr_verf(struct nfs_direct_req *dreq,
{ {
struct nfs_writeverf *verfp; struct nfs_writeverf *verfp;
verfp = nfs_direct_select_verf(dreq, hdr->ds_clp, verfp = nfs_direct_select_verf(dreq, hdr->ds_clp, hdr->ds_commit_idx);
hdr->ds_idx);
WARN_ON_ONCE(verfp->committed >= 0); WARN_ON_ONCE(verfp->committed >= 0);
memcpy(verfp, &hdr->verf, sizeof(struct nfs_writeverf)); memcpy(verfp, &hdr->verf, sizeof(struct nfs_writeverf));
WARN_ON_ONCE(verfp->committed < 0); WARN_ON_ONCE(verfp->committed < 0);
...@@ -169,8 +207,7 @@ static int nfs_direct_set_or_cmp_hdr_verf(struct nfs_direct_req *dreq, ...@@ -169,8 +207,7 @@ static int nfs_direct_set_or_cmp_hdr_verf(struct nfs_direct_req *dreq,
{ {
struct nfs_writeverf *verfp; struct nfs_writeverf *verfp;
verfp = nfs_direct_select_verf(dreq, hdr->ds_clp, verfp = nfs_direct_select_verf(dreq, hdr->ds_clp, hdr->ds_commit_idx);
hdr->ds_idx);
if (verfp->committed < 0) { if (verfp->committed < 0) {
nfs_direct_set_hdr_verf(dreq, hdr); nfs_direct_set_hdr_verf(dreq, hdr);
return 0; return 0;
...@@ -193,7 +230,11 @@ static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq, ...@@ -193,7 +230,11 @@ static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq,
verfp = nfs_direct_select_verf(dreq, data->ds_clp, verfp = nfs_direct_select_verf(dreq, data->ds_clp,
data->ds_commit_index); data->ds_commit_index);
WARN_ON_ONCE(verfp->committed < 0);
/* verifier not set so always fail */
if (verfp->committed < 0)
return 1;
return memcmp(verfp, &data->verf, sizeof(struct nfs_writeverf)); return memcmp(verfp, &data->verf, sizeof(struct nfs_writeverf));
} }
...@@ -249,6 +290,18 @@ void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, ...@@ -249,6 +290,18 @@ void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,
cinfo->completion_ops = &nfs_direct_commit_completion_ops; cinfo->completion_ops = &nfs_direct_commit_completion_ops;
} }
static inline void nfs_direct_setup_mirroring(struct nfs_direct_req *dreq,
struct nfs_pageio_descriptor *pgio,
struct nfs_page *req)
{
int mirror_count = 1;
if (pgio->pg_ops->pg_get_mirror_count)
mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req);
dreq->mirror_count = mirror_count;
}
static inline struct nfs_direct_req *nfs_direct_req_alloc(void) static inline struct nfs_direct_req *nfs_direct_req_alloc(void)
{ {
struct nfs_direct_req *dreq; struct nfs_direct_req *dreq;
...@@ -263,6 +316,7 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void) ...@@ -263,6 +316,7 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void)
INIT_LIST_HEAD(&dreq->mds_cinfo.list); INIT_LIST_HEAD(&dreq->mds_cinfo.list);
dreq->verf.committed = NFS_INVALID_STABLE_HOW; /* not set yet */ dreq->verf.committed = NFS_INVALID_STABLE_HOW; /* not set yet */
INIT_WORK(&dreq->work, nfs_direct_write_schedule_work); INIT_WORK(&dreq->work, nfs_direct_write_schedule_work);
dreq->mirror_count = 1;
spin_lock_init(&dreq->lock); spin_lock_init(&dreq->lock);
return dreq; return dreq;
...@@ -369,7 +423,8 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr) ...@@ -369,7 +423,8 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && (hdr->good_bytes == 0)) if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && (hdr->good_bytes == 0))
dreq->error = hdr->error; dreq->error = hdr->error;
else else
dreq->count += hdr->good_bytes; nfs_direct_good_bytes(dreq, hdr);
spin_unlock(&dreq->lock); spin_unlock(&dreq->lock);
while (!list_empty(&hdr->pages)) { while (!list_empty(&hdr->pages)) {
...@@ -547,6 +602,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter, ...@@ -547,6 +602,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter,
dreq->inode = inode; dreq->inode = inode;
dreq->bytes_left = count; dreq->bytes_left = count;
dreq->io_start = pos;
dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
l_ctx = nfs_get_lock_context(dreq->ctx); l_ctx = nfs_get_lock_context(dreq->ctx);
if (IS_ERR(l_ctx)) { if (IS_ERR(l_ctx)) {
...@@ -579,6 +635,20 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter, ...@@ -579,6 +635,20 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter,
return result; return result;
} }
static void
nfs_direct_write_scan_commit_list(struct inode *inode,
struct list_head *list,
struct nfs_commit_info *cinfo)
{
spin_lock(cinfo->lock);
#ifdef CONFIG_NFS_V4_1
if (cinfo->ds != NULL && cinfo->ds->nwritten != 0)
NFS_SERVER(inode)->pnfs_curr_ld->recover_commit_reqs(list, cinfo);
#endif
nfs_scan_commit_list(&cinfo->mds->list, list, cinfo, 0);
spin_unlock(cinfo->lock);
}
static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
{ {
struct nfs_pageio_descriptor desc; struct nfs_pageio_descriptor desc;
...@@ -586,20 +656,23 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) ...@@ -586,20 +656,23 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
LIST_HEAD(reqs); LIST_HEAD(reqs);
struct nfs_commit_info cinfo; struct nfs_commit_info cinfo;
LIST_HEAD(failed); LIST_HEAD(failed);
int i;
nfs_init_cinfo_from_dreq(&cinfo, dreq); nfs_init_cinfo_from_dreq(&cinfo, dreq);
pnfs_recover_commit_reqs(dreq->inode, &reqs, &cinfo); nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo);
spin_lock(cinfo.lock);
nfs_scan_commit_list(&cinfo.mds->list, &reqs, &cinfo, 0);
spin_unlock(cinfo.lock);
dreq->count = 0; dreq->count = 0;
for (i = 0; i < dreq->mirror_count; i++)
dreq->mirrors[i].count = 0;
get_dreq(dreq); get_dreq(dreq);
nfs_pageio_init_write(&desc, dreq->inode, FLUSH_STABLE, false, nfs_pageio_init_write(&desc, dreq->inode, FLUSH_STABLE, false,
&nfs_direct_write_completion_ops); &nfs_direct_write_completion_ops);
desc.pg_dreq = dreq; desc.pg_dreq = dreq;
req = nfs_list_entry(reqs.next);
nfs_direct_setup_mirroring(dreq, &desc, req);
list_for_each_entry_safe(req, tmp, &reqs, wb_list) { list_for_each_entry_safe(req, tmp, &reqs, wb_list) {
if (!nfs_pageio_add_request(&desc, req)) { if (!nfs_pageio_add_request(&desc, req)) {
nfs_list_remove_request(req); nfs_list_remove_request(req);
...@@ -646,7 +719,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) ...@@ -646,7 +719,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
nfs_list_remove_request(req); nfs_list_remove_request(req);
if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) { if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) {
/* Note the rewrite will go through mds */ /* Note the rewrite will go through mds */
nfs_mark_request_commit(req, NULL, &cinfo); nfs_mark_request_commit(req, NULL, &cinfo, 0);
} else } else
nfs_release_request(req); nfs_release_request(req);
nfs_unlock_and_release_request(req); nfs_unlock_and_release_request(req);
...@@ -721,7 +794,7 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr) ...@@ -721,7 +794,7 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
dreq->error = hdr->error; dreq->error = hdr->error;
} }
if (dreq->error == 0) { if (dreq->error == 0) {
dreq->count += hdr->good_bytes; nfs_direct_good_bytes(dreq, hdr);
if (nfs_write_need_commit(hdr)) { if (nfs_write_need_commit(hdr)) {
if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES)
request_commit = true; request_commit = true;
...@@ -745,7 +818,8 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr) ...@@ -745,7 +818,8 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
nfs_list_remove_request(req); nfs_list_remove_request(req);
if (request_commit) { if (request_commit) {
kref_get(&req->wb_kref); kref_get(&req->wb_kref);
nfs_mark_request_commit(req, hdr->lseg, &cinfo); nfs_mark_request_commit(req, hdr->lseg, &cinfo,
hdr->ds_commit_idx);
} }
nfs_unlock_and_release_request(req); nfs_unlock_and_release_request(req);
} }
...@@ -826,6 +900,9 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, ...@@ -826,6 +900,9 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
result = PTR_ERR(req); result = PTR_ERR(req);
break; break;
} }
nfs_direct_setup_mirroring(dreq, &desc, req);
nfs_lock_request(req); nfs_lock_request(req);
req->wb_index = pos >> PAGE_SHIFT; req->wb_index = pos >> PAGE_SHIFT;
req->wb_offset = pos & ~PAGE_MASK; req->wb_offset = pos & ~PAGE_MASK;
...@@ -934,6 +1011,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter, ...@@ -934,6 +1011,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter,
dreq->inode = inode; dreq->inode = inode;
dreq->bytes_left = count; dreq->bytes_left = count;
dreq->io_start = pos;
dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
l_ctx = nfs_get_lock_context(dreq->ctx); l_ctx = nfs_get_lock_context(dreq->ctx);
if (IS_ERR(l_ctx)) { if (IS_ERR(l_ctx)) {
......
This diff is collapsed.
...@@ -32,13 +32,6 @@ ...@@ -32,13 +32,6 @@
#include "../pnfs.h" #include "../pnfs.h"
/*
* Default data server connection timeout and retrans vaules.
* Set by module paramters dataserver_timeo and dataserver_retrans.
*/
#define NFS4_DEF_DS_TIMEO 600 /* in tenths of a second */
#define NFS4_DEF_DS_RETRANS 5
/* /*
* Field testing shows we need to support up to 4096 stripe indices. * Field testing shows we need to support up to 4096 stripe indices.
* We store each index as a u8 (u32 on the wire) to keep the memory footprint * We store each index as a u8 (u32 on the wire) to keep the memory footprint
...@@ -48,32 +41,11 @@ ...@@ -48,32 +41,11 @@
#define NFS4_PNFS_MAX_STRIPE_CNT 4096 #define NFS4_PNFS_MAX_STRIPE_CNT 4096
#define NFS4_PNFS_MAX_MULTI_CNT 256 /* 256 fit into a u8 stripe_index */ #define NFS4_PNFS_MAX_MULTI_CNT 256 /* 256 fit into a u8 stripe_index */
/* error codes for internal use */
#define NFS4ERR_RESET_TO_MDS 12001
enum stripetype4 { enum stripetype4 {
STRIPE_SPARSE = 1, STRIPE_SPARSE = 1,
STRIPE_DENSE = 2 STRIPE_DENSE = 2
}; };
/* Individual ip address */
struct nfs4_pnfs_ds_addr {
struct sockaddr_storage da_addr;
size_t da_addrlen;
struct list_head da_node; /* nfs4_pnfs_dev_hlist dev_dslist */
char *da_remotestr; /* human readable addr+port */
};
struct nfs4_pnfs_ds {
struct list_head ds_node; /* nfs4_pnfs_dev_hlist dev_dslist */
char *ds_remotestr; /* comma sep list of addrs */
struct list_head ds_addrs;
struct nfs_client *ds_clp;
atomic_t ds_count;
unsigned long ds_state;
#define NFS4DS_CONNECTING 0 /* ds is establishing connection */
};
struct nfs4_file_layout_dsaddr { struct nfs4_file_layout_dsaddr {
struct nfs4_deviceid_node id_node; struct nfs4_deviceid_node id_node;
u32 stripe_count; u32 stripe_count;
...@@ -119,17 +91,6 @@ FILELAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg) ...@@ -119,17 +91,6 @@ FILELAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg)
return &FILELAYOUT_LSEG(lseg)->dsaddr->id_node; return &FILELAYOUT_LSEG(lseg)->dsaddr->id_node;
} }
static inline void
filelayout_mark_devid_invalid(struct nfs4_deviceid_node *node)
{
u32 *p = (u32 *)&node->deviceid;
printk(KERN_WARNING "NFS: Deviceid [%x%x%x%x] marked out of use.\n",
p[0], p[1], p[2], p[3]);
set_bit(NFS_DEVICEID_INVALID, &node->flags);
}
static inline bool static inline bool
filelayout_test_devid_invalid(struct nfs4_deviceid_node *node) filelayout_test_devid_invalid(struct nfs4_deviceid_node *node)
{ {
...@@ -142,7 +103,6 @@ filelayout_test_devid_unavailable(struct nfs4_deviceid_node *node); ...@@ -142,7 +103,6 @@ filelayout_test_devid_unavailable(struct nfs4_deviceid_node *node);
extern struct nfs_fh * extern struct nfs_fh *
nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j); nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j);
extern void print_ds(struct nfs4_pnfs_ds *ds);
u32 nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset); u32 nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset);
u32 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j); u32 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j);
struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg,
......
This diff is collapsed.
#
# Makefile for the pNFS Flexfile Layout Driver kernel module
#
obj-$(CONFIG_PNFS_FLEXFILE_LAYOUT) += nfs_layout_flexfiles.o
nfs_layout_flexfiles-y := flexfilelayout.o flexfilelayoutdev.o
This diff is collapsed.
/*
* NFSv4 flexfile layout driver data structures.
*
* Copyright (c) 2014, Primary Data, Inc. All rights reserved.
*
* Tao Peng <bergwolf@primarydata.com>
*/
#ifndef FS_NFS_NFS4FLEXFILELAYOUT_H
#define FS_NFS_NFS4FLEXFILELAYOUT_H
#include "../pnfs.h"
/* XXX: Let's filter out insanely large mirror count for now to avoid oom
* due to network error etc. */
#define NFS4_FLEXFILE_LAYOUT_MAX_MIRROR_CNT 4096
struct nfs4_ff_ds_version {
u32 version;
u32 minor_version;
u32 rsize;
u32 wsize;
bool tightly_coupled;
};
/* chained in global deviceid hlist */
struct nfs4_ff_layout_ds {
struct nfs4_deviceid_node id_node;
u32 ds_versions_cnt;
struct nfs4_ff_ds_version *ds_versions;
struct nfs4_pnfs_ds *ds;
};
struct nfs4_ff_layout_ds_err {
struct list_head list; /* linked in mirror error_list */
u64 offset;
u64 length;
int status;
enum nfs_opnum4 opnum;
nfs4_stateid stateid;
struct nfs4_deviceid deviceid;
};
struct nfs4_ff_layout_mirror {
u32 ds_count;
u32 efficiency;
struct nfs4_ff_layout_ds *mirror_ds;
u32 fh_versions_cnt;
struct nfs_fh *fh_versions;
nfs4_stateid stateid;
struct nfs4_string user_name;
struct nfs4_string group_name;
u32 uid;
u32 gid;
struct rpc_cred *cred;
spinlock_t lock;
};
struct nfs4_ff_layout_segment {
struct pnfs_layout_segment generic_hdr;
u64 stripe_unit;
u32 mirror_array_cnt;
struct nfs4_ff_layout_mirror **mirror_array;
};
struct nfs4_flexfile_layout {
struct pnfs_layout_hdr generic_hdr;
struct pnfs_ds_commit_info commit_info;
struct list_head error_list; /* nfs4_ff_layout_ds_err */
};
static inline struct nfs4_flexfile_layout *
FF_LAYOUT_FROM_HDR(struct pnfs_layout_hdr *lo)
{
return container_of(lo, struct nfs4_flexfile_layout, generic_hdr);
}
static inline struct nfs4_ff_layout_segment *
FF_LAYOUT_LSEG(struct pnfs_layout_segment *lseg)
{
return container_of(lseg,
struct nfs4_ff_layout_segment,
generic_hdr);
}
static inline struct nfs4_deviceid_node *
FF_LAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg, u32 idx)
{
if (idx >= FF_LAYOUT_LSEG(lseg)->mirror_array_cnt ||
FF_LAYOUT_LSEG(lseg)->mirror_array[idx] == NULL ||
FF_LAYOUT_LSEG(lseg)->mirror_array[idx]->mirror_ds == NULL)
return NULL;
return &FF_LAYOUT_LSEG(lseg)->mirror_array[idx]->mirror_ds->id_node;
}
static inline struct nfs4_ff_layout_ds *
FF_LAYOUT_MIRROR_DS(struct nfs4_deviceid_node *node)
{
return container_of(node, struct nfs4_ff_layout_ds, id_node);
}
static inline struct nfs4_ff_layout_mirror *
FF_LAYOUT_COMP(struct pnfs_layout_segment *lseg, u32 idx)
{
if (idx >= FF_LAYOUT_LSEG(lseg)->mirror_array_cnt)
return NULL;
return FF_LAYOUT_LSEG(lseg)->mirror_array[idx];
}
static inline u32
FF_LAYOUT_MIRROR_COUNT(struct pnfs_layout_segment *lseg)
{
return FF_LAYOUT_LSEG(lseg)->mirror_array_cnt;
}
static inline bool
ff_layout_test_devid_unavailable(struct nfs4_deviceid_node *node)
{
return nfs4_test_deviceid_unavailable(node);
}
static inline int
nfs4_ff_layout_ds_version(struct pnfs_layout_segment *lseg, u32 ds_idx)
{
return FF_LAYOUT_COMP(lseg, ds_idx)->mirror_ds->ds_versions[0].version;
}
struct nfs4_ff_layout_ds *
nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
gfp_t gfp_flags);
void nfs4_ff_layout_put_deviceid(struct nfs4_ff_layout_ds *mirror_ds);
void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds);
int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
struct nfs4_ff_layout_mirror *mirror, u64 offset,
u64 length, int status, enum nfs_opnum4 opnum,
gfp_t gfp_flags);
int ff_layout_encode_ds_ioerr(struct nfs4_flexfile_layout *flo,
struct xdr_stream *xdr, int *count,
const struct pnfs_layout_range *range);
struct nfs_fh *
nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx);
struct nfs4_pnfs_ds *
nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
bool fail_return);
struct rpc_clnt *
nfs4_ff_find_or_create_ds_client(struct pnfs_layout_segment *lseg,
u32 ds_idx,
struct nfs_client *ds_clp,
struct inode *inode);
struct rpc_cred *ff_layout_get_ds_cred(struct pnfs_layout_segment *lseg,
u32 ds_idx, struct rpc_cred *mdscred);
bool ff_layout_has_available_ds(struct pnfs_layout_segment *lseg);
#endif /* FS_NFS_NFS4FLEXFILELAYOUT_H */
This diff is collapsed.
...@@ -152,7 +152,7 @@ void nfs_fattr_map_and_free_names(struct nfs_server *server, struct nfs_fattr *f ...@@ -152,7 +152,7 @@ void nfs_fattr_map_and_free_names(struct nfs_server *server, struct nfs_fattr *f
nfs_fattr_free_group_name(fattr); nfs_fattr_free_group_name(fattr);
} }
static int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *res) int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *res)
{ {
unsigned long val; unsigned long val;
char buf[16]; char buf[16];
...@@ -166,6 +166,7 @@ static int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *re ...@@ -166,6 +166,7 @@ static int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *re
*res = val; *res = val;
return 1; return 1;
} }
EXPORT_SYMBOL_GPL(nfs_map_string_to_numeric);
static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen) static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen)
{ {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/nfs_page.h>
#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS) #define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
...@@ -187,9 +188,15 @@ extern struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp, ...@@ -187,9 +188,15 @@ extern struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
const struct sockaddr *ds_addr, const struct sockaddr *ds_addr,
int ds_addrlen, int ds_proto, int ds_addrlen, int ds_proto,
unsigned int ds_timeo, unsigned int ds_timeo,
unsigned int ds_retrans); unsigned int ds_retrans,
u32 minor_version,
rpc_authflavor_t au_flavor);
extern struct rpc_clnt *nfs4_find_or_create_ds_client(struct nfs_client *, extern struct rpc_clnt *nfs4_find_or_create_ds_client(struct nfs_client *,
struct inode *); struct inode *);
extern struct nfs_client *nfs3_set_ds_client(struct nfs_client *mds_clp,
const struct sockaddr *ds_addr, int ds_addrlen,
int ds_proto, unsigned int ds_timeo,
unsigned int ds_retrans, rpc_authflavor_t au_flavor);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
extern int __init nfs_fs_proc_init(void); extern int __init nfs_fs_proc_init(void);
extern void nfs_fs_proc_exit(void); extern void nfs_fs_proc_exit(void);
...@@ -242,9 +249,12 @@ struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *); ...@@ -242,9 +249,12 @@ struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *);
void nfs_pgio_header_free(struct nfs_pgio_header *); void nfs_pgio_header_free(struct nfs_pgio_header *);
void nfs_pgio_data_destroy(struct nfs_pgio_header *); void nfs_pgio_data_destroy(struct nfs_pgio_header *);
int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *); int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *);
int nfs_initiate_pgio(struct rpc_clnt *, struct nfs_pgio_header *, int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
const struct rpc_call_ops *, int, int); struct rpc_cred *cred, const struct nfs_rpc_ops *rpc_ops,
const struct rpc_call_ops *call_ops, int how, int flags);
void nfs_free_request(struct nfs_page *req); void nfs_free_request(struct nfs_page *req);
struct nfs_pgio_mirror *
nfs_pgio_current_mirror(struct nfs_pageio_descriptor *desc);
static inline void nfs_iocounter_init(struct nfs_io_counter *c) static inline void nfs_iocounter_init(struct nfs_io_counter *c)
{ {
...@@ -252,6 +262,12 @@ static inline void nfs_iocounter_init(struct nfs_io_counter *c) ...@@ -252,6 +262,12 @@ static inline void nfs_iocounter_init(struct nfs_io_counter *c)
atomic_set(&c->io_count, 0); atomic_set(&c->io_count, 0);
} }
static inline bool nfs_pgio_has_mirroring(struct nfs_pageio_descriptor *desc)
{
WARN_ON_ONCE(desc->pg_mirror_count < 1);
return desc->pg_mirror_count > 1;
}
/* nfs2xdr.c */ /* nfs2xdr.c */
extern struct rpc_procinfo nfs_procedures[]; extern struct rpc_procinfo nfs_procedures[];
extern int nfs2_decode_dirent(struct xdr_stream *, extern int nfs2_decode_dirent(struct xdr_stream *,
...@@ -427,6 +443,7 @@ extern void nfs_write_prepare(struct rpc_task *task, void *calldata); ...@@ -427,6 +443,7 @@ extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
extern void nfs_commit_prepare(struct rpc_task *task, void *calldata); extern void nfs_commit_prepare(struct rpc_task *task, void *calldata);
extern int nfs_initiate_commit(struct rpc_clnt *clnt, extern int nfs_initiate_commit(struct rpc_clnt *clnt,
struct nfs_commit_data *data, struct nfs_commit_data *data,
const struct nfs_rpc_ops *nfs_ops,
const struct rpc_call_ops *call_ops, const struct rpc_call_ops *call_ops,
int how, int flags); int how, int flags);
extern void nfs_init_commit(struct nfs_commit_data *data, extern void nfs_init_commit(struct nfs_commit_data *data,
...@@ -440,13 +457,15 @@ int nfs_scan_commit(struct inode *inode, struct list_head *dst, ...@@ -440,13 +457,15 @@ int nfs_scan_commit(struct inode *inode, struct list_head *dst,
struct nfs_commit_info *cinfo); struct nfs_commit_info *cinfo);
void nfs_mark_request_commit(struct nfs_page *req, void nfs_mark_request_commit(struct nfs_page *req,
struct pnfs_layout_segment *lseg, struct pnfs_layout_segment *lseg,
struct nfs_commit_info *cinfo); struct nfs_commit_info *cinfo,
u32 ds_commit_idx);
int nfs_write_need_commit(struct nfs_pgio_header *); int nfs_write_need_commit(struct nfs_pgio_header *);
int nfs_generic_commit_list(struct inode *inode, struct list_head *head, int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
int how, struct nfs_commit_info *cinfo); int how, struct nfs_commit_info *cinfo);
void nfs_retry_commit(struct list_head *page_list, void nfs_retry_commit(struct list_head *page_list,
struct pnfs_layout_segment *lseg, struct pnfs_layout_segment *lseg,
struct nfs_commit_info *cinfo); struct nfs_commit_info *cinfo,
u32 ds_commit_idx);
void nfs_commitdata_release(struct nfs_commit_data *data); void nfs_commitdata_release(struct nfs_commit_data *data);
void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst, void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst,
struct nfs_commit_info *cinfo); struct nfs_commit_info *cinfo);
...@@ -457,6 +476,7 @@ void nfs_init_cinfo(struct nfs_commit_info *cinfo, ...@@ -457,6 +476,7 @@ void nfs_init_cinfo(struct nfs_commit_info *cinfo,
struct nfs_direct_req *dreq); struct nfs_direct_req *dreq);
int nfs_key_timeout_notify(struct file *filp, struct inode *inode); int nfs_key_timeout_notify(struct file *filp, struct inode *inode);
bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx); bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx);
void nfs_pageio_stop_mirroring(struct nfs_pageio_descriptor *pgio);
#ifdef CONFIG_MIGRATION #ifdef CONFIG_MIGRATION
extern int nfs_migrate_page(struct address_space *, extern int nfs_migrate_page(struct address_space *,
...@@ -480,6 +500,7 @@ static inline void nfs_inode_dio_wait(struct inode *inode) ...@@ -480,6 +500,7 @@ static inline void nfs_inode_dio_wait(struct inode *inode)
inode_dio_wait(inode); inode_dio_wait(inode);
} }
extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq); extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq);
extern void nfs_direct_set_resched_writes(struct nfs_direct_req *dreq);
/* nfs4proc.c */ /* nfs4proc.c */
extern void __nfs4_read_done_cb(struct nfs_pgio_header *); extern void __nfs4_read_done_cb(struct nfs_pgio_header *);
......
...@@ -481,7 +481,8 @@ static int decode_path(struct xdr_stream *xdr) ...@@ -481,7 +481,8 @@ static int decode_path(struct xdr_stream *xdr)
* void; * void;
* }; * };
*/ */
static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result) static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result,
__u32 *op_status)
{ {
enum nfs_stat status; enum nfs_stat status;
int error; int error;
...@@ -489,6 +490,8 @@ static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result) ...@@ -489,6 +490,8 @@ static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result)
error = decode_stat(xdr, &status); error = decode_stat(xdr, &status);
if (unlikely(error)) if (unlikely(error))
goto out; goto out;
if (op_status)
*op_status = status;
if (status != NFS_OK) if (status != NFS_OK)
goto out_default; goto out_default;
error = decode_fattr(xdr, result); error = decode_fattr(xdr, result);
...@@ -808,7 +811,7 @@ static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr, ...@@ -808,7 +811,7 @@ static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr,
static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr, static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr,
struct nfs_fattr *result) struct nfs_fattr *result)
{ {
return decode_attrstat(xdr, result); return decode_attrstat(xdr, result, NULL);
} }
static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr, static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr,
...@@ -865,6 +868,7 @@ static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr, ...@@ -865,6 +868,7 @@ static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr,
error = decode_stat(xdr, &status); error = decode_stat(xdr, &status);
if (unlikely(error)) if (unlikely(error))
goto out; goto out;
result->op_status = status;
if (status != NFS_OK) if (status != NFS_OK)
goto out_default; goto out_default;
error = decode_fattr(xdr, result->fattr); error = decode_fattr(xdr, result->fattr);
...@@ -882,7 +886,7 @@ static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr, ...@@ -882,7 +886,7 @@ static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr,
{ {
/* All NFSv2 writes are "file sync" writes */ /* All NFSv2 writes are "file sync" writes */
result->verf->committed = NFS_FILE_SYNC; result->verf->committed = NFS_FILE_SYNC;
return decode_attrstat(xdr, result->fattr); return decode_attrstat(xdr, result->fattr, &result->op_status);
} }
/** /**
......
...@@ -30,5 +30,7 @@ struct nfs_server *nfs3_create_server(struct nfs_mount_info *, struct nfs_subver ...@@ -30,5 +30,7 @@ struct nfs_server *nfs3_create_server(struct nfs_mount_info *, struct nfs_subver
struct nfs_server *nfs3_clone_server(struct nfs_server *, struct nfs_fh *, struct nfs_server *nfs3_clone_server(struct nfs_server *, struct nfs_fh *,
struct nfs_fattr *, rpc_authflavor_t); struct nfs_fattr *, rpc_authflavor_t);
/* nfs3super.c */
extern struct nfs_subversion nfs_v3;
#endif /* __LINUX_FS_NFS_NFS3_FS_H */ #endif /* __LINUX_FS_NFS_NFS3_FS_H */
#include <linux/nfs_fs.h> #include <linux/nfs_fs.h>
#include <linux/nfs_mount.h> #include <linux/nfs_mount.h>
#include <linux/sunrpc/addr.h>
#include "internal.h" #include "internal.h"
#include "nfs3_fs.h" #include "nfs3_fs.h"
...@@ -64,3 +65,43 @@ struct nfs_server *nfs3_clone_server(struct nfs_server *source, ...@@ -64,3 +65,43 @@ struct nfs_server *nfs3_clone_server(struct nfs_server *source,
nfs_init_server_aclclient(server); nfs_init_server_aclclient(server);
return server; return server;
} }
/*
* Set up a pNFS Data Server client over NFSv3.
*
* Return any existing nfs_client that matches server address,port,version
* and minorversion.
*
* For a new nfs_client, use a soft mount (default), a low retrans and a
* low timeout interval so that if a connection is lost, we retry through
* the MDS.
*/
struct nfs_client *nfs3_set_ds_client(struct nfs_client *mds_clp,
const struct sockaddr *ds_addr, int ds_addrlen,
int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans,
rpc_authflavor_t au_flavor)
{
struct nfs_client_initdata cl_init = {
.addr = ds_addr,
.addrlen = ds_addrlen,
.nfs_mod = &nfs_v3,
.proto = ds_proto,
.net = mds_clp->cl_net,
};
struct rpc_timeout ds_timeout;
struct nfs_client *clp;
char buf[INET6_ADDRSTRLEN + 1];
/* fake a hostname because lockd wants it */
if (rpc_ntop(ds_addr, buf, sizeof(buf)) <= 0)
return ERR_PTR(-EINVAL);
cl_init.hostname = buf;
/* Use the MDS nfs_client cl_ipaddr. */
nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);
clp = nfs_get_client(&cl_init, &ds_timeout, mds_clp->cl_ipaddr,
au_flavor);
return clp;
}
EXPORT_SYMBOL_GPL(nfs3_set_ds_client);
...@@ -800,6 +800,9 @@ static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr) ...@@ -800,6 +800,9 @@ static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
{ {
struct inode *inode = hdr->inode; struct inode *inode = hdr->inode;
if (hdr->pgio_done_cb != NULL)
return hdr->pgio_done_cb(task, hdr);
if (nfs3_async_handle_jukebox(task, inode)) if (nfs3_async_handle_jukebox(task, inode))
return -EAGAIN; return -EAGAIN;
...@@ -825,6 +828,9 @@ static int nfs3_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr) ...@@ -825,6 +828,9 @@ static int nfs3_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
{ {
struct inode *inode = hdr->inode; struct inode *inode = hdr->inode;
if (hdr->pgio_done_cb != NULL)
return hdr->pgio_done_cb(task, hdr);
if (nfs3_async_handle_jukebox(task, inode)) if (nfs3_async_handle_jukebox(task, inode))
return -EAGAIN; return -EAGAIN;
if (task->tk_status >= 0) if (task->tk_status >= 0)
...@@ -845,6 +851,9 @@ static void nfs3_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commi ...@@ -845,6 +851,9 @@ static void nfs3_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commi
static int nfs3_commit_done(struct rpc_task *task, struct nfs_commit_data *data) static int nfs3_commit_done(struct rpc_task *task, struct nfs_commit_data *data)
{ {
if (data->commit_done_cb != NULL)
return data->commit_done_cb(task, data);
if (nfs3_async_handle_jukebox(task, data->inode)) if (nfs3_async_handle_jukebox(task, data->inode))
return -EAGAIN; return -EAGAIN;
nfs_refresh_inode(data->inode, data->res.fattr); nfs_refresh_inode(data->inode, data->res.fattr);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include "nfs3_fs.h" #include "nfs3_fs.h"
#include "nfs.h" #include "nfs.h"
static struct nfs_subversion nfs_v3 = { struct nfs_subversion nfs_v3 = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.nfs_fs = &nfs_fs_type, .nfs_fs = &nfs_fs_type,
.rpc_vers = &nfs_version3, .rpc_vers = &nfs_version3,
......
...@@ -1636,6 +1636,7 @@ static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr, ...@@ -1636,6 +1636,7 @@ static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
error = decode_post_op_attr(xdr, result->fattr); error = decode_post_op_attr(xdr, result->fattr);
if (unlikely(error)) if (unlikely(error))
goto out; goto out;
result->op_status = status;
if (status != NFS3_OK) if (status != NFS3_OK)
goto out_status; goto out_status;
error = decode_read3resok(xdr, result); error = decode_read3resok(xdr, result);
...@@ -1708,6 +1709,7 @@ static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr, ...@@ -1708,6 +1709,7 @@ static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr,
error = decode_wcc_data(xdr, result->fattr); error = decode_wcc_data(xdr, result->fattr);
if (unlikely(error)) if (unlikely(error))
goto out; goto out;
result->op_status = status;
if (status != NFS3_OK) if (status != NFS3_OK)
goto out_status; goto out_status;
error = decode_write3resok(xdr, result); error = decode_write3resok(xdr, result);
...@@ -2323,6 +2325,7 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, ...@@ -2323,6 +2325,7 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
error = decode_wcc_data(xdr, result->fattr); error = decode_wcc_data(xdr, result->fattr);
if (unlikely(error)) if (unlikely(error))
goto out; goto out;
result->op_status = status;
if (status != NFS3_OK) if (status != NFS3_OK)
goto out_status; goto out_status;
error = decode_writeverf3(xdr, &result->verf->verifier); error = decode_writeverf3(xdr, &result->verf->verifier);
......
...@@ -446,6 +446,12 @@ extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid); ...@@ -446,6 +446,12 @@ extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid);
extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid); extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid);
extern void nfs_release_seqid(struct nfs_seqid *seqid); extern void nfs_release_seqid(struct nfs_seqid *seqid);
extern void nfs_free_seqid(struct nfs_seqid *seqid); extern void nfs_free_seqid(struct nfs_seqid *seqid);
extern int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
struct nfs4_sequence_args *args,
struct nfs4_sequence_res *res,
struct rpc_task *task);
extern int nfs4_sequence_done(struct rpc_task *task,
struct nfs4_sequence_res *res);
extern void nfs4_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp); extern void nfs4_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp);
......
...@@ -849,14 +849,15 @@ static int nfs4_set_client(struct nfs_server *server, ...@@ -849,14 +849,15 @@ static int nfs4_set_client(struct nfs_server *server,
*/ */
struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp, struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
const struct sockaddr *ds_addr, int ds_addrlen, const struct sockaddr *ds_addr, int ds_addrlen,
int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans) int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans,
u32 minor_version, rpc_authflavor_t au_flavor)
{ {
struct nfs_client_initdata cl_init = { struct nfs_client_initdata cl_init = {
.addr = ds_addr, .addr = ds_addr,
.addrlen = ds_addrlen, .addrlen = ds_addrlen,
.nfs_mod = &nfs_v4, .nfs_mod = &nfs_v4,
.proto = ds_proto, .proto = ds_proto,
.minorversion = mds_clp->cl_minorversion, .minorversion = minor_version,
.net = mds_clp->cl_net, .net = mds_clp->cl_net,
}; };
struct rpc_timeout ds_timeout; struct rpc_timeout ds_timeout;
...@@ -874,7 +875,7 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp, ...@@ -874,7 +875,7 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
*/ */
nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans); nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);
clp = nfs_get_client(&cl_init, &ds_timeout, mds_clp->cl_ipaddr, clp = nfs_get_client(&cl_init, &ds_timeout, mds_clp->cl_ipaddr,
mds_clp->cl_rpcclient->cl_auth->au_flavor); au_flavor);
dprintk("<-- %s %p\n", __func__, clp); dprintk("<-- %s %p\n", __func__, clp);
return clp; return clp;
......
...@@ -495,12 +495,11 @@ static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args) ...@@ -495,12 +495,11 @@ static void nfs4_set_sequence_privileged(struct nfs4_sequence_args *args)
args->sa_privileged = 1; args->sa_privileged = 1;
} }
static int nfs40_setup_sequence(const struct nfs_server *server, int nfs40_setup_sequence(struct nfs4_slot_table *tbl,
struct nfs4_sequence_args *args, struct nfs4_sequence_args *args,
struct nfs4_sequence_res *res, struct nfs4_sequence_res *res,
struct rpc_task *task) struct rpc_task *task)
{ {
struct nfs4_slot_table *tbl = server->nfs_client->cl_slot_tbl;
struct nfs4_slot *slot; struct nfs4_slot *slot;
/* slot already allocated? */ /* slot already allocated? */
...@@ -535,6 +534,7 @@ static int nfs40_setup_sequence(const struct nfs_server *server, ...@@ -535,6 +534,7 @@ static int nfs40_setup_sequence(const struct nfs_server *server,
spin_unlock(&tbl->slot_tbl_lock); spin_unlock(&tbl->slot_tbl_lock);
return -EAGAIN; return -EAGAIN;
} }
EXPORT_SYMBOL_GPL(nfs40_setup_sequence);
static int nfs40_sequence_done(struct rpc_task *task, static int nfs40_sequence_done(struct rpc_task *task,
struct nfs4_sequence_res *res) struct nfs4_sequence_res *res)
...@@ -694,8 +694,7 @@ int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) ...@@ -694,8 +694,7 @@ int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
} }
EXPORT_SYMBOL_GPL(nfs41_sequence_done); EXPORT_SYMBOL_GPL(nfs41_sequence_done);
static int nfs4_sequence_done(struct rpc_task *task, int nfs4_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
struct nfs4_sequence_res *res)
{ {
if (res->sr_slot == NULL) if (res->sr_slot == NULL)
return 1; return 1;
...@@ -703,6 +702,7 @@ static int nfs4_sequence_done(struct rpc_task *task, ...@@ -703,6 +702,7 @@ static int nfs4_sequence_done(struct rpc_task *task,
return nfs40_sequence_done(task, res); return nfs40_sequence_done(task, res);
return nfs41_sequence_done(task, res); return nfs41_sequence_done(task, res);
} }
EXPORT_SYMBOL_GPL(nfs4_sequence_done);
int nfs41_setup_sequence(struct nfs4_session *session, int nfs41_setup_sequence(struct nfs4_session *session,
struct nfs4_sequence_args *args, struct nfs4_sequence_args *args,
...@@ -777,7 +777,8 @@ static int nfs4_setup_sequence(const struct nfs_server *server, ...@@ -777,7 +777,8 @@ static int nfs4_setup_sequence(const struct nfs_server *server,
int ret = 0; int ret = 0;
if (!session) if (!session)
return nfs40_setup_sequence(server, args, res, task); return nfs40_setup_sequence(server->nfs_client->cl_slot_tbl,
args, res, task);
dprintk("--> %s clp %p session %p sr_slot %u\n", dprintk("--> %s clp %p session %p sr_slot %u\n",
__func__, session->clp, session, res->sr_slot ? __func__, session->clp, session, res->sr_slot ?
...@@ -818,14 +819,16 @@ static int nfs4_setup_sequence(const struct nfs_server *server, ...@@ -818,14 +819,16 @@ static int nfs4_setup_sequence(const struct nfs_server *server,
struct nfs4_sequence_res *res, struct nfs4_sequence_res *res,
struct rpc_task *task) struct rpc_task *task)
{ {
return nfs40_setup_sequence(server, args, res, task); return nfs40_setup_sequence(server->nfs_client->cl_slot_tbl,
args, res, task);
} }
static int nfs4_sequence_done(struct rpc_task *task, int nfs4_sequence_done(struct rpc_task *task,
struct nfs4_sequence_res *res) struct nfs4_sequence_res *res)
{ {
return nfs40_sequence_done(task, res); return nfs40_sequence_done(task, res);
} }
EXPORT_SYMBOL_GPL(nfs4_sequence_done);
#endif /* !CONFIG_NFS_V4_1 */ #endif /* !CONFIG_NFS_V4_1 */
...@@ -1712,8 +1715,8 @@ static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata) ...@@ -1712,8 +1715,8 @@ static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata)
{ {
struct nfs4_opendata *data = calldata; struct nfs4_opendata *data = calldata;
nfs40_setup_sequence(data->o_arg.server, &data->c_arg.seq_args, nfs40_setup_sequence(data->o_arg.server->nfs_client->cl_slot_tbl,
&data->c_res.seq_res, task); &data->c_arg.seq_args, &data->c_res.seq_res, task);
} }
static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
...@@ -5994,8 +5997,8 @@ static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata ...@@ -5994,8 +5997,8 @@ static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata
{ {
struct nfs_release_lockowner_data *data = calldata; struct nfs_release_lockowner_data *data = calldata;
struct nfs_server *server = data->server; struct nfs_server *server = data->server;
nfs40_setup_sequence(server, &data->args.seq_args, nfs40_setup_sequence(server->nfs_client->cl_slot_tbl,
&data->res.seq_res, task); &data->args.seq_args, &data->res.seq_res, task);
data->args.lock_owner.clientid = server->nfs_client->cl_clientid; data->args.lock_owner.clientid = server->nfs_client->cl_clientid;
data->timestamp = jiffies; data->timestamp = jiffies;
} }
...@@ -7557,6 +7560,7 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata) ...@@ -7557,6 +7560,7 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata)
return; return;
if (pnfs_choose_layoutget_stateid(&lgp->args.stateid, if (pnfs_choose_layoutget_stateid(&lgp->args.stateid,
NFS_I(lgp->args.inode)->layout, NFS_I(lgp->args.inode)->layout,
&lgp->args.range,
lgp->args.ctx->state)) { lgp->args.ctx->state)) {
rpc_exit(task, NFS4_OK); rpc_exit(task, NFS4_OK);
} }
...@@ -7812,6 +7816,9 @@ static void nfs4_layoutreturn_release(void *calldata) ...@@ -7812,6 +7816,9 @@ static void nfs4_layoutreturn_release(void *calldata)
spin_lock(&lo->plh_inode->i_lock); spin_lock(&lo->plh_inode->i_lock);
if (lrp->res.lrs_present) if (lrp->res.lrs_present)
pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
pnfs_clear_layoutreturn_waitbit(lo);
clear_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE, &lo->plh_flags);
rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq);
lo->plh_block_lgets--; lo->plh_block_lgets--;
spin_unlock(&lo->plh_inode->i_lock); spin_unlock(&lo->plh_inode->i_lock);
pnfs_put_layout_hdr(lrp->args.layout); pnfs_put_layout_hdr(lrp->args.layout);
...@@ -7825,7 +7832,7 @@ static const struct rpc_call_ops nfs4_layoutreturn_call_ops = { ...@@ -7825,7 +7832,7 @@ static const struct rpc_call_ops nfs4_layoutreturn_call_ops = {
.rpc_release = nfs4_layoutreturn_release, .rpc_release = nfs4_layoutreturn_release,
}; };
int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp) int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync)
{ {
struct rpc_task *task; struct rpc_task *task;
struct rpc_message msg = { struct rpc_message msg = {
...@@ -7839,16 +7846,23 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp) ...@@ -7839,16 +7846,23 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp)
.rpc_message = &msg, .rpc_message = &msg,
.callback_ops = &nfs4_layoutreturn_call_ops, .callback_ops = &nfs4_layoutreturn_call_ops,
.callback_data = lrp, .callback_data = lrp,
.flags = RPC_TASK_ASYNC,
}; };
int status; int status = 0;
dprintk("--> %s\n", __func__); dprintk("--> %s\n", __func__);
nfs4_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1); nfs4_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1);
task = rpc_run_task(&task_setup_data); task = rpc_run_task(&task_setup_data);
if (IS_ERR(task)) if (IS_ERR(task))
return PTR_ERR(task); return PTR_ERR(task);
if (sync == false)
goto out;
status = nfs4_wait_for_completion_rpc_task(task);
if (status != 0)
goto out;
status = task->tk_status; status = task->tk_status;
trace_nfs4_layoutreturn(lrp->args.inode, status); trace_nfs4_layoutreturn(lrp->args.inode, status);
out:
dprintk("<-- %s status=%d\n", __func__, status); dprintk("<-- %s status=%d\n", __func__, status);
rpc_put_task(task); rpc_put_task(task);
return status; return status;
......
...@@ -346,6 +346,9 @@ static int __init init_nfs_v4(void) ...@@ -346,6 +346,9 @@ static int __init init_nfs_v4(void)
static void __exit exit_nfs_v4(void) static void __exit exit_nfs_v4(void)
{ {
/* Not called in the _init(), conditionally loaded */
nfs4_pnfs_v3_ds_connect_unload();
unregister_nfs_version(&nfs_v4); unregister_nfs_version(&nfs_v4);
nfs4_unregister_sysctl(); nfs4_unregister_sysctl();
nfs_idmap_quit(); nfs_idmap_quit();
......
...@@ -2011,11 +2011,11 @@ encode_layoutreturn(struct xdr_stream *xdr, ...@@ -2011,11 +2011,11 @@ encode_layoutreturn(struct xdr_stream *xdr,
p = reserve_space(xdr, 16); p = reserve_space(xdr, 16);
*p++ = cpu_to_be32(0); /* reclaim. always 0 for now */ *p++ = cpu_to_be32(0); /* reclaim. always 0 for now */
*p++ = cpu_to_be32(args->layout_type); *p++ = cpu_to_be32(args->layout_type);
*p++ = cpu_to_be32(IOMODE_ANY); *p++ = cpu_to_be32(args->range.iomode);
*p = cpu_to_be32(RETURN_FILE); *p = cpu_to_be32(RETURN_FILE);
p = reserve_space(xdr, 16); p = reserve_space(xdr, 16);
p = xdr_encode_hyper(p, 0); p = xdr_encode_hyper(p, args->range.offset);
p = xdr_encode_hyper(p, NFS4_MAX_UINT64); p = xdr_encode_hyper(p, args->range.length);
spin_lock(&args->inode->i_lock); spin_lock(&args->inode->i_lock);
encode_nfs4_stateid(xdr, &args->stateid); encode_nfs4_stateid(xdr, &args->stateid);
spin_unlock(&args->inode->i_lock); spin_unlock(&args->inode->i_lock);
...@@ -6566,6 +6566,7 @@ static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, struct xdr_stream *xdr, ...@@ -6566,6 +6566,7 @@ static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
int status; int status;
status = decode_compound_hdr(xdr, &hdr); status = decode_compound_hdr(xdr, &hdr);
res->op_status = hdr.status;
if (status) if (status)
goto out; goto out;
status = decode_sequence(xdr, &res->seq_res, rqstp); status = decode_sequence(xdr, &res->seq_res, rqstp);
...@@ -6591,6 +6592,7 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, struct xdr_stream *xdr, ...@@ -6591,6 +6592,7 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
int status; int status;
status = decode_compound_hdr(xdr, &hdr); status = decode_compound_hdr(xdr, &hdr);
res->op_status = hdr.status;
if (status) if (status)
goto out; goto out;
status = decode_sequence(xdr, &res->seq_res, rqstp); status = decode_sequence(xdr, &res->seq_res, rqstp);
...@@ -6620,6 +6622,7 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr, ...@@ -6620,6 +6622,7 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
int status; int status;
status = decode_compound_hdr(xdr, &hdr); status = decode_compound_hdr(xdr, &hdr);
res->op_status = hdr.status;
if (status) if (status)
goto out; goto out;
status = decode_sequence(xdr, &res->seq_res, rqstp); status = decode_sequence(xdr, &res->seq_res, rqstp);
......
...@@ -537,11 +537,12 @@ int objio_write_pagelist(struct nfs_pgio_header *hdr, int how) ...@@ -537,11 +537,12 @@ int objio_write_pagelist(struct nfs_pgio_header *hdr, int how)
static size_t objio_pg_test(struct nfs_pageio_descriptor *pgio, static size_t objio_pg_test(struct nfs_pageio_descriptor *pgio,
struct nfs_page *prev, struct nfs_page *req) struct nfs_page *prev, struct nfs_page *req)
{ {
struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(pgio);
unsigned int size; unsigned int size;
size = pnfs_generic_pg_test(pgio, prev, req); size = pnfs_generic_pg_test(pgio, prev, req);
if (!size || pgio->pg_count + req->wb_bytes > if (!size || mirror->pg_count + req->wb_bytes >
(unsigned long)pgio->pg_layout_private) (unsigned long)pgio->pg_layout_private)
return 0; return 0;
...@@ -607,12 +608,14 @@ static const struct nfs_pageio_ops objio_pg_read_ops = { ...@@ -607,12 +608,14 @@ static const struct nfs_pageio_ops objio_pg_read_ops = {
.pg_init = objio_init_read, .pg_init = objio_init_read,
.pg_test = objio_pg_test, .pg_test = objio_pg_test,
.pg_doio = pnfs_generic_pg_readpages, .pg_doio = pnfs_generic_pg_readpages,
.pg_cleanup = pnfs_generic_pg_cleanup,
}; };
static const struct nfs_pageio_ops objio_pg_write_ops = { static const struct nfs_pageio_ops objio_pg_write_ops = {
.pg_init = objio_init_write, .pg_init = objio_init_write,
.pg_test = objio_pg_test, .pg_test = objio_pg_test,
.pg_doio = pnfs_generic_pg_writepages, .pg_doio = pnfs_generic_pg_writepages,
.pg_cleanup = pnfs_generic_pg_cleanup,
}; };
static struct pnfs_layoutdriver_type objlayout_type = { static struct pnfs_layoutdriver_type objlayout_type = {
......
This diff is collapsed.
This diff is collapsed.
...@@ -38,6 +38,25 @@ enum { ...@@ -38,6 +38,25 @@ enum {
NFS_LSEG_VALID = 0, /* cleared when lseg is recalled/returned */ NFS_LSEG_VALID = 0, /* cleared when lseg is recalled/returned */
NFS_LSEG_ROC, /* roc bit received from server */ NFS_LSEG_ROC, /* roc bit received from server */
NFS_LSEG_LAYOUTCOMMIT, /* layoutcommit bit set for layoutcommit */ NFS_LSEG_LAYOUTCOMMIT, /* layoutcommit bit set for layoutcommit */
NFS_LSEG_LAYOUTRETURN, /* layoutreturn bit set for layoutreturn */
};
/* Individual ip address */
struct nfs4_pnfs_ds_addr {
struct sockaddr_storage da_addr;
size_t da_addrlen;
struct list_head da_node; /* nfs4_pnfs_dev_hlist dev_dslist */
char *da_remotestr; /* human readable addr+port */
};
struct nfs4_pnfs_ds {
struct list_head ds_node; /* nfs4_pnfs_dev_hlist dev_dslist */
char *ds_remotestr; /* comma sep list of addrs */
struct list_head ds_addrs;
struct nfs_client *ds_clp;
atomic_t ds_count;
unsigned long ds_state;
#define NFS4DS_CONNECTING 0 /* ds is establishing connection */
}; };
struct pnfs_layout_segment { struct pnfs_layout_segment {
...@@ -53,19 +72,34 @@ struct pnfs_layout_segment { ...@@ -53,19 +72,34 @@ struct pnfs_layout_segment {
enum pnfs_try_status { enum pnfs_try_status {
PNFS_ATTEMPTED = 0, PNFS_ATTEMPTED = 0,
PNFS_NOT_ATTEMPTED = 1, PNFS_NOT_ATTEMPTED = 1,
PNFS_TRY_AGAIN = 2,
}; };
#ifdef CONFIG_NFS_V4_1 #ifdef CONFIG_NFS_V4_1
#define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4" #define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4"
/*
* Default data server connection timeout and retrans vaules.
* Set by module parameters dataserver_timeo and dataserver_retrans.
*/
#define NFS4_DEF_DS_TIMEO 600 /* in tenths of a second */
#define NFS4_DEF_DS_RETRANS 5
/* error codes for internal use */
#define NFS4ERR_RESET_TO_MDS 12001
#define NFS4ERR_RESET_TO_PNFS 12002
enum { enum {
NFS_LAYOUT_RO_FAILED = 0, /* get ro layout failed stop trying */ NFS_LAYOUT_RO_FAILED = 0, /* get ro layout failed stop trying */
NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */ NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */
NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */ NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */
NFS_LAYOUT_ROC, /* some lseg had roc bit set */ NFS_LAYOUT_ROC, /* some lseg had roc bit set */
NFS_LAYOUT_RETURN, /* Return this layout ASAP */ NFS_LAYOUT_RETURN, /* Return this layout ASAP */
NFS_LAYOUT_RETURN_BEFORE_CLOSE, /* Return this layout before close */
NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */ NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */
NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */
NFS_LAYOUT_RETRY_LAYOUTGET, /* Retry layoutget */
}; };
enum layoutdriver_policy_flags { enum layoutdriver_policy_flags {
...@@ -106,7 +140,8 @@ struct pnfs_layoutdriver_type { ...@@ -106,7 +140,8 @@ struct pnfs_layoutdriver_type {
struct pnfs_ds_commit_info *(*get_ds_info) (struct inode *inode); struct pnfs_ds_commit_info *(*get_ds_info) (struct inode *inode);
void (*mark_request_commit) (struct nfs_page *req, void (*mark_request_commit) (struct nfs_page *req,
struct pnfs_layout_segment *lseg, struct pnfs_layout_segment *lseg,
struct nfs_commit_info *cinfo); struct nfs_commit_info *cinfo,
u32 ds_commit_idx);
void (*clear_request_commit) (struct nfs_page *req, void (*clear_request_commit) (struct nfs_page *req,
struct nfs_commit_info *cinfo); struct nfs_commit_info *cinfo);
int (*scan_commit_lists) (struct nfs_commit_info *cinfo, int (*scan_commit_lists) (struct nfs_commit_info *cinfo,
...@@ -154,6 +189,7 @@ struct pnfs_layout_hdr { ...@@ -154,6 +189,7 @@ struct pnfs_layout_hdr {
u32 plh_barrier; /* ignore lower seqids */ u32 plh_barrier; /* ignore lower seqids */
unsigned long plh_retry_timestamp; unsigned long plh_retry_timestamp;
unsigned long plh_flags; unsigned long plh_flags;
enum pnfs_iomode plh_return_iomode;
loff_t plh_lwb; /* last write byte for layoutcommit */ loff_t plh_lwb; /* last write byte for layoutcommit */
struct rpc_cred *plh_lc_cred; /* layoutcommit cred */ struct rpc_cred *plh_lc_cred; /* layoutcommit cred */
struct inode *plh_inode; struct inode *plh_inode;
...@@ -185,7 +221,7 @@ extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, ...@@ -185,7 +221,7 @@ extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
struct pnfs_device *dev, struct pnfs_device *dev,
struct rpc_cred *cred); struct rpc_cred *cred);
extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags); extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync);
/* pnfs.c */ /* pnfs.c */
void pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo); void pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo);
...@@ -198,6 +234,7 @@ void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page * ...@@ -198,6 +234,7 @@ void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *
int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc); int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
struct nfs_page *req, u64 wb_size); struct nfs_page *req, u64 wb_size);
void pnfs_generic_pg_cleanup(struct nfs_pageio_descriptor *);
int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc); int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc);
size_t pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, size_t pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio,
struct nfs_page *prev, struct nfs_page *req); struct nfs_page *prev, struct nfs_page *req);
...@@ -217,6 +254,7 @@ void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, ...@@ -217,6 +254,7 @@ void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
bool update_barrier); bool update_barrier);
int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, int pnfs_choose_layoutget_stateid(nfs4_stateid *dst,
struct pnfs_layout_hdr *lo, struct pnfs_layout_hdr *lo,
struct pnfs_layout_range *range,
struct nfs4_state *open_state); struct nfs4_state *open_state);
int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
struct list_head *tmp_list, struct list_head *tmp_list,
...@@ -233,17 +271,21 @@ int _pnfs_return_layout(struct inode *); ...@@ -233,17 +271,21 @@ int _pnfs_return_layout(struct inode *);
int pnfs_commit_and_return_layout(struct inode *); int pnfs_commit_and_return_layout(struct inode *);
void pnfs_ld_write_done(struct nfs_pgio_header *); void pnfs_ld_write_done(struct nfs_pgio_header *);
void pnfs_ld_read_done(struct nfs_pgio_header *); void pnfs_ld_read_done(struct nfs_pgio_header *);
int pnfs_read_resend_pnfs(struct nfs_pgio_header *);
struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino, struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
struct nfs_open_context *ctx, struct nfs_open_context *ctx,
loff_t pos, loff_t pos,
u64 count, u64 count,
enum pnfs_iomode iomode, enum pnfs_iomode iomode,
gfp_t gfp_flags); gfp_t gfp_flags);
void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo);
void nfs4_deviceid_mark_client_invalid(struct nfs_client *clp); void nfs4_deviceid_mark_client_invalid(struct nfs_client *clp);
int pnfs_read_done_resend_to_mds(struct nfs_pgio_header *); int pnfs_read_done_resend_to_mds(struct nfs_pgio_header *);
int pnfs_write_done_resend_to_mds(struct nfs_pgio_header *); int pnfs_write_done_resend_to_mds(struct nfs_pgio_header *);
struct nfs4_threshold *pnfs_mdsthreshold_alloc(void); struct nfs4_threshold *pnfs_mdsthreshold_alloc(void);
void pnfs_error_mark_layout_for_return(struct inode *inode,
struct pnfs_layout_segment *lseg);
/* nfs4_deviceid_flags */ /* nfs4_deviceid_flags */
enum { enum {
...@@ -275,6 +317,34 @@ void nfs4_mark_deviceid_unavailable(struct nfs4_deviceid_node *node); ...@@ -275,6 +317,34 @@ void nfs4_mark_deviceid_unavailable(struct nfs4_deviceid_node *node);
bool nfs4_test_deviceid_unavailable(struct nfs4_deviceid_node *node); bool nfs4_test_deviceid_unavailable(struct nfs4_deviceid_node *node);
void nfs4_deviceid_purge_client(const struct nfs_client *); void nfs4_deviceid_purge_client(const struct nfs_client *);
/* pnfs_nfs.c */
void pnfs_generic_clear_request_commit(struct nfs_page *req,
struct nfs_commit_info *cinfo);
void pnfs_generic_commit_release(void *calldata);
void pnfs_generic_prepare_to_resend_writes(struct nfs_commit_data *data);
void pnfs_generic_rw_release(void *data);
void pnfs_generic_recover_commit_reqs(struct list_head *dst,
struct nfs_commit_info *cinfo);
int pnfs_generic_commit_pagelist(struct inode *inode,
struct list_head *mds_pages,
int how,
struct nfs_commit_info *cinfo,
int (*initiate_commit)(struct nfs_commit_data *data,
int how));
int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo, int max);
void pnfs_generic_write_commit_done(struct rpc_task *task, void *data);
void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds);
struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs,
gfp_t gfp_flags);
void nfs4_pnfs_v3_ds_connect_unload(void);
void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
struct nfs4_deviceid_node *devid, unsigned int timeo,
unsigned int retrans, u32 version, u32 minor_version,
rpc_authflavor_t au_flavor);
struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net,
struct xdr_stream *xdr,
gfp_t gfp_flags);
static inline bool nfs_have_layout(struct inode *inode) static inline bool nfs_have_layout(struct inode *inode)
{ {
return NFS_I(inode)->layout != NULL; return NFS_I(inode)->layout != NULL;
...@@ -287,6 +357,26 @@ nfs4_get_deviceid(struct nfs4_deviceid_node *d) ...@@ -287,6 +357,26 @@ nfs4_get_deviceid(struct nfs4_deviceid_node *d)
return d; return d;
} }
static inline void pnfs_set_retry_layoutget(struct pnfs_layout_hdr *lo)
{
if (!test_and_set_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags))
atomic_inc(&lo->plh_refcount);
}
static inline void pnfs_clear_retry_layoutget(struct pnfs_layout_hdr *lo)
{
if (test_and_clear_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags)) {
atomic_dec(&lo->plh_refcount);
/* wake up waiters for LAYOUTRETURN as that is not needed */
wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN);
}
}
static inline bool pnfs_should_retry_layoutget(struct pnfs_layout_hdr *lo)
{
return test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags);
}
static inline struct pnfs_layout_segment * static inline struct pnfs_layout_segment *
pnfs_get_lseg(struct pnfs_layout_segment *lseg) pnfs_get_lseg(struct pnfs_layout_segment *lseg)
{ {
...@@ -322,16 +412,22 @@ pnfs_get_ds_info(struct inode *inode) ...@@ -322,16 +412,22 @@ pnfs_get_ds_info(struct inode *inode)
return ld->get_ds_info(inode); return ld->get_ds_info(inode);
} }
static inline void
pnfs_generic_mark_devid_invalid(struct nfs4_deviceid_node *node)
{
set_bit(NFS_DEVICEID_INVALID, &node->flags);
}
static inline bool static inline bool
pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg, pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg,
struct nfs_commit_info *cinfo) struct nfs_commit_info *cinfo, u32 ds_commit_idx)
{ {
struct inode *inode = req->wb_context->dentry->d_inode; struct inode *inode = req->wb_context->dentry->d_inode;
struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld; struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
if (lseg == NULL || ld->mark_request_commit == NULL) if (lseg == NULL || ld->mark_request_commit == NULL)
return false; return false;
ld->mark_request_commit(req, lseg, cinfo); ld->mark_request_commit(req, lseg, cinfo, ds_commit_idx);
return true; return true;
} }
...@@ -357,15 +453,6 @@ pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo, ...@@ -357,15 +453,6 @@ pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo,
return NFS_SERVER(inode)->pnfs_curr_ld->scan_commit_lists(cinfo, max); return NFS_SERVER(inode)->pnfs_curr_ld->scan_commit_lists(cinfo, max);
} }
static inline void
pnfs_recover_commit_reqs(struct inode *inode, struct list_head *list,
struct nfs_commit_info *cinfo)
{
if (cinfo->ds == NULL || cinfo->ds->nwritten == 0)
return;
NFS_SERVER(inode)->pnfs_curr_ld->recover_commit_reqs(list, cinfo);
}
static inline struct nfs_page * static inline struct nfs_page *
pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo, pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
struct page *page) struct page *page)
...@@ -523,7 +610,7 @@ pnfs_get_ds_info(struct inode *inode) ...@@ -523,7 +610,7 @@ pnfs_get_ds_info(struct inode *inode)
static inline bool static inline bool
pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg, pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg,
struct nfs_commit_info *cinfo) struct nfs_commit_info *cinfo, u32 ds_commit_idx)
{ {
return false; return false;
} }
...@@ -541,12 +628,6 @@ pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo, ...@@ -541,12 +628,6 @@ pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo,
return 0; return 0;
} }
static inline void
pnfs_recover_commit_reqs(struct inode *inode, struct list_head *list,
struct nfs_commit_info *cinfo)
{
}
static inline struct nfs_page * static inline struct nfs_page *
pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo, pnfs_search_commit_reqs(struct inode *inode, struct nfs_commit_info *cinfo,
struct page *page) struct page *page)
...@@ -578,6 +659,10 @@ static inline struct nfs4_threshold *pnfs_mdsthreshold_alloc(void) ...@@ -578,6 +659,10 @@ static inline struct nfs4_threshold *pnfs_mdsthreshold_alloc(void)
return NULL; return NULL;
} }
static inline void nfs4_pnfs_v3_ds_connect_unload(void)
{
}
#endif /* CONFIG_NFS_V4_1 */ #endif /* CONFIG_NFS_V4_1 */
#endif /* FS_NFS_PNFS_H */ #endif /* FS_NFS_PNFS_H */
This diff is collapsed.
...@@ -70,8 +70,15 @@ EXPORT_SYMBOL_GPL(nfs_pageio_init_read); ...@@ -70,8 +70,15 @@ EXPORT_SYMBOL_GPL(nfs_pageio_init_read);
void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio) void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio)
{ {
struct nfs_pgio_mirror *mirror;
pgio->pg_ops = &nfs_pgio_rw_ops; pgio->pg_ops = &nfs_pgio_rw_ops;
pgio->pg_bsize = NFS_SERVER(pgio->pg_inode)->rsize;
/* read path should never have more than one mirror */
WARN_ON_ONCE(pgio->pg_mirror_count != 1);
mirror = &pgio->pg_mirrors[0];
mirror->pg_bsize = NFS_SERVER(pgio->pg_inode)->rsize;
} }
EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds); EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds);
...@@ -81,6 +88,7 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, ...@@ -81,6 +88,7 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
struct nfs_page *new; struct nfs_page *new;
unsigned int len; unsigned int len;
struct nfs_pageio_descriptor pgio; struct nfs_pageio_descriptor pgio;
struct nfs_pgio_mirror *pgm;
len = nfs_page_length(page); len = nfs_page_length(page);
if (len == 0) if (len == 0)
...@@ -97,7 +105,13 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, ...@@ -97,7 +105,13 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
&nfs_async_read_completion_ops); &nfs_async_read_completion_ops);
nfs_pageio_add_request(&pgio, new); nfs_pageio_add_request(&pgio, new);
nfs_pageio_complete(&pgio); nfs_pageio_complete(&pgio);
NFS_I(inode)->read_io += pgio.pg_bytes_written;
/* It doesn't make sense to do mirrored reads! */
WARN_ON_ONCE(pgio.pg_mirror_count != 1);
pgm = &pgio.pg_mirrors[0];
NFS_I(inode)->read_io += pgm->pg_bytes_written;
return 0; return 0;
} }
...@@ -168,13 +182,14 @@ static void nfs_read_completion(struct nfs_pgio_header *hdr) ...@@ -168,13 +182,14 @@ static void nfs_read_completion(struct nfs_pgio_header *hdr)
static void nfs_initiate_read(struct nfs_pgio_header *hdr, static void nfs_initiate_read(struct nfs_pgio_header *hdr,
struct rpc_message *msg, struct rpc_message *msg,
const struct nfs_rpc_ops *rpc_ops,
struct rpc_task_setup *task_setup_data, int how) struct rpc_task_setup *task_setup_data, int how)
{ {
struct inode *inode = hdr->inode; struct inode *inode = hdr->inode;
int swap_flags = IS_SWAPFILE(inode) ? NFS_RPC_SWAPFLAGS : 0; int swap_flags = IS_SWAPFILE(inode) ? NFS_RPC_SWAPFLAGS : 0;
task_setup_data->flags |= swap_flags; task_setup_data->flags |= swap_flags;
NFS_PROTO(inode)->read_setup(hdr, msg); rpc_ops->read_setup(hdr, msg);
} }
static void static void
...@@ -351,6 +366,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, ...@@ -351,6 +366,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
struct list_head *pages, unsigned nr_pages) struct list_head *pages, unsigned nr_pages)
{ {
struct nfs_pageio_descriptor pgio; struct nfs_pageio_descriptor pgio;
struct nfs_pgio_mirror *pgm;
struct nfs_readdesc desc = { struct nfs_readdesc desc = {
.pgio = &pgio, .pgio = &pgio,
}; };
...@@ -386,10 +402,15 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, ...@@ -386,10 +402,15 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
&nfs_async_read_completion_ops); &nfs_async_read_completion_ops);
ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc); ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc);
nfs_pageio_complete(&pgio); nfs_pageio_complete(&pgio);
NFS_I(inode)->read_io += pgio.pg_bytes_written;
npages = (pgio.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; /* It doesn't make sense to do mirrored reads! */
WARN_ON_ONCE(pgio.pg_mirror_count != 1);
pgm = &pgio.pg_mirrors[0];
NFS_I(inode)->read_io += pgm->pg_bytes_written;
npages = (pgm->pg_bytes_written + PAGE_CACHE_SIZE - 1) >>
PAGE_CACHE_SHIFT;
nfs_add_stats(inode, NFSIOS_READPAGES, npages); nfs_add_stats(inode, NFSIOS_READPAGES, npages);
read_complete: read_complete:
put_nfs_open_context(desc.ctx); put_nfs_open_context(desc.ctx);
......
This diff is collapsed.
...@@ -516,6 +516,7 @@ enum pnfs_layouttype { ...@@ -516,6 +516,7 @@ enum pnfs_layouttype {
LAYOUT_NFSV4_1_FILES = 1, LAYOUT_NFSV4_1_FILES = 1,
LAYOUT_OSD2_OBJECTS = 2, LAYOUT_OSD2_OBJECTS = 2,
LAYOUT_BLOCK_VOLUME = 3, LAYOUT_BLOCK_VOLUME = 3,
LAYOUT_FLEX_FILES = 4,
}; };
/* used for both layout return and recall */ /* used for both layout return and recall */
......
...@@ -77,10 +77,6 @@ struct nfs_client { ...@@ -77,10 +77,6 @@ struct nfs_client {
/* Client owner identifier */ /* Client owner identifier */
const char * cl_owner_id; const char * cl_owner_id;
/* Our own IP address, as a null-terminated string.
* This is used to generate the mv0 callback address.
*/
char cl_ipaddr[48];
u32 cl_cb_ident; /* v4.0 callback identifier */ u32 cl_cb_ident; /* v4.0 callback identifier */
const struct nfs4_minor_version_ops *cl_mvops; const struct nfs4_minor_version_ops *cl_mvops;
unsigned long cl_mig_gen; unsigned long cl_mig_gen;
...@@ -108,6 +104,11 @@ struct nfs_client { ...@@ -108,6 +104,11 @@ struct nfs_client {
#define NFS_SP4_MACH_CRED_COMMIT 6 /* COMMIT */ #define NFS_SP4_MACH_CRED_COMMIT 6 /* COMMIT */
#endif /* CONFIG_NFS_V4 */ #endif /* CONFIG_NFS_V4 */
/* Our own IP address, as a null-terminated string.
* This is used to generate the mv0 callback address.
*/
char cl_ipaddr[48];
#ifdef CONFIG_NFS_FSCACHE #ifdef CONFIG_NFS_FSCACHE
struct fscache_cookie *fscache; /* client index cache cookie */ struct fscache_cookie *fscache; /* client index cache cookie */
#endif #endif
......
...@@ -73,5 +73,7 @@ int nfs_map_group_to_gid(const struct nfs_server *, const char *, size_t, kgid_t ...@@ -73,5 +73,7 @@ int nfs_map_group_to_gid(const struct nfs_server *, const char *, size_t, kgid_t
int nfs_map_uid_to_name(const struct nfs_server *, kuid_t, char *, size_t); int nfs_map_uid_to_name(const struct nfs_server *, kuid_t, char *, size_t);
int nfs_map_gid_to_group(const struct nfs_server *, kgid_t, char *, size_t); int nfs_map_gid_to_group(const struct nfs_server *, kgid_t, char *, size_t);
int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *res);
extern unsigned int nfs_idmap_cache_timeout; extern unsigned int nfs_idmap_cache_timeout;
#endif /* NFS_IDMAP_H */ #endif /* NFS_IDMAP_H */
This diff is collapsed.
This diff is collapsed.
...@@ -79,6 +79,8 @@ struct rpc_clnt; ...@@ -79,6 +79,8 @@ struct rpc_clnt;
struct rpc_iostats * rpc_alloc_iostats(struct rpc_clnt *); struct rpc_iostats * rpc_alloc_iostats(struct rpc_clnt *);
void rpc_count_iostats(const struct rpc_task *, void rpc_count_iostats(const struct rpc_task *,
struct rpc_iostats *); struct rpc_iostats *);
void rpc_count_iostats_metrics(const struct rpc_task *,
struct rpc_iostats *);
void rpc_print_iostats(struct seq_file *, struct rpc_clnt *); void rpc_print_iostats(struct seq_file *, struct rpc_clnt *);
void rpc_free_iostats(struct rpc_iostats *); void rpc_free_iostats(struct rpc_iostats *);
...@@ -87,6 +89,8 @@ void rpc_free_iostats(struct rpc_iostats *); ...@@ -87,6 +89,8 @@ void rpc_free_iostats(struct rpc_iostats *);
static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; } static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; }
static inline void rpc_count_iostats(const struct rpc_task *task, static inline void rpc_count_iostats(const struct rpc_task *task,
struct rpc_iostats *stats) {} struct rpc_iostats *stats) {}
static inline void rpc_count_iostats_metrics(const struct rpc_task *,
struct rpc_iostats *) {}
static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {} static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {}
static inline void rpc_free_iostats(struct rpc_iostats *stats) {} static inline void rpc_free_iostats(struct rpc_iostats *stats) {}
......
This diff is collapsed.
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