1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
37 #ifndef _LINUX_COMPAT25_H
38 #define _LINUX_COMPAT25_H
42 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5)
43 #error sorry, lustre requires at least 2.6.5
46 #include <linux/fs_struct.h>
47 #include <libcfs/linux/portals_compat25.h>
49 #include <linux/lustre_patchless_compat.h>
51 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
52 struct ll_iattr_struct {
54 unsigned int ia_attr_flags;
57 #define ll_iattr_struct iattr
58 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) */
60 #ifdef HAVE_FS_STRUCT_USE_PATH
61 static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
62 struct dentry *dentry)
69 write_lock(&fs->lock);
73 write_unlock(&fs->lock);
79 static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
80 struct dentry *dentry)
82 struct dentry *old_pwd;
83 struct vfsmount *old_pwdmnt;
85 write_lock(&fs->lock);
87 old_pwdmnt = fs->pwdmnt;
88 fs->pwdmnt = mntget(mnt);
89 fs->pwd = dget(dentry);
90 write_unlock(&fs->lock);
97 #endif /* HAVE_FS_STRUCT_USE_PATH */
99 #ifdef HAVE_INODE_I_MUTEX
100 #define UNLOCK_INODE_MUTEX(inode) do {mutex_unlock(&(inode)->i_mutex); } while(0)
101 #define LOCK_INODE_MUTEX(inode) do {mutex_lock(&(inode)->i_mutex); } while(0)
102 #define TRYLOCK_INODE_MUTEX(inode) mutex_trylock(&(inode)->i_mutex)
104 #define UNLOCK_INODE_MUTEX(inode) do {up(&(inode)->i_sem); } while(0)
105 #define LOCK_INODE_MUTEX(inode) do {down(&(inode)->i_sem); } while(0)
106 #define TRYLOCK_INODE_MUTEX(inode) (!down_trylock(&(inode)->i_sem))
107 #endif /* HAVE_INODE_I_MUTEX */
109 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
110 #define d_child d_u.d_child
111 #define d_rcu d_u.d_rcu
114 #ifdef HAVE_DQUOTOFF_MUTEX
115 #define UNLOCK_DQONOFF_MUTEX(dqopt) do {mutex_unlock(&(dqopt)->dqonoff_mutex); } while(0)
116 #define LOCK_DQONOFF_MUTEX(dqopt) do {mutex_lock(&(dqopt)->dqonoff_mutex); } while(0)
118 #define UNLOCK_DQONOFF_MUTEX(dqopt) do {up(&(dqopt)->dqonoff_sem); } while(0)
119 #define LOCK_DQONOFF_MUTEX(dqopt) do {down(&(dqopt)->dqonoff_sem); } while(0)
120 #endif /* HAVE_DQUOTOFF_MUTEX */
123 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4)
124 #define NGROUPS_SMALL NGROUPS
125 #define NGROUPS_PER_BLOCK ((int)(EXEC_PAGESIZE / sizeof(gid_t)))
130 gid_t small_block[NGROUPS_SMALL];
134 #define current_ngroups current->ngroups
135 #define current_groups current->groups
137 struct group_info *groups_alloc(int gidsetsize);
138 void groups_free(struct group_info *ginfo);
141 #define current_ngroups current_cred()->group_info->ngroups
142 #define current_groups current_cred()->group_info->small_block
144 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) */
147 #define page_private(page) ((page)->private)
148 #define set_page_private(page, v) ((page)->private = (v))
155 #define lock_dentry(___dentry) spin_lock(&(___dentry)->d_lock)
156 #define unlock_dentry(___dentry) spin_unlock(&(___dentry)->d_lock)
158 #define ll_kernel_locked() kernel_locked()
161 * OBD need working random driver, thus all our
162 * initialization routines must be called after device
163 * driver initialization
167 #define module_init(a) late_initcall(a)
170 /* XXX our code should be using the 2.6 calls, not the other way around */
171 #ifndef HAVE_TRYLOCK_PAGE
172 #define TryLockPage(page) TestSetPageLocked(page)
174 #define TryLockPage(page) (!trylock_page(page))
177 #define Page_Uptodate(page) PageUptodate(page)
178 #define ll_redirty_page(page) set_page_dirty(page)
180 #define KDEVT_INIT(val) (val)
182 #define LTIME_S(time) (time.tv_sec)
183 #define ll_path_lookup path_lookup
185 #ifdef HAVE_EXPORT_INODE_PERMISSION
186 #define ll_permission(inode,mask,nd) inode_permission(inode,mask)
188 #define ll_permission(inode,mask,nd) permission(inode,mask,nd)
191 #define ll_pgcache_lock(mapping) spin_lock(&mapping->page_lock)
192 #define ll_pgcache_unlock(mapping) spin_unlock(&mapping->page_lock)
193 #define ll_call_writepage(inode, page) \
194 (inode)->i_mapping->a_ops->writepage(page, NULL)
195 #define ll_invalidate_inode_pages(inode) \
196 invalidate_inode_pages((inode)->i_mapping)
197 #define ll_truncate_complete_page(page) \
198 truncate_complete_page(page->mapping, page)
200 #define ll_vfs_create(a,b,c,d) vfs_create(a,b,c,d)
201 #define ll_dev_t dev_t
203 #define to_kdev_t(dev) (dev)
204 #define kdev_t_to_nr(dev) (dev)
205 #define val_to_kdev(dev) (dev)
206 #define ILOOKUP(sb, ino, test, data) ilookup5(sb, ino, test, (void *)(data));
208 #ifdef HAVE_BLKDEV_PUT_2ARGS
209 #define ll_blkdev_put(a, b) blkdev_put(a, b)
211 #define ll_blkdev_put(a, b) blkdev_put(a)
214 #ifdef HAVE_DENTRY_OPEN_4ARGS
215 #define ll_dentry_open(a, b, c, d) dentry_open(a, b, c, d)
217 #define ll_dentry_open(a, b, c, d) dentry_open(a, b, c)
220 #include <linux/writeback.h>
222 static inline int cleanup_group_info(void)
224 struct group_info *ginfo;
226 ginfo = groups_alloc(0);
230 set_current_groups(ginfo);
231 put_group_info(ginfo);
236 #define __set_page_ll_data(page, llap) \
238 page_cache_get(page); \
239 SetPagePrivate(page); \
240 set_page_private(page, (unsigned long)llap); \
242 #define __clear_page_ll_data(page) \
244 ClearPagePrivate(page); \
245 set_page_private(page, 0); \
246 page_cache_release(page); \
251 #include <linux/proc_fs.h>
253 #if !defined(HAVE_D_REHASH_COND) && defined(HAVE___D_REHASH)
254 #define d_rehash_cond(dentry, lock) __d_rehash(dentry, lock)
255 extern void __d_rehash(struct dentry *dentry, int lock);
257 extern void d_rehash_cond(struct dentry*, int lock);
260 #if !defined(HAVE_D_MOVE_LOCKED) && defined(HAVE___D_MOVE)
261 #define d_move_locked(dentry, target) __d_move(dentry, target)
262 extern void __d_move(struct dentry *dentry, struct dentry *target);
265 #ifdef HAVE_CAN_SLEEP_ARG
266 #define ll_flock_lock_file_wait(file, lock, can_sleep) \
267 flock_lock_file_wait(file, lock, can_sleep)
269 #define ll_flock_lock_file_wait(file, lock, can_sleep) \
270 flock_lock_file_wait(file, lock)
273 #define CheckWriteback(page, cmd) \
274 ((!PageWriteback(page) && (cmd & OBD_BRW_READ)) || \
275 (PageWriteback(page) && (cmd & OBD_BRW_WRITE)))
278 #ifdef HAVE_PAGE_LIST
279 static inline int mapping_has_pages(struct address_space *mapping)
283 ll_pgcache_lock(mapping);
284 if (list_empty(&mapping->dirty_pages) &&
285 list_empty(&mapping->clean_pages) &&
286 list_empty(&mapping->locked_pages)) {
289 ll_pgcache_unlock(mapping);
294 static inline int mapping_has_pages(struct address_space *mapping)
296 return mapping->nrpages > 0;
300 #ifdef HAVE_KIOBUF_KIO_BLOCKS
301 #define KIOBUF_GET_BLOCKS(k) ((k)->kio_blocks)
303 #define KIOBUF_GET_BLOCKS(k) ((k)->blocks)
306 #ifdef HAVE_SECURITY_PLUG
307 #ifdef HAVE_VFS_SYMLINK_5ARGS
308 #define ll_vfs_symlink(dir, dentry, mnt, path, mode) \
309 vfs_symlink(dir, dentry, mnt, path, mode)
311 #define ll_vfs_symlink(dir, dentry, mnt, path, mode) \
312 vfs_symlink(dir, dentry, mnt, path)
315 #ifdef HAVE_4ARGS_VFS_SYMLINK
316 #define ll_vfs_symlink(dir, dentry, mnt, path, mode) \
317 vfs_symlink(dir, dentry, path, mode)
319 #define ll_vfs_symlink(dir, dentry, mnt, path, mode) \
320 vfs_symlink(dir, dentry, path)
322 #endif /* HAVE_SECURITY_PLUG */
324 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
325 #define ll_set_dflags(dentry, flags) do { dentry->d_vfs_flags |= flags; } while(0)
327 #define ll_set_dflags(dentry, flags) do { \
328 spin_lock(&dentry->d_lock); \
329 dentry->d_flags |= flags; \
330 spin_unlock(&dentry->d_lock); \
335 #define container_of(ptr, type, member) ({ \
336 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
337 (type *)( (char *)__mptr - offsetof(type,member) );})
340 #define UP_WRITE_I_ALLOC_SEM(i) up_write(&(i)->i_alloc_sem)
341 #define DOWN_WRITE_I_ALLOC_SEM(i) down_write(&(i)->i_alloc_sem)
342 #define LASSERT_I_ALLOC_SEM_WRITE_LOCKED(i) LASSERT(down_read_trylock(&(i)->i_alloc_sem) == 0)
344 #define UP_READ_I_ALLOC_SEM(i) up_read(&(i)->i_alloc_sem)
345 #define DOWN_READ_I_ALLOC_SEM(i) down_read(&(i)->i_alloc_sem)
346 #define LASSERT_I_ALLOC_SEM_READ_LOCKED(i) LASSERT(down_write_trylock(&(i)->i_alloc_sem) == 0)
348 #ifndef HAVE_GRAB_CACHE_PAGE_NOWAIT_GFP
349 #define grab_cache_page_nowait_gfp(x, y, z) grab_cache_page_nowait((x), (y))
352 #include <linux/mpage.h> /* for generic_writepages */
353 #ifndef HAVE_FILEMAP_FDATAWRITE_RANGE
354 #include <linux/backing-dev.h> /* for mapping->backing_dev_info */
355 static inline int filemap_fdatawrite_range(struct address_space *mapping,
356 loff_t start, loff_t end)
359 struct writeback_control wbc = {
360 .sync_mode = WB_SYNC_ALL,
361 .nr_to_write = (end - start + PAGE_SIZE - 1) >> PAGE_SHIFT,
364 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
365 wbc.range_start = start;
372 #ifdef HAVE_MAPPING_CAP_WRITEBACK_DIRTY
373 if (!mapping_cap_writeback_dirty(mapping))
376 if (mapping->backing_dev_info->memory_backed)
379 /* do_writepages() */
380 else if (mapping->a_ops->writepages)
381 rc = mapping->a_ops->writepages(mapping, &wbc);
383 rc = generic_writepages(mapping, &wbc);
387 int filemap_fdatawrite_range(struct address_space *mapping,
388 loff_t start, loff_t end);
389 #endif /* HAVE_FILEMAP_FDATAWRITE_RANGE */
391 #ifdef HAVE_VFS_KERN_MOUNT
392 static inline struct vfsmount *
393 ll_kern_mount(const char *fstype, int flags, const char *name, void *data)
395 struct file_system_type *type = get_fs_type(fstype);
396 struct vfsmount *mnt;
398 return ERR_PTR(-ENODEV);
399 mnt = vfs_kern_mount(type, flags, name, data);
400 module_put(type->owner);
404 #define ll_kern_mount(fstype, flags, name, data) do_kern_mount((fstype), (flags), (name), (data))
407 #ifdef HAVE_STATFS_DENTRY_PARAM
408 #define ll_do_statfs(sb, sfs) (sb)->s_op->statfs((sb)->s_root, (sfs))
410 #define ll_do_statfs(sb, sfs) (sb)->s_op->statfs((sb), (sfs))
413 #ifndef HAVE_D_OBTAIN_ALIAS
414 #define d_obtain_alias(inode) d_alloc_anon(inode)
417 #ifdef HAVE_UNREGISTER_BLKDEV_RETURN_INT
418 #define ll_unregister_blkdev(a,b) unregister_blkdev((a),(b))
421 int ll_unregister_blkdev(unsigned int dev, const char *name)
423 unregister_blkdev(dev, name);
428 #ifdef HAVE_INVALIDATE_BDEV_2ARG
429 #define ll_invalidate_bdev(a,b) invalidate_bdev((a),(b))
431 #define ll_invalidate_bdev(a,b) invalidate_bdev((a))
434 #ifdef HAVE_FS_RENAME_DOES_D_MOVE
435 #define LL_RENAME_DOES_D_MOVE FS_RENAME_DOES_D_MOVE
437 #define LL_RENAME_DOES_D_MOVE FS_ODD_RENAME
440 #ifdef HAVE_FILE_REMOVE_SUID
441 #define ll_remove_suid(file, mnt) file_remove_suid(file)
443 #ifdef HAVE_SECURITY_PLUG
444 #ifdef HAVE_PATH_REMOVE_SUID
445 #define ll_remove_suid(file,mnt) remove_suid(&file->f_path)
447 #define ll_remove_suid(file,mnt) remove_suid(file->f_dentry,mnt)
450 #define ll_remove_suid(file,mnt) remove_suid(file->f_dentry)
454 #ifndef HAVE_SYNCHRONIZE_RCU
455 #define synchronize_rcu() synchronize_kernel()
458 #ifdef HAVE_SECURITY_PLUG
459 #define ll_vfs_rmdir(dir,entry,mnt) vfs_rmdir(dir,entry,mnt)
460 #define ll_vfs_mkdir(inode,dir,mnt,mode) vfs_mkdir(inode,dir,mnt,mode)
461 #define ll_vfs_link(old,mnt,dir,new,mnt1) vfs_link(old,mnt,dir,new,mnt1)
462 #define ll_vfs_unlink(inode,entry,mnt) vfs_unlink(inode,entry,mnt)
463 #define ll_vfs_mknod(dir,entry,mnt,mode,dev) \
464 vfs_mknod(dir,entry,mnt,mode,dev)
465 #define ll_security_inode_unlink(dir,entry,mnt) \
466 security_inode_unlink(dir,entry,mnt)
467 #define ll_vfs_rename(old,old_dir,mnt,new,new_dir,mnt1) \
468 vfs_rename(old,old_dir,mnt,new,new_dir,mnt1)
470 #define ll_vfs_rmdir(dir,entry,mnt) vfs_rmdir(dir,entry)
471 #define ll_vfs_mkdir(inode,dir,mnt,mode) vfs_mkdir(inode,dir,mode)
472 #define ll_vfs_link(old,mnt,dir,new,mnt1) vfs_link(old,dir,new)
473 #define ll_vfs_unlink(inode,entry,mnt) vfs_unlink(inode,entry)
474 #define ll_vfs_mknod(dir,entry,mnt,mode,dev) vfs_mknod(dir,entry,mode,dev)
475 #define ll_security_inode_unlink(dir,entry,mnt) security_inode_unlink(dir,entry)
476 #define ll_vfs_rename(old,old_dir,mnt,new,new_dir,mnt1) \
477 vfs_rename(old,old_dir,new,new_dir)
478 #endif /* HAVE_SECURITY_PLUG */
480 #ifndef for_each_possible_cpu
481 #define for_each_possible_cpu(i) for_each_cpu(i)
485 #define cpu_to_node(cpu) 0
488 #ifdef HAVE_REGISTER_SHRINKER
490 #define SHRINKER_MASK_T gfp_t
492 typedef int (*shrinker_t)(int nr_to_scan, gfp_t gfp_mask);
495 struct shrinker *set_shrinker(int seek, shrinker_t func)
499 s = kmalloc(sizeof(*s), GFP_KERNEL);
506 register_shrinker(s);
512 void remove_shrinker(struct shrinker *shrinker)
514 if (shrinker == NULL)
517 unregister_shrinker(shrinker);
520 #endif /* HAVE_REGISTER_SHRINKER */
522 #ifdef HAVE_BIO_ENDIO_2ARG
523 #define cfs_bio_io_error(a,b) bio_io_error((a))
524 #define cfs_bio_endio(a,b,c) bio_endio((a),(c))
526 #define cfs_bio_io_error(a,b) bio_io_error((a),(b))
527 #define cfs_bio_endio(a,b,c) bio_endio((a),(b),(c))
530 #ifdef HAVE_FS_STRUCT_USE_PATH
531 #define cfs_fs_pwd(fs) ((fs)->pwd.dentry)
532 #define cfs_fs_mnt(fs) ((fs)->pwd.mnt)
533 #define cfs_path_put(nd) path_put(&(nd)->path)
535 #define cfs_fs_pwd(fs) ((fs)->pwd)
536 #define cfs_fs_mnt(fs) ((fs)->pwdmnt)
537 #define cfs_path_put(nd) path_release(nd)
540 #ifndef list_for_each_safe_rcu
541 #define list_for_each_safe_rcu(a,b,c) list_for_each_rcu(a, c)
545 static inline int abs(int x)
547 return (x < 0) ? -x : x;
552 static inline long labs(long x)
554 return (x < 0) ? -x : x;
558 /* Using kernel fls(). Userspace will use one defined in user-bitops.h. */
563 #ifdef HAVE_INVALIDATE_INODE_PAGES
564 #define invalidate_mapping_pages(mapping,s,e) invalidate_inode_pages(mapping)
567 #ifndef SLAB_DESTROY_BY_RCU
568 #define SLAB_DESTROY_BY_RCU 0
571 #ifdef HAVE_INODE_IPRIVATE
572 #define INODE_PRIVATE_DATA(inode) ((inode)->i_private)
574 #define INODE_PRIVATE_DATA(inode) ((inode)->u.generic_ip)
577 #ifndef HAVE_SYSCTL_VFS_CACHE_PRESSURE
578 #define sysctl_vfs_cache_pressure 100
581 #ifdef HAVE_SB_HAS_QUOTA_ACTIVE
582 #define ll_sb_has_quota_active(sb, type) sb_has_quota_active(sb, type)
584 #define ll_sb_has_quota_active(sb, type) sb_has_quota_enabled(sb, type)
587 #ifdef HAVE_SB_ANY_QUOTA_ACTIVE
588 #define ll_sb_any_quota_active(sb) sb_any_quota_active(sb)
590 #define ll_sb_any_quota_active(sb) sb_any_quota_enabled(sb)
594 ll_quota_on(struct super_block *sb, int off, int ver, char *name, int remount)
596 if (sb->s_qcop->quota_on) {
597 return sb->s_qcop->quota_on(sb, off, ver, name
598 #ifdef HAVE_QUOTA_ON_5ARGS
607 static inline int ll_quota_off(struct super_block *sb, int off, int remount)
609 if (sb->s_qcop->quota_off) {
610 return sb->s_qcop->quota_off(sb, off
611 #ifdef HAVE_QUOTA_OFF_3ARGS
620 #ifndef HAVE_BI_HW_SEGMENTS
621 #define bio_hw_segments(q, bio) 0
624 #ifdef HAVE_FILE_UPDATE_TIME
625 #define ll_update_time(file) file_update_time(file)
627 #define ll_update_time(file) inode_update_time(file->f_mapping->host, 1)
630 /* Needed for sles9 */
631 #ifndef HAVE_ATOMIC_CMPXCHG
632 #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
635 /* Needed for rhel4 and sles9 */
636 #ifndef HAVE_ATOMIC_INC_NOT_ZERO
638 * atomic_add_unless - add unless the number is a given value
639 * @v: pointer of type atomic_t
640 * @a: the amount to add to v...
641 * @u: ...unless v is equal to u.
643 * Atomically adds @a to @v, so long as it was not @u.
644 * Returns non-zero if @v was not @u, and zero otherwise.
646 #define atomic_add_unless(v, a, u) \
649 c = atomic_read(v); \
650 while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
654 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
655 #endif /* !atomic_inc_not_zero */
657 #endif /* __KERNEL__ */
658 #endif /* _COMPAT25_H */