aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs.h
diff options
context:
space:
mode:
authorFred Isaman <iisaman@netapp.com>2011-03-23 09:27:51 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-03-23 15:29:03 -0400
commita861a1e1c398fe34701569fd8ac9225dfe0a9a7e (patch)
treefe28b8cfa4b8a6066ee6f2feeaa2b61e9bfaa0c0 /fs/nfs/pnfs.h
parent425eb736cd905181a4dd4dc8d66342a7c7ab2f27 (diff)
NFSv4.1: add generic layer hooks for pnfs COMMIT
We create three major hooks for the pnfs code. pnfs_mark_request_commit() is called during writeback_done from nfs_mark_request_commit, which gives the driver an opportunity to claim it wants control over commiting a particular req. pnfs_choose_commit_list() is called from nfs_scan_list to choose which list a given req should be added to, based on where we intend to send it for COMMIT. It is up to the driver to have preallocated list headers for each destination it may need. pnfs_commit_list() is how the driver actually takes control, it is used instead of nfs_commit_list(). In order to pass information between the above functions, we create a union in nfs_page to hold a lseg (which is possible because the req is not on any list while in transition), and add some flags to indicate if we need to use the pnfs code. Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/pnfs.h')
-rw-r--r--fs/nfs/pnfs.h73
1 files changed, 73 insertions, 0 deletions
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 6380b9405bcd..5370f1b9aa43 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -74,6 +74,13 @@ struct pnfs_layoutdriver_type {
74 /* test for nfs page cache coalescing */ 74 /* test for nfs page cache coalescing */
75 int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); 75 int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *);
76 76
77 /* Returns true if layoutdriver wants to divert this request to
78 * driver's commit routine.
79 */
80 bool (*mark_pnfs_commit)(struct pnfs_layout_segment *lseg);
81 struct list_head * (*choose_commit_list) (struct nfs_page *req);
82 int (*commit_pagelist)(struct inode *inode, struct list_head *mds_pages, int how);
83
77 /* 84 /*
78 * Return PNFS_ATTEMPTED to indicate the layout code has attempted 85 * Return PNFS_ATTEMPTED to indicate the layout code has attempted
79 * I/O, else return PNFS_NOT_ATTEMPTED to fall back to normal NFS 86 * I/O, else return PNFS_NOT_ATTEMPTED to fall back to normal NFS
@@ -169,6 +176,51 @@ static inline int pnfs_enabled_sb(struct nfs_server *nfss)
169 return nfss->pnfs_curr_ld != NULL; 176 return nfss->pnfs_curr_ld != NULL;
170} 177}
171 178
179static inline void
180pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg)
181{
182 if (lseg) {
183 struct pnfs_layoutdriver_type *ld;
184
185 ld = NFS_SERVER(req->wb_page->mapping->host)->pnfs_curr_ld;
186 if (ld->mark_pnfs_commit && ld->mark_pnfs_commit(lseg)) {
187 set_bit(PG_PNFS_COMMIT, &req->wb_flags);
188 req->wb_commit_lseg = get_lseg(lseg);
189 }
190 }
191}
192
193static inline int
194pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how)
195{
196 if (!test_and_clear_bit(NFS_INO_PNFS_COMMIT, &NFS_I(inode)->flags))
197 return PNFS_NOT_ATTEMPTED;
198 return NFS_SERVER(inode)->pnfs_curr_ld->commit_pagelist(inode, mds_pages, how);
199}
200
201static inline struct list_head *
202pnfs_choose_commit_list(struct nfs_page *req, struct list_head *mds)
203{
204 struct list_head *rv;
205
206 if (test_and_clear_bit(PG_PNFS_COMMIT, &req->wb_flags)) {
207 struct inode *inode = req->wb_commit_lseg->pls_layout->plh_inode;
208
209 set_bit(NFS_INO_PNFS_COMMIT, &NFS_I(inode)->flags);
210 rv = NFS_SERVER(inode)->pnfs_curr_ld->choose_commit_list(req);
211 /* matched by ref taken when PG_PNFS_COMMIT is set */
212 put_lseg(req->wb_commit_lseg);
213 } else
214 rv = mds;
215 return rv;
216}
217
218static inline void pnfs_clear_request_commit(struct nfs_page *req)
219{
220 if (test_and_clear_bit(PG_PNFS_COMMIT, &req->wb_flags))
221 put_lseg(req->wb_commit_lseg);
222}
223
172#else /* CONFIG_NFS_V4_1 */ 224#else /* CONFIG_NFS_V4_1 */
173 225
174static inline void pnfs_destroy_all_layouts(struct nfs_client *clp) 226static inline void pnfs_destroy_all_layouts(struct nfs_client *clp)
@@ -252,6 +304,27 @@ pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *ino)
252 pgio->pg_test = NULL; 304 pgio->pg_test = NULL;
253} 305}
254 306
307static inline void
308pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg)
309{
310}
311
312static inline int
313pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how)
314{
315 return PNFS_NOT_ATTEMPTED;
316}
317
318static inline struct list_head *
319pnfs_choose_commit_list(struct nfs_page *req, struct list_head *mds)
320{
321 return mds;
322}
323
324static inline void pnfs_clear_request_commit(struct nfs_page *req)
325{
326}
327
255#endif /* CONFIG_NFS_V4_1 */ 328#endif /* CONFIG_NFS_V4_1 */
256 329
257#endif /* FS_NFS_PNFS_H */ 330#endif /* FS_NFS_PNFS_H */