1 /* Kernel compatibility routines
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
9 #ifndef AFS_LINUX_OSI_COMPAT_H
10 #define AFS_LINUX_OSI_COMPAT_H
12 #if defined(HAVE_LINUX_FREEZER_H)
13 # include <linux/freezer.h>
16 #ifndef HAVE_LINUX_DO_SYNC_READ
18 do_sync_read(struct file *fp, char *buf, size_t count, loff_t *offp) {
19 return generic_file_read(fp, buf, count, offp);
23 do_sync_write(struct file *fp, char *buf, size_t count, loff_t *offp) {
24 return generic_file_write(fp, buf, count, offp);
27 #endif /* DO_SYNC_READ */
30 afs_posix_lock_file(struct file *fp, struct file_lock *flp) {
31 #ifdef POSIX_LOCK_FILE_WAIT_ARG
32 return posix_lock_file(fp, flp, NULL);
34 flp->fl_flags &=~ FL_SLEEP;
35 return posix_lock_file(fp, flp);
40 afs_posix_test_lock(struct file *fp, struct file_lock *flp) {
41 #if defined(POSIX_TEST_LOCK_CONFLICT_ARG)
42 struct file_lock conflict;
43 if (posix_test_lock(fp, flp, &conflict)) {
44 locks_copy_lock(flp, &conflict);
45 flp->fl_type = F_UNLCK;
47 #elif defined(POSIX_TEST_LOCK_RETURNS_CONFLICT)
48 struct file_lock *conflict;
49 if (conflict = posix_test_lock(fp, flp)) {
50 locks_copy_lock(flp, conflict);
51 flp->fl_type = F_UNLCK;
54 posix_test_lock(fp, flp);
58 #ifdef DCACHE_NFSFS_RENAMED
60 afs_linux_clear_nfsfs_renamed(struct dentry *dp) {
61 spin_lock(&dp->d_lock);
62 dp->d_flags &= ~DCACHE_NFSFS_RENAMED;
63 spin_unlock(&dp->d_lock);
67 afs_linux_set_nfsfs_renamed(struct dentry *dp) {
68 spin_lock(&dp->d_lock);
69 dp->d_flags |= DCACHE_NFSFS_RENAMED;
70 spin_unlock(&dp->d_lock);
74 afs_linux_nfsfs_renamed(struct dentry *dp) {
75 return dp->d_flags & DCACHE_NFSFS_RENAMED;
79 static inline void afs_linux_clear_nfsfs_renamed(void) { return; }
80 static inline void afs_linux_set_nfsfs_renamed(void) { return; }
83 #ifndef HAVE_LINUX_HLIST_UNHASHED
85 hlist_unhashed(const struct hlist_node *h) {
86 return (!h->pprev == NULL);
90 #if defined(WRITEPAGE_ACTIVATE)
91 #define AOP_WRITEPAGE_ACTIVATE WRITEPAGE_ACTIVATE
94 #if defined(STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_WRITE_BEGIN) && !defined(HAVE_LINUX_GRAB_CACHE_PAGE_WRITE_BEGIN)
95 static inline struct page *
96 grab_cache_page_write_begin(struct address_space *mapping, pgoff_t index,
98 return __grab_cache_page(mapping, index);
102 #if defined(HAVE_KMEM_CACHE_T)
103 #define afs_kmem_cache_t kmem_cache_t
105 #define afs_kmem_cache_t struct kmem_cache
108 extern void init_once(void *);
109 #if defined(HAVE_KMEM_CACHE_T)
111 init_once_func(void * foo, kmem_cache_t * cachep, unsigned long flags) {
112 #if defined(SLAB_CTOR_VERIFY)
113 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
114 SLAB_CTOR_CONSTRUCTOR)
118 #elif defined(KMEM_CACHE_INIT)
120 init_once_func(struct kmem_cache * cachep, void * foo) {
123 #elif !defined(KMEM_CACHE_CTOR_TAKES_VOID)
125 init_once_func(void * foo, struct kmem_cache * cachep, unsigned long flags) {
126 #if defined(SLAB_CTOR_VERIFY)
127 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
128 SLAB_CTOR_CONSTRUCTOR)
134 init_once_func(void * foo) {
139 #ifndef SLAB_RECLAIM_ACCOUNT
140 #define SLAB_RECLAIM_ACCOUNT 0
143 #if defined(SLAB_KERNEL)
144 #define KALLOC_TYPE SLAB_KERNEL
146 #define KALLOC_TYPE GFP_KERNEL
149 static inline struct key *
150 afs_linux_key_alloc(struct key_type *type, const char *desc, uid_t uid,
151 gid_t gid, key_perm_t perm, unsigned long flags)
153 #if defined(KEY_ALLOC_NEEDS_STRUCT_TASK)
154 return key_alloc(type, desc, uid, gid, current, perm, flags);
155 #elif defined(KEY_ALLOC_NEEDS_CRED)
156 return key_alloc(type, desc, uid, gid, current_cred(), perm, flags);
158 return key_alloc(type, desc, uid, gid, perm, flags);
162 #if defined(STRUCT_TASK_STRUCT_HAS_CRED)
163 static inline struct key*
164 afs_linux_search_keyring(afs_ucred_t *cred, struct key_type *type)
168 if (cred->tgcred->session_keyring) {
169 key_ref = keyring_search(
170 make_key_ref(cred->tgcred->session_keyring, 1),
173 return ERR_CAST(key_ref);
175 return key_ref_to_ptr(key_ref);
178 return ERR_PTR(-ENOKEY);
182 afs_linux_cred_is_current(afs_ucred_t *cred)
184 return (cred == current_cred());
188 static inline struct key*
189 afs_linux_search_keyring(afs_ucred_t *cred, struct key_type *type)
191 return request_key(type, "_pag", NULL);
195 afs_linux_cred_is_current(afs_ucred_t *cred)
201 #ifdef LINUX_KEYRING_SUPPORT
202 # ifndef KEY_ALLOC_NOT_IN_QUOTA
203 # define KEY_ALLOC_NOT_IN_QUOTA 1
205 # ifndef KEY_ALLOC_IN_QUOTA
206 # define KEY_ALLOC_IN_QUOTA 0
211 #ifndef HAVE_LINUX_PAGE_OFFSET
213 page_offset(struct page *pp)
215 return (((loff_t) pp->index) << PAGE_CACHE_SHIFT);
219 #ifndef HAVE_LINUX_ZERO_USER_SEGMENTS
221 zero_user_segments(struct page *pp, unsigned int from1, unsigned int to1,
222 unsigned int from2, unsigned int to2)
224 void *base = kmap_atomic(pp, KM_USER0);
227 memset(base + from1, 0, to1 - from1);
230 memset(base + from2, 0, to2 - from2);
232 flush_dcache_page(pp);
233 kunmap_atomic(base, KM_USER0);
237 #ifndef HAVE_LINUX_KERNEL_SETSOCKOPT
238 /* Available from 2.6.19 */
241 kernel_setsockopt(struct socket *sockp, int level, int name, char *val,
243 mm_segment_t old_fs = get_fs();
247 ret = sockp->ops->setsockopt(sockp, level, name, val, len);
254 kernel_getsockopt(struct socket *sockp, int level, int name, char *val,
256 mm_segment_t old_fs = get_fs();
260 ret = sockp->ops->setsockopt(sockp, level, name, val, len);
267 #ifdef HAVE_TRY_TO_FREEZE
269 afs_try_to_freeze(void) {
270 # ifdef LINUX_REFRIGERATOR_TAKES_PF_FREEZE
271 try_to_freeze(PF_FREEZE);
278 afs_try_to_freeze(void) {
280 if (current->flags & PF_FREEZE) {
281 refrigerator(PF_FREEZE);
286 #if !defined(HAVE_LINUX_PAGECHECKED)
287 # if defined(HAVE_LINUX_PAGEFSMISC)
288 # include <linux/page-flags.h>
290 # define PageChecked(p) PageFsMisc((p))
291 # define SetPageChecked(p) SetPageFsMisc((p))
292 # define ClearPageChecked(p) ClearPageFsMisc((p))