Linux: Fix builds on RHEL4
[openafs.git] / src / afs / LINUX / osi_compat.h
1 /* Kernel compatibility routines
2  *
3  * This file contains definitions to provide compatibility between different
4  * versions of the Linux kernel. It is an ifdef maze, but the idea is that
5  * by concentrating the horror here, the rest of the tree may remaing a
6  * little cleaner...
7  */
8
9 #ifndef AFS_LINUX_OSI_COMPAT_H
10 #define AFS_LINUX_OSI_COMPAT_H
11
12 #ifndef DO_SYNC_READ
13 static inline int
14 do_sync_read(struct file *fp, char *buf, size_t count, loff_t *offp) {
15     return generic_file_read(fp, buf, count, offp);
16 }
17
18 static inline int
19 do_sync_write(struct file *fp, char *buf, size_t count, loff_t *offp) {
20     return generic_file_write(fp, buf, count, offp);
21 }
22
23 #endif /* DO_SYNC_READ */
24
25 static inline int
26 afs_posix_lock_file(struct file *fp, struct file_lock *flp) {
27 #ifdef POSIX_LOCK_FILE_WAIT_ARG
28     return posix_lock_file(fp, flp, NULL);
29 #else
30     flp->fl_flags &=~ FL_SLEEP;
31     return posix_lock_file(fp, flp);
32 #endif
33 }
34
35 static inline void
36 afs_posix_test_lock(struct file *fp, struct file_lock *flp) {
37 #if defined(POSIX_TEST_LOCK_CONFLICT_ARG)
38     struct file_lock conflict;
39     if (posix_test_lock(fp, flp, &conflict)) {
40         locks_copy_lock(flp, &conflict);
41         flp->fl_type = F_UNLCK;
42     }
43 #elif defined(POSIX_TEST_LOCK_RETURNS_CONFLICT)
44     struct file_lock *conflict;
45     if (conflict = posix_test_lock(fp, flp)) {
46         locks_copy_lock(flp, conflict);
47         flp->fl_type = F_UNLCK;
48     }
49 #else
50     posix_test_lock(fp, flp);
51 #endif
52 }
53
54 #ifdef DCACHE_NFSFS_RENAMED
55 static inline void
56 afs_linux_clear_nfsfs_renamed(struct dentry *dp) {
57     spin_lock(&dp->d_lock);
58     dp->d_flags &= ~DCACHE_NFSFS_RENAMED;
59     spin_unlock(&dp->d_lock);
60 }
61
62 static inline void
63 afs_linux_set_nfsfs_renamed(struct dentry *dp) {
64     spin_lock(&dp->d_lock);
65     dp->d_flags |= DCACHE_NFSFS_RENAMED;
66     spin_unlock(&dp->d_lock);
67 }
68
69 static inline int
70 afs_linux_nfsfs_renamed(struct dentry *dp) {
71     return dp->d_flags & DCACHE_NFSFS_RENAMED;
72 }
73
74 #else
75 static inline void afs_linux_clear_nfsfs_renamed(void) { return; }
76 static inline void afs_linux_set_nfsfs_renamed(void) { return; }
77 #endif
78
79 #ifndef HAVE_KERNEL_HLIST_UNHASHED
80 static void
81 hlist_unhashed(const struct hlist_node *h) {
82     return (!h->pprev == NULL);
83 }
84 #endif
85
86 #if defined(WRITEPAGE_ACTIVATE)
87 #define AOP_WRITEPAGE_ACTIVATE WRITEPAGE_ACTIVATE
88 #endif
89
90 #if defined(HAVE_WRITE_BEGIN) && !defined(HAVE_GRAB_CACHE_PAGE_WRITE_BEGIN)
91 static inline struct page *
92 grab_cache_page_write_begin(struct address_space *mapping, pgoff_t index,
93                             unsigned int flags) {
94     return __grab_cache_page(mapping, index);
95 }
96 #endif
97
98 #if defined(HAVE_KMEM_CACHE_T)
99 #define afs_kmem_cache_t kmem_cache_t
100 #else
101 #define afs_kmem_cache_t struct kmem_cache
102 #endif
103
104 extern void init_once(void *);
105 #if defined(HAVE_KMEM_CACHE_T)
106 static inline void
107 init_once_func(void * foo, kmem_cache_t * cachep, unsigned long flags) {
108 #if defined(SLAB_CTOR_VERIFY)
109     if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
110         SLAB_CTOR_CONSTRUCTOR)
111 #endif
112     init_once(foo);
113 }
114 #elif defined(KMEM_CACHE_INIT)
115 static inline void
116 init_once_func(struct kmem_cache * cachep, void * foo) {
117     init_once(foo);
118 }
119 #elif !defined(KMEM_CACHE_CTOR_TAKES_VOID)
120 static inline void
121 init_once_func(void * foo, struct kmem_cache * cachep, unsigned long flags) {
122 #if defined(SLAB_CTOR_VERIFY)
123     if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
124         SLAB_CTOR_CONSTRUCTOR)
125 #endif
126     init_once(foo);
127 }
128 #else
129 static inline void
130 init_once_func(void * foo) {
131     init_once(foo);
132 }
133 #endif
134
135 #ifndef SLAB_RECLAIM_ACCOUNT
136 #define SLAB_RECLAIM_ACCOUNT 0
137 #endif
138
139 #if defined(SLAB_KERNEL)
140 #define KALLOC_TYPE SLAB_KERNEL
141 #else
142 #define KALLOC_TYPE GFP_KERNEL
143 #endif
144
145 static inline struct key *
146 afs_linux_key_alloc(struct key_type *type, const char *desc, uid_t uid,
147                     gid_t gid, key_perm_t perm, unsigned long flags)
148 {
149 #if defined(KEY_ALLOC_NEEDS_STRUCT_TASK)
150     return key_alloc(type, desc, uid, gid, current, perm, flags);
151 #elif defined(KEY_ALLOC_NEEDS_CRED)
152     return key_alloc(type, desc, uid, gid, current_cred(), perm, flags);
153 #else
154     return key_alloc(type, desc, uid, gid, perm, flags);
155 #endif
156 }
157
158 #if defined(STRUCT_TASK_HAS_CRED)
159 static inline struct key*
160 afs_linux_search_keyring(afs_ucred_t *cred, struct key_type *type)
161 {
162     key_ref_t key_ref;
163
164     if (cred->tgcred->session_keyring) {
165         key_ref = keyring_search(
166                       make_key_ref(cred->tgcred->session_keyring, 1),
167                       type, "_pag");
168         if (IS_ERR(key_ref))
169             return ERR_CAST(key_ref);
170
171         return key_ref_to_ptr(key_ref);
172     }
173
174     return ERR_PTR(-ENOKEY);
175 }
176
177 static inline int
178 afs_linux_cred_is_current(afs_ucred_t *cred)
179 {
180     return (cred == current_cred());
181 }
182
183 #else
184 static inline struct key*
185 afs_linux_search_keyring(afs_ucred_t *cred, struct key_type *type)
186 {
187     return request_key(type, "_pag", NULL);
188 }
189
190 static inline int
191 afs_linux_cred_is_current(afs_ucred_t *cred)
192 {
193     return 1;
194 }
195 #endif
196
197 #ifdef LINUX_KEYRING_SUPPORT
198 # ifndef KEY_ALLOC_NOT_IN_QUOTA
199 #  define KEY_ALLOC_NOT_IN_QUOTA 1
200 # endif
201 # ifndef KEY_ALLOC_IN_QUOTA
202 #  define KEY_ALLOC_IN_QUOTA 0
203 # endif
204 #endif
205 #endif
206
207 #ifndef HAVE_PAGE_OFFSET
208 static inline loff_t
209 page_offset(struct page *pp)
210 {
211     return (((loff_t) pp->index) << PAGE_CACHE_SHIFT);
212 }
213 #endif
214
215 #ifndef HAVE_ZERO_USER_SEGMENTS
216 static inline void
217 zero_user_segments(struct page *pp, unsigned int from1, unsigned int to1,
218                    unsigned int from2, unsigned int to2)
219 {
220     void *base = kmap_atomic(pp, KM_USER0);
221
222     if (to1 > from1)
223         memset(base + from1, 0, to1 - from1);
224
225     if (to2 > from2)
226         memset(base + from2, 0, to2 - from2);
227
228     flush_dcache_page(pp);
229     kunmap_atomic(base, KM_USER0);
230 }
231 #endif
232