Commit ea2cf228 authored by Fred Isaman's avatar Fred Isaman Committed by Trond Myklebust

NFS: create struct nfs_commit_info

It is COMMIT that is handled the most differently between
the paged and direct paths.  Create a structure that encapsulates
everything either path needs to know about the commit state.

We could use void to hide some of the layout driver stuff, but
Trond suggests pulling it out to ensure type checking, given the
huge changes being made, and the fact that it doesn't interfere
with other drivers.
Signed-off-by: default avatarFred Isaman <iisaman@netapp.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 84c53ab5
......@@ -1547,7 +1547,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi)
nfsi->delegation_state = 0;
init_rwsem(&nfsi->rwsem);
nfsi->layout = NULL;
atomic_set(&nfsi->commits_outstanding, 0);
atomic_set(&nfsi->commit_info.rpcs_out, 0);
#endif
}
......@@ -1559,9 +1559,9 @@ static void init_once(void *foo)
INIT_LIST_HEAD(&nfsi->open_files);
INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
INIT_LIST_HEAD(&nfsi->commit_list);
INIT_LIST_HEAD(&nfsi->commit_info.list);
nfsi->npages = 0;
nfsi->ncommit = 0;
nfsi->commit_info.ncommit = 0;
atomic_set(&nfsi->silly_count, 1);
INIT_HLIST_HEAD(&nfsi->silly_list);
init_waitqueue_head(&nfsi->waitqueue);
......
......@@ -346,12 +346,18 @@ extern void nfs_init_commit(struct nfs_commit_data *data,
struct list_head *head,
struct pnfs_layout_segment *lseg);
void nfs_retry_commit(struct list_head *page_list,
struct pnfs_layout_segment *lseg);
struct pnfs_layout_segment *lseg,
struct nfs_commit_info *cinfo);
void nfs_commit_clear_lock(struct nfs_inode *nfsi);
void nfs_commitdata_release(struct nfs_commit_data *data);
void nfs_commit_release_pages(struct nfs_commit_data *data);
void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *head);
void nfs_request_remove_commit_list(struct nfs_page *req);
void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst,
struct nfs_commit_info *cinfo);
void nfs_request_remove_commit_list(struct nfs_page *req,
struct nfs_commit_info *cinfo);
void nfs_init_cinfo(struct nfs_commit_info *cinfo,
struct inode *inode,
struct nfs_direct_req *dreq);
#ifdef CONFIG_MIGRATION
extern int nfs_migrate_page(struct address_space *,
......
This diff is collapsed.
......@@ -74,18 +74,6 @@ struct nfs4_file_layout_dsaddr {
struct nfs4_pnfs_ds *ds_list[1];
};
struct nfs4_fl_commit_bucket {
struct list_head written;
struct list_head committing;
struct pnfs_layout_segment *wlseg;
struct pnfs_layout_segment *clseg;
};
struct nfs4_fl_commit_info {
int nbuckets;
struct nfs4_fl_commit_bucket *buckets;
};
struct nfs4_filelayout_segment {
struct pnfs_layout_segment generic_hdr;
u32 stripe_type;
......@@ -100,7 +88,7 @@ struct nfs4_filelayout_segment {
struct nfs4_filelayout {
struct pnfs_layout_hdr generic_hdr;
struct nfs4_fl_commit_info commit_info;
struct pnfs_ds_commit_info commit_info;
};
static inline struct nfs4_filelayout *
......
......@@ -94,11 +94,18 @@ struct pnfs_layoutdriver_type {
const struct nfs_pageio_ops *pg_read_ops;
const struct nfs_pageio_ops *pg_write_ops;
struct pnfs_ds_commit_info *(*get_ds_info) (struct inode *inode);
void (*mark_request_commit) (struct nfs_page *req,
struct pnfs_layout_segment *lseg);
void (*clear_request_commit) (struct nfs_page *req);
int (*scan_commit_lists) (struct inode *inode, int max, spinlock_t *lock);
int (*commit_pagelist)(struct inode *inode, struct list_head *mds_pages, int how);
struct pnfs_layout_segment *lseg,
struct nfs_commit_info *cinfo);
void (*clear_request_commit) (struct nfs_page *req,
struct nfs_commit_info *cinfo);
int (*scan_commit_lists) (struct nfs_commit_info *cinfo,
int max);
int (*commit_pagelist)(struct inode *inode,
struct list_head *mds_pages,
int how,
struct nfs_commit_info *cinfo);
/*
* Return PNFS_ATTEMPTED to indicate the layout code has attempted
......@@ -263,49 +270,57 @@ static inline int pnfs_enabled_sb(struct nfs_server *nfss)
}
static inline int
pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how)
pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how,
struct nfs_commit_info *cinfo)
{
if (!test_and_clear_bit(NFS_INO_PNFS_COMMIT, &NFS_I(inode)->flags))
if (cinfo->ds == NULL || cinfo->ds->ncommitting == 0)
return PNFS_NOT_ATTEMPTED;
return NFS_SERVER(inode)->pnfs_curr_ld->commit_pagelist(inode, mds_pages, how);
return NFS_SERVER(inode)->pnfs_curr_ld->commit_pagelist(inode, mds_pages, how, cinfo);
}
static inline struct pnfs_ds_commit_info *
pnfs_get_ds_info(struct inode *inode)
{
struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
if (ld == NULL || ld->get_ds_info == NULL)
return NULL;
return ld->get_ds_info(inode);
}
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 inode *inode = req->wb_context->dentry->d_inode;
struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
if (lseg == NULL || ld->mark_request_commit == NULL)
return false;
ld->mark_request_commit(req, lseg);
ld->mark_request_commit(req, lseg, cinfo);
return true;
}
static inline bool
pnfs_clear_request_commit(struct nfs_page *req)
pnfs_clear_request_commit(struct nfs_page *req, struct nfs_commit_info *cinfo)
{
struct inode *inode = req->wb_context->dentry->d_inode;
struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
if (ld == NULL || ld->clear_request_commit == NULL)
return false;
ld->clear_request_commit(req);
ld->clear_request_commit(req, cinfo);
return true;
}
static inline int
pnfs_scan_commit_lists(struct inode *inode, int max, spinlock_t *lock)
pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo,
int max)
{
struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld;
int ret;
if (ld == NULL || ld->scan_commit_lists == NULL)
if (cinfo->ds == NULL || cinfo->ds->nwritten == 0)
return 0;
ret = ld->scan_commit_lists(inode, max, lock);
if (ret != 0)
set_bit(NFS_INO_PNFS_COMMIT, &NFS_I(inode)->flags);
return ret;
else
return NFS_SERVER(inode)->pnfs_curr_ld->scan_commit_lists(cinfo, max);
}
/* Should the pNFS client commit and return the layout upon a setattr */
......@@ -409,25 +424,34 @@ static inline bool pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, st
}
static inline int
pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how)
pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how,
struct nfs_commit_info *cinfo)
{
return PNFS_NOT_ATTEMPTED;
}
static inline struct pnfs_ds_commit_info *
pnfs_get_ds_info(struct inode *inode)
{
return NULL;
}
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)
{
return false;
}
static inline bool
pnfs_clear_request_commit(struct nfs_page *req)
pnfs_clear_request_commit(struct nfs_page *req, struct nfs_commit_info *cinfo)
{
return false;
}
static inline int
pnfs_scan_commit_lists(struct inode *inode, int max, spinlock_t *lock)
pnfs_scan_commit_lists(struct inode *inode, struct nfs_commit_info *cinfo,
int max)
{
return 0;
}
......
This diff is collapsed.
......@@ -179,8 +179,7 @@ struct nfs_inode {
__be32 cookieverf[2];
unsigned long npages;
unsigned long ncommit;
struct list_head commit_list;
struct nfs_mds_commit_info commit_info;
/* Open contexts for shared mmap writes */
struct list_head open_files;
......@@ -201,7 +200,6 @@ struct nfs_inode {
/* pNFS layout information */
struct pnfs_layout_hdr *layout;
atomic_t commits_outstanding;
#endif /* CONFIG_NFS_V4*/
#ifdef CONFIG_NFS_FSCACHE
struct fscache_cookie *fscache;
......@@ -230,7 +228,6 @@ struct nfs_inode {
#define NFS_INO_FSCACHE (5) /* inode can be cached by FS-Cache */
#define NFS_INO_FSCACHE_LOCK (6) /* FS-Cache cookie management lock */
#define NFS_INO_COMMIT (7) /* inode is committing unstable writes */
#define NFS_INO_PNFS_COMMIT (8) /* use pnfs code for commit */
#define NFS_INO_LAYOUTCOMMIT (9) /* layoutcommit required */
#define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */
......
......@@ -1079,6 +1079,21 @@ struct nfstime4 {
};
#ifdef CONFIG_NFS_V4_1
struct pnfs_commit_bucket {
struct list_head written;
struct list_head committing;
struct pnfs_layout_segment *wlseg;
struct pnfs_layout_segment *clseg;
};
struct pnfs_ds_commit_info {
int nwritten;
int ncommitting;
int nbuckets;
struct pnfs_commit_bucket *buckets;
};
#define NFS4_EXCHANGE_ID_LEN (48)
struct nfs41_exchange_id_args {
struct nfs_client *client;
......@@ -1242,6 +1257,18 @@ struct nfs_write_header {
struct nfs_write_data rpc_data;
};
struct nfs_mds_commit_info {
atomic_t rpcs_out;
unsigned long ncommit;
struct list_head list;
};
struct nfs_commit_info {
spinlock_t *lock;
struct nfs_mds_commit_info *mds;
struct pnfs_ds_commit_info *ds;
};
struct nfs_commit_data {
struct rpc_task task;
struct inode *inode;
......
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