11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/include/linux/nfs_page.h 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2000 Trond Myklebust 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NFS page cache wrapper. 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef _LINUX_NFS_PAGE_H 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _LINUX_NFS_PAGE_H 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/list.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pagemap.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/wait.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sunrpc/auth.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/nfs_xdr.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19c03b40246123b2ced79e2620d1d2c089bb12369aTrond Myklebust#include <linux/kref.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Valid flags for a dirty buffer 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 24e468bae97d243fe0e1515abaa1f7d0edf1476ad0Trond Myklebustenum { 2512c05792599ec57ebab33096b2c75b863dfe6ea4Weston Andros Adamson PG_BUSY = 0, /* nfs_{un}lock_request */ 2612c05792599ec57ebab33096b2c75b863dfe6ea4Weston Andros Adamson PG_MAPPED, /* page private set for buffered io */ 2712c05792599ec57ebab33096b2c75b863dfe6ea4Weston Andros Adamson PG_CLEAN, /* write succeeded */ 2812c05792599ec57ebab33096b2c75b863dfe6ea4Weston Andros Adamson PG_COMMIT_TO_DS, /* used by pnfs layouts */ 29b412ddf0661e11485876a202c48868143e3a01cfWeston Andros Adamson PG_INODE_REF, /* extra ref held by inode when in writeback */ 302bfc6e566daa8386c9cffef2f7de17fc330d3835Weston Andros Adamson PG_HEADLOCK, /* page group lock of wb_head */ 312bfc6e566daa8386c9cffef2f7de17fc330d3835Weston Andros Adamson PG_TEARDOWN, /* page group sync for destroy */ 3267d0338edd71db9a4f406d8778f7c525d31e9f7fWeston Andros Adamson PG_UNLOCKPAGE, /* page group sync bit in read path */ 3367d0338edd71db9a4f406d8778f7c525d31e9f7fWeston Andros Adamson PG_UPTODATE, /* page group sync bit in read path */ 3420633f042fd0907300069714b98aaf607a8b5bf8Weston Andros Adamson PG_WB_END, /* page group sync bit in write path */ 3520633f042fd0907300069714b98aaf607a8b5bf8Weston Andros Adamson PG_REMOVE, /* page group sync bit in write path */ 36e468bae97d243fe0e1515abaa1f7d0edf1476ad0Trond Myklebust}; 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 383da28eb1c6545fe73263a24eba0996217490e1ebTrond Myklebuststruct nfs_inode; 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct nfs_page { 40d6d6dc7cdfda7c8f49a89a7b7261846f319da6d1Fred Isaman struct list_head wb_list; /* Defines state of page: */ 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct page *wb_page; /* page to read in/write out */ 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nfs_open_context *wb_context; /* File state context info */ 43f11ac8db5d07b6e99d41ff4aa39d878ee5cef1c5Trond Myklebust struct nfs_lock_context *wb_lock_context; /* lock context info */ 44ca52fec152282ef73e5e882b847b36b1febbb1c6Trond Myklebust pgoff_t wb_index; /* Offset >> PAGE_CACHE_SHIFT */ 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int wb_offset, /* Offset & ~PAGE_CACHE_MASK */ 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wb_pgbase, /* Start of page data */ 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wb_bytes; /* Length of request */ 48c03b40246123b2ced79e2620d1d2c089bb12369aTrond Myklebust struct kref wb_kref; /* reference count */ 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long wb_flags; 502f2c63bc221c5fcded24de2704575d0abf96b910Trond Myklebust struct nfs_write_verifier wb_verf; /* Commit cookie */ 512bfc6e566daa8386c9cffef2f7de17fc330d3835Weston Andros Adamson struct nfs_page *wb_this_page; /* list of reqs for this page */ 522bfc6e566daa8386c9cffef2f7de17fc330d3835Weston Andros Adamson struct nfs_page *wb_head; /* head pointer for req list */ 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 551751c3638f2a07a8c66a803a31791bab9bd3fcedTrond Myklebuststruct nfs_pageio_descriptor; 561751c3638f2a07a8c66a803a31791bab9bd3fcedTrond Myklebuststruct nfs_pageio_ops { 57d8007d4dd6ff8749cc8a4063c3ec87442db76d82Trond Myklebust void (*pg_init)(struct nfs_pageio_descriptor *, struct nfs_page *); 58b4fdac1a5150174df0847a45dc6612ce5ce3daebWeston Andros Adamson size_t (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, 59b4fdac1a5150174df0847a45dc6612ce5ce3daebWeston Andros Adamson struct nfs_page *); 601751c3638f2a07a8c66a803a31791bab9bd3fcedTrond Myklebust int (*pg_doio)(struct nfs_pageio_descriptor *); 611751c3638f2a07a8c66a803a31791bab9bd3fcedTrond Myklebust}; 621751c3638f2a07a8c66a803a31791bab9bd3fcedTrond Myklebust 634a0de55c565a36cac8422b76a948c4634a90781eAnna Schumakerstruct nfs_rw_ops { 64a4cdda59111f92000297e0d3edb1e0e08ba3549bAnna Schumaker const fmode_t rw_mode; 651e7f3a485922211b6e4a082ebc6bf05810b0b6eaWeston Andros Adamson struct nfs_pgio_header *(*rw_alloc_header)(void); 661e7f3a485922211b6e4a082ebc6bf05810b0b6eaWeston Andros Adamson void (*rw_free_header)(struct nfs_pgio_header *); 67d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson void (*rw_release)(struct nfs_pgio_header *); 68d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson int (*rw_done)(struct rpc_task *, struct nfs_pgio_header *, 69d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson struct inode *); 70d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson void (*rw_result)(struct rpc_task *, struct nfs_pgio_header *); 71d45f60c67848b9f19160692581d78e5b4757a000Weston Andros Adamson void (*rw_initiate)(struct nfs_pgio_header *, struct rpc_message *, 721ed26f33008e954a8e91d26f97d4380dea8145dbAnna Schumaker struct rpc_task_setup *, int); 734a0de55c565a36cac8422b76a948c4634a90781eAnna Schumaker}; 744a0de55c565a36cac8422b76a948c4634a90781eAnna Schumaker 75d8a5ad75cc4d577987964e37a4c43b1c648c201eTrond Myklebuststruct nfs_pageio_descriptor { 76d8a5ad75cc4d577987964e37a4c43b1c648c201eTrond Myklebust struct list_head pg_list; 77bcb71bba7e64f0442d0ca339d7d3117a7060589fTrond Myklebust unsigned long pg_bytes_written; 78d8a5ad75cc4d577987964e37a4c43b1c648c201eTrond Myklebust size_t pg_count; 79d8a5ad75cc4d577987964e37a4c43b1c648c201eTrond Myklebust size_t pg_bsize; 80d8a5ad75cc4d577987964e37a4c43b1c648c201eTrond Myklebust unsigned int pg_base; 81d9156f9f364897e93bdd98b4ad22138de18f7c24Trond Myklebust unsigned char pg_moreio : 1, 82d9156f9f364897e93bdd98b4ad22138de18f7c24Trond Myklebust pg_recoalesce : 1; 83bcb71bba7e64f0442d0ca339d7d3117a7060589fTrond Myklebust 84bcb71bba7e64f0442d0ca339d7d3117a7060589fTrond Myklebust struct inode *pg_inode; 851751c3638f2a07a8c66a803a31791bab9bd3fcedTrond Myklebust const struct nfs_pageio_ops *pg_ops; 864a0de55c565a36cac8422b76a948c4634a90781eAnna Schumaker const struct nfs_rw_ops *pg_rw_ops; 87bcb71bba7e64f0442d0ca339d7d3117a7060589fTrond Myklebust int pg_ioflags; 88bcb71bba7e64f0442d0ca339d7d3117a7060589fTrond Myklebust int pg_error; 8950828d7e6767a92726708bc0666e2b8b84575808Trond Myklebust const struct rpc_call_ops *pg_rpc_callops; 90061ae2edb7375ab6776468b075da71008a098b55Fred Isaman const struct nfs_pgio_completion_ops *pg_completion_ops; 9194ad1c80e28f9700c84b4d28d1e5302ddf63a6fdFred Isaman struct pnfs_layout_segment *pg_lseg; 92584aa810b6240d88c28113a90c5029449814a3b5Fred Isaman struct nfs_direct_req *pg_dreq; 93f6166384095b7ecf77752b5e9096e6d03d75f7aePeng Tao void *pg_layout_private; 94d8a5ad75cc4d577987964e37a4c43b1c648c201eTrond Myklebust}; 95d8a5ad75cc4d577987964e37a4c43b1c648c201eTrond Myklebust 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx, 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct page *page, 1002bfc6e566daa8386c9cffef2f7de17fc330d3835Weston Andros Adamson struct nfs_page *last, 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int offset, 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int count); 1032bfc6e566daa8386c9cffef2f7de17fc330d3835Weston Andros Adamsonextern void nfs_release_request(struct nfs_page *); 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 106bcb71bba7e64f0442d0ca339d7d3117a7060589fTrond Myklebustextern void nfs_pageio_init(struct nfs_pageio_descriptor *desc, 107bcb71bba7e64f0442d0ca339d7d3117a7060589fTrond Myklebust struct inode *inode, 1081751c3638f2a07a8c66a803a31791bab9bd3fcedTrond Myklebust const struct nfs_pageio_ops *pg_ops, 109061ae2edb7375ab6776468b075da71008a098b55Fred Isaman const struct nfs_pgio_completion_ops *compl_ops, 1104a0de55c565a36cac8422b76a948c4634a90781eAnna Schumaker const struct nfs_rw_ops *rw_ops, 111bcb71bba7e64f0442d0ca339d7d3117a7060589fTrond Myklebust size_t bsize, 112bcb71bba7e64f0442d0ca339d7d3117a7060589fTrond Myklebust int how); 1138b09bee3083897e375bd0bf9d60f48daedfab3e0Trond Myklebustextern int nfs_pageio_add_request(struct nfs_pageio_descriptor *, 1148b09bee3083897e375bd0bf9d60f48daedfab3e0Trond Myklebust struct nfs_page *); 11553113ad35e4b9ce82d949c7c67c7b666fad5d907Weston Andros Adamsonextern int nfs_pageio_resend(struct nfs_pageio_descriptor *, 11653113ad35e4b9ce82d949c7c67c7b666fad5d907Weston Andros Adamson struct nfs_pgio_header *); 117bcb71bba7e64f0442d0ca339d7d3117a7060589fTrond Myklebustextern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc); 1187fe7f8487ae742239dd8c66596e2311c30d057d1Trond Myklebustextern void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t); 119b4fdac1a5150174df0847a45dc6612ce5ce3daebWeston Andros Adamsonextern size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, 12019345cb299e8234006c5125151ab723e851a1d24Benny Halevy struct nfs_page *prev, 12119345cb299e8234006c5125151ab723e851a1d24Benny Halevy struct nfs_page *req); 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern int nfs_wait_on_request(struct nfs_page *); 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void nfs_unlock_request(struct nfs_page *req); 1242bfc6e566daa8386c9cffef2f7de17fc330d3835Weston Andros Adamsonextern void nfs_unlock_and_release_request(struct nfs_page *); 125e7029206ff43f6cf7d6fcb741adb126f47200516Weston Andros Adamsonextern int nfs_page_group_lock(struct nfs_page *, bool); 1267c3af975257383ece54b83c0505d3e0656cb7dafWeston Andros Adamsonextern void nfs_page_group_lock_wait(struct nfs_page *); 1272bfc6e566daa8386c9cffef2f7de17fc330d3835Weston Andros Adamsonextern void nfs_page_group_unlock(struct nfs_page *); 1282bfc6e566daa8386c9cffef2f7de17fc330d3835Weston Andros Adamsonextern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int); 129c6a556b88adfacd2af90be84357c8165d716c27dTrond Myklebust 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1317ad84aa9448571678c243f0c5ef383fbe5b50f4fTrond Myklebust * Lock the page of an asynchronous request 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int 1348dd3775889345850ecddd689b5c200cdd91bd8c9Trond Myklebustnfs_lock_request(struct nfs_page *req) 1358dd3775889345850ecddd689b5c200cdd91bd8c9Trond Myklebust{ 1367ad84aa9448571678c243f0c5ef383fbe5b50f4fTrond Myklebust return !test_and_set_bit(PG_BUSY, &req->wb_flags); 1378dd3775889345850ecddd689b5c200cdd91bd8c9Trond Myklebust} 1388dd3775889345850ecddd689b5c200cdd91bd8c9Trond Myklebust 1393da28eb1c6545fe73263a24eba0996217490e1ebTrond Myklebust/** 1403da28eb1c6545fe73263a24eba0996217490e1ebTrond Myklebust * nfs_list_add_request - Insert a request into a list 1413da28eb1c6545fe73263a24eba0996217490e1ebTrond Myklebust * @req: request 1423da28eb1c6545fe73263a24eba0996217490e1ebTrond Myklebust * @head: head of list into which to insert the request. 1433da28eb1c6545fe73263a24eba0996217490e1ebTrond Myklebust */ 1443da28eb1c6545fe73263a24eba0996217490e1ebTrond Myklebuststatic inline void 1453da28eb1c6545fe73263a24eba0996217490e1ebTrond Myklebustnfs_list_add_request(struct nfs_page *req, struct list_head *head) 1463da28eb1c6545fe73263a24eba0996217490e1ebTrond Myklebust{ 1473da28eb1c6545fe73263a24eba0996217490e1ebTrond Myklebust list_add_tail(&req->wb_list, head); 1483da28eb1c6545fe73263a24eba0996217490e1ebTrond Myklebust} 1493da28eb1c6545fe73263a24eba0996217490e1ebTrond Myklebust 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * nfs_list_remove_request - Remove a request from its wb_list 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @req: request 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsnfs_list_remove_request(struct nfs_page *req) 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (list_empty(&req->wb_list)) 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds list_del_init(&req->wb_list); 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline struct nfs_page * 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsnfs_list_entry(struct list_head *head) 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return list_entry(head, struct nfs_page, wb_list); 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsloff_t req_offset(struct nfs_page *req) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (((loff_t)req->wb_index) << PAGE_CACHE_SHIFT) + req->wb_offset; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* _LINUX_NFS_PAGE_H */ 176