Rev 422 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
422 | giacomo | 1 | /* |
2 | * linux/include/linux/nfs_page.h |
||
3 | * |
||
4 | * Copyright (C) 2000 Trond Myklebust |
||
5 | * |
||
6 | * NFS page cache wrapper. |
||
7 | */ |
||
8 | |||
9 | #ifndef _LINUX_NFS_PAGE_H |
||
10 | #define _LINUX_NFS_PAGE_H |
||
11 | |||
12 | |||
13 | #include <linux/list.h> |
||
14 | #include <linux/pagemap.h> |
||
15 | #include <linux/wait.h> |
||
16 | #include <linux/nfs_fs_sb.h> |
||
17 | #include <linux/sunrpc/auth.h> |
||
18 | #include <linux/nfs_xdr.h> |
||
19 | |||
20 | /* |
||
21 | * Valid flags for a dirty buffer |
||
22 | */ |
||
23 | #define PG_BUSY 0 |
||
24 | |||
25 | struct nfs_page { |
||
26 | struct list_head wb_list, /* Defines state of page: */ |
||
27 | *wb_list_head; /* read/write/commit */ |
||
28 | struct file *wb_file; |
||
29 | struct inode *wb_inode; |
||
30 | struct rpc_cred *wb_cred; |
||
31 | struct nfs4_state *wb_state; |
||
32 | struct page *wb_page; /* page to read in/write out */ |
||
33 | wait_queue_head_t wb_wait; /* wait queue */ |
||
34 | unsigned long wb_index; /* Offset >> PAGE_CACHE_SHIFT */ |
||
35 | unsigned int wb_offset, /* Offset & ~PAGE_CACHE_MASK */ |
||
36 | wb_pgbase, /* Start of page data */ |
||
37 | wb_bytes, /* Length of request */ |
||
38 | wb_count; /* reference count */ |
||
39 | unsigned long wb_flags; |
||
40 | struct nfs_writeverf wb_verf; /* Commit cookie */ |
||
41 | }; |
||
42 | |||
43 | #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) |
||
44 | |||
45 | extern struct nfs_page *nfs_create_request(struct file *, struct inode *, |
||
46 | struct page *, |
||
47 | unsigned int, unsigned int); |
||
48 | extern void nfs_clear_request(struct nfs_page *req); |
||
49 | extern void nfs_release_request(struct nfs_page *req); |
||
50 | |||
51 | |||
52 | extern void nfs_list_add_request(struct nfs_page *, struct list_head *); |
||
53 | |||
54 | extern int nfs_scan_list(struct list_head *, struct list_head *, |
||
55 | struct file *, unsigned long, unsigned int); |
||
56 | extern int nfs_coalesce_requests(struct list_head *, struct list_head *, |
||
57 | unsigned int); |
||
58 | extern int nfs_wait_on_request(struct nfs_page *); |
||
59 | |||
60 | extern spinlock_t nfs_wreq_lock; |
||
61 | |||
62 | /* |
||
63 | * Lock the page of an asynchronous request without incrementing the wb_count |
||
64 | */ |
||
65 | static inline int |
||
66 | nfs_lock_request_dontget(struct nfs_page *req) |
||
67 | { |
||
68 | if (test_and_set_bit(PG_BUSY, &req->wb_flags)) |
||
69 | return 0; |
||
70 | return 1; |
||
71 | } |
||
72 | |||
73 | /* |
||
74 | * Lock the page of an asynchronous request |
||
75 | */ |
||
76 | static inline int |
||
77 | nfs_lock_request(struct nfs_page *req) |
||
78 | { |
||
79 | if (test_and_set_bit(PG_BUSY, &req->wb_flags)) |
||
80 | return 0; |
||
81 | req->wb_count++; |
||
82 | return 1; |
||
83 | } |
||
84 | |||
85 | static inline void |
||
86 | nfs_unlock_request(struct nfs_page *req) |
||
87 | { |
||
88 | if (!NFS_WBACK_BUSY(req)) { |
||
89 | printk(KERN_ERR "NFS: Invalid unlock attempted\n"); |
||
90 | BUG(); |
||
91 | } |
||
92 | smp_mb__before_clear_bit(); |
||
93 | clear_bit(PG_BUSY, &req->wb_flags); |
||
94 | smp_mb__after_clear_bit(); |
||
95 | if (waitqueue_active(&req->wb_wait)) |
||
96 | wake_up_all(&req->wb_wait); |
||
97 | nfs_release_request(req); |
||
98 | } |
||
99 | |||
100 | /** |
||
101 | * nfs_list_remove_request - Remove a request from its wb_list |
||
102 | * @req: request |
||
103 | */ |
||
104 | static inline void |
||
105 | nfs_list_remove_request(struct nfs_page *req) |
||
106 | { |
||
107 | if (list_empty(&req->wb_list)) |
||
108 | return; |
||
109 | if (!NFS_WBACK_BUSY(req)) { |
||
110 | printk(KERN_ERR "NFS: unlocked request attempted removed from list!\n"); |
||
111 | BUG(); |
||
112 | } |
||
113 | list_del_init(&req->wb_list); |
||
114 | req->wb_list_head = NULL; |
||
115 | } |
||
116 | |||
117 | static inline struct nfs_page * |
||
118 | nfs_list_entry(struct list_head *head) |
||
119 | { |
||
120 | return list_entry(head, struct nfs_page, wb_list); |
||
121 | } |
||
122 | |||
123 | static inline |
||
124 | loff_t req_offset(struct nfs_page *req) |
||
125 | { |
||
126 | return (((loff_t)req->wb_index) << PAGE_CACHE_SHIFT) + req->wb_offset; |
||
127 | } |
||
128 | |||
129 | #endif /* _LINUX_NFS_PAGE_H */ |