#include <linux/kmod.h>
#include <linux/module.h>
#include <linux/notifier.h>
-#ifdef HAVE_KERNEL_LOCKED
-#include <linux/smp_lock.h>
-#endif
#include <linux/string.h>
#include <linux/unistd.h>
#include <linux/stacktrace.h>
if (in_interrupt()) {
cfs_trace_debug_print();
} else {
-#ifdef HAVE_KERNEL_LOCKED
- while (kernel_locked())
- unlock_kernel();
-#endif
libcfs_debug_dumplog_internal((void *)(long)current_pid());
}
#endif
]) # LC_INODE_PERMISION_2ARGS
#
-# LC_BLK_QUEUE_MAX_SEGMENTS
-#
-# 2.6.32 replaces 2 functions blk_queue_max_phys_segments and blk_queue_max_hw_segments by blk_queue_max_segments
-#
-AC_DEFUN([LC_BLK_QUEUE_MAX_SEGMENTS], [
-LB_CHECK_COMPILE([if 'blk_queue_max_segments' is defined],
-blk_queue_max_segments, [
- #include <linux/blkdev.h>
-],[
- blk_queue_max_segments(NULL, 0);
-],[
- AC_DEFINE(HAVE_BLK_QUEUE_MAX_SEGMENTS, 1,
- [blk_queue_max_segments is defined])
-])
-]) # LC_BLK_QUEUE_MAX_SEGMENTS
-
-#
-# LC_HAVE_XATTR_HANDLER_FLAGS
-#
-# 2.6.33 added a private flag to xattr_handler
-#
-AC_DEFUN([LC_HAVE_XATTR_HANDLER_FLAGS], [
-LB_CHECK_COMPILE([if 'struct xattr_handler' has flags field],
-xattr_handler_flags, [
- #include <linux/xattr.h>
-],[
- struct xattr_handler handler;
-
- handler.flags = 0;
-],[
- AC_DEFINE(HAVE_XATTR_HANDLER_FLAGS, 1, [flags field exist])
-])
-]) # LC_HAVE_XATTR_HANDLER_FLAGS
-
-#
-# LC_HAVE_DQUOT_FS_DISK_QUOTA
-#
-# 2.6.34 has quotactl_ops->[sg]et_dqblk that take struct fs_disk_quota
-#
-AC_DEFUN([LC_HAVE_DQUOT_FS_DISK_QUOTA], [
-tmp_flags="$EXTRA_KCFLAGS"
-EXTRA_KCFLAGS="-Werror"
-LB_CHECK_COMPILE([if 'quotactl_ops.set_dqblk' takes struct fs_disk_quota],
-fs_disk_quota, [
- #include <linux/fs.h>
- #include <linux/quota.h>
-],[
- ((struct quotactl_ops *)0)->set_dqblk(NULL, 0, 0, (struct fs_disk_quota*)0);
-],[
- AC_DEFINE(HAVE_DQUOT_FS_DISK_QUOTA, 1,
- [quotactl_ops.set_dqblk takes struct fs_disk_quota])
-],[
- LB_CHECK_COMPILE([if 'quotactl_ops.set_dqblk' takes struct kqid & fs_disk_quota],
- kqid_fs_disk_quota, [
- #include <linux/fs.h>
- #include <linux/quota.h>
- ],[
- ((struct quotactl_ops *)0)->set_dqblk((struct super_block*)0, *((struct kqid*)0), (struct fs_disk_quota*)0);
- ],[
- AC_DEFINE(HAVE_DQUOT_FS_DISK_QUOTA, 1,
- [quotactl_ops.set_dqblk takes struct fs_disk_quota])
- AC_DEFINE(HAVE_DQUOT_KQID, 1,
- [quotactl_ops.set_dqblk takes struct kqid])
- ])
-])
-EXTRA_KCFLAGS="$tmp_flags"
-]) # LC_HAVE_DQUOT_FS_DISK_QUOTA
-
-#
-# LC_HAVE_DQUOT_SUSPEND
-#
-# 2.6.34 has renamed dquot options to dquot_*, check for dquot_suspend
-#
-AC_DEFUN([LC_HAVE_DQUOT_SUSPEND], [
-LB_CHECK_COMPILE([if 'dquot_suspend' is defined],
-dquot_suspend, [
- #include <linux/quotaops.h>
-],[
- dquot_suspend(NULL, -1);
-],[
- AC_DEFINE(HAVE_DQUOT_SUSPEND, 1, [dquot_suspend is defined])
-])
-]) # LC_HAVE_DQUOT_SUSPEND
-
-#
-# LC_QUOTA64
-#
-# Check if kernel has been patched for 64-bit quota limits support.
-# The upstream version of this patch in RHEL6 2.6.32 kernels introduces
-# the constant QFMT_VFS_V1 in include/linux/quota.h, so we can check for
-# that in the absence of quotaio_v1.h in the kernel headers.
-#
-AC_DEFUN([LC_QUOTA64], [
-tmp_flags="$EXTRA_KCFLAGS"
-EXTRA_KCFLAGS="-I$LINUX/fs"
-LB_CHECK_COMPILE([if kernel has 64-bit quota limits support],
-quota64, [
- #include <linux/kernel.h>
- #include <linux/fs.h>
- #if defined(HAVE_FS_QUOTA_QUOTAIO_H)
- #include <quota/quotaio_v2.h>
- struct v2r1_disk_dqblk dqblk_r1;
- #else
- #include <linux/quota.h>
- int ver = QFMT_VFS_V1;
- #endif
-], [], [
- AC_DEFINE(HAVE_QUOTA64, 1, [have quota64])
-],[
- LB_CHECK_FILE([$LINUX/include/linux/lustre_version.h],
- [AC_MSG_ERROR([You have got no 64-bit kernel quota support.])])
-])
-EXTRA_KCFLAGS=$tmp_flags
-]) # LC_QUOTA64
-
-#
-# LC_HAVE_ADD_WAIT_QUEUE_EXCLUSIVE
-#
-# 2.6.34 adds __add_wait_queue_exclusive
-#
-AC_DEFUN([LC_HAVE_ADD_WAIT_QUEUE_EXCLUSIVE], [
-LB_CHECK_COMPILE([if '__add_wait_queue_exclusive' exists],
-__add_wait_queue_exclusive, [
- #include <linux/wait.h>
-],[
- wait_queue_head_t queue = { };
- wait_queue_t wait = { };
-
- __add_wait_queue_exclusive(&queue, &wait);
-],[
- AC_DEFINE(HAVE___ADD_WAIT_QUEUE_EXCLUSIVE, 1,
- [__add_wait_queue_exclusive exists])
-])
-]) # LC_HAVE_ADD_WAIT_QUEUE_EXCLUSIVE
-
-#
-# LC_FS_STRUCT_RWLOCK
-#
-# 2.6.36 fs_struct.lock use spinlock instead of rwlock.
-#
-AC_DEFUN([LC_FS_STRUCT_RWLOCK], [
-LB_CHECK_COMPILE([if 'fs_struct.lock' use rwlock],
-fs_struct_rwlock, [
- #include <asm/atomic.h>
- #include <linux/spinlock.h>
- #include <linux/fs_struct.h>
-],[
- struct fs_struct fss = { };
- rwlock_t rwl = { };
-
- fss.lock = rwl;
-],[
- AC_DEFINE(HAVE_FS_STRUCT_RWLOCK, 1, [fs_struct.lock use rwlock])
-])
-]) # LC_FS_STRUCT_RWLOCK
-
-#
-# LC_SBOPS_EVICT_INODE
-#
-# 2.6.36 super_operations add evict_inode method. it hybird of
-# delete_inode & clear_inode.
-#
-AC_DEFUN([LC_SBOPS_EVICT_INODE], [
-LB_CHECK_COMPILE([if 'super_operations.evict_inode' exist],
-super_ops_evict_inode, [
- #include <linux/fs.h>
-],[
- ((struct super_operations *)0)->evict_inode(NULL);
-],[
- AC_DEFINE(HAVE_SBOPS_EVICT_INODE, 1,
- [super_operations.evict_inode() is exist in kernel])
-])
-]) # LC_SBOPS_EVICT_INODE
-
-#
-# LC_KERNEL_LOCKED
-#
-# 2.6.37 remove kernel_locked
-#
-AC_DEFUN([LC_KERNEL_LOCKED], [
-LB_CHECK_COMPILE([if 'kernel_locked' is defined],
-kernel_locked, [
- #include <linux/smp_lock.h>
-],[
- kernel_locked();
-],[
- AC_DEFINE(HAVE_KERNEL_LOCKED, 1, [kernel_locked is defined])
-])
-]) # LC_KERNEL_LOCKED
-
-#
-# LC_FS_STRUCT_SEQCOUNT
-#
-# 2.6.37 uses seqlock in fs_struct
-#
-AC_DEFUN([LC_FS_STRUCT_SEQCOUNT], [
-LB_CHECK_COMPILE([if fs_struct use seqcount],
-fs_struct_seqcount, [
- #include <linux/fs_struct.h>
-],[
- ((struct fs_struct *)0)->seq = (struct seqcount){ 0 };
-],[
- AC_DEFINE(HAVE_FS_STRUCT_SEQCOUNT, 1, [fs_struct use seqcount])
-])
-]) # LC_FS_STRUCT_SEQCOUNT
-
-# LC_DENTRY_PATH_RAW
-#
-# Kernel version 2.6.37 commit ec2447c278ee973d35f38e53ca16ba7f965ae33d
-# dentry_path_raw is exported
-#
-AC_DEFUN([LC_DENTRY_PATH_RAW], [
-LB_CHECK_COMPILE([if 'dentry_path_raw' exist],
-dentry_path_raw, [
- #include <linux/dcache.h>
-],[
- dentry_path_raw(NULL, NULL, 0);
-],[
- AC_DEFINE(HAVE_DENTRY_PATH_RAW, 1,
- ['dentry_path_raw' is available])
-])
-]) # LC_DENTRY_PATH_RAW
-
-#
-# LC_D_COMPARE_7ARGS
-#
-# 2.6.38 dentry_operations.d_compare() taken 7 arguments.
-#
-AC_DEFUN([LC_D_COMPARE_7ARGS], [
-LB_CHECK_COMPILE([if 'dentry_operations.d_compare()' taken 7 arguments],
-dentry_ops_d_compare_7arg, [
- #include <linux/dcache.h>
-],[
- ((struct dentry_operations*)0)->d_compare(NULL,NULL,NULL,NULL,0,NULL,NULL);
-],[
- AC_DEFINE(HAVE_D_COMPARE_7ARGS, 1, [d_compare need 7 arguments])
-])
-]) # LC_D_COMPARE_7ARGS
-
-#
-# LC_D_DELETE_CONST
-#
-# 2.6.38 dentry_operations.d_delete() defined 'const' for 1st parameter.
-#
-AC_DEFUN([LC_D_DELETE_CONST], [
-tmp_flags="$EXTRA_KCFLAGS"
-EXTRA_KCFLAGS="-Werror"
-LB_CHECK_COMPILE([if 'dentry_operations.d_delete()' has const declare on first parameter],
-dentry_ops_d_delete_1st_const, [
- #include <linux/dcache.h>
-],[
- const struct dentry *d = NULL;
- ((struct dentry_operations*)0)->d_delete(d);
-],[
- AC_DEFINE(HAVE_D_DELETE_CONST, const,
- [d_delete first parameter declared const])
-],[
- AC_DEFINE(HAVE_D_DELETE_CONST, [],
- [d_delete first parameter declared is not const])
-])
-EXTRA_KCFLAGS="$tmp_flags"
-]) # LC_D_DELETE_CONST
-
-#
-# LC_DCACHE_LOCK
-#
-# 2.6.38 dcache_lock removed. rcu-walk committed.
-#
-AC_DEFUN([LC_DCACHE_LOCK], [
-LB_CHECK_COMPILE([if 'dcache_lock' is exist],
-dcache_lock, [
- #include <linux/dcache.h>
-],[
- spin_lock(&dcache_lock);
-],[
- AC_DEFINE(HAVE_DCACHE_LOCK, 1,
- [dcache_lock is exist])
-])
-]) # LC_DCACHE_LOCK
-
-#
-# LC_INODE_I_RCU
-#
-# 2.6.38 inode.i_rcu added.
-#
-AC_DEFUN([LC_INODE_I_RCU], [
-LB_CHECK_COMPILE([if 'inode.i_rcu' exists],
-inode_i_rcu, [
- #include <linux/fs.h>
-],[
- struct inode ino;
- struct rcu_head rcu = {};
- ino.i_rcu = rcu;
-],[
- AC_DEFINE(HAVE_INODE_I_RCU, 1,
- [inode.i_rcu exists])
-])
-]) # LC_INODE_I_RCU
-
-#
-# LC_BLKDEV_GET_BY_DEV
-#
-# 2.6.38 export blkdev_get_by_dev
-#
-AC_DEFUN([LC_BLKDEV_GET_BY_DEV], [
-LB_CHECK_EXPORT([blkdev_get_by_dev], [fs/block_dev.c],
- [AC_DEFINE(HAVE_BLKDEV_GET_BY_DEV, 1,
- [blkdev_get_by_dev is exported by the kernel])])
-]) # LC_BLKDEV_GET_BY_DEV
-
-#
-# LC_EXPORT_SIMPLE_SETATTR
-#
-# 2.6.38 export simple_setattr
-#
-AC_DEFUN([LC_EXPORT_SIMPLE_SETATTR], [
-LB_CHECK_EXPORT([simple_setattr], [fs/libfs.c],
- [AC_DEFINE(HAVE_SIMPLE_SETATTR, 1,
- [simple_setattr is exported by the kernel])])
-]) # LC_EXPORT_SIMPLE_SETATTR
-
-#
-# LC_HAVE_BLK_PLUG
-#
-# 2.6.38 add struct blk_plug
-#
-AC_DEFUN([LC_HAVE_BLK_PLUG], [
-LB_CHECK_COMPILE([if 'struct blk_plug' exists],
-blk_plug, [
- #include <linux/blkdev.h>
-],[
- struct blk_plug plug;
-
- blk_start_plug(&plug);
- blk_finish_plug(&plug);
-],[
- AC_DEFINE(HAVE_BLK_PLUG, 1,
- [blk_plug struct exists])
-])
-]) # LC_HAVE_BLK_PLUG
-
-#
# LC_HAVE_FSTYPE_MOUNT
#
# 2.6.39 replace get_sb with mount in struct file_system_type
]) # LC_SETNS
#
-# LC_GENERIC_PERMISSION
-#
-# 2.6.38 generic_permission taken 4 parameters.
-# in fact, it means rcu-walk aware permission bring.
-#
-# 3.1 generic_permission taken 2 parameters.
-# see kernel commit 2830ba7f34ebb27c4e5b8b6ef408cd6d74860890
-#
-AC_DEFUN([LC_GENERIC_PERMISSION], [
-LB_CHECK_COMPILE([if 'generic_permission' take 2 arguments],
-generic_permission_2args, [
- #include <linux/fs.h>
-],[
- generic_permission(NULL, 0);
-],[
- AC_DEFINE(HAVE_GENERIC_PERMISSION_2ARGS, 1,
- [generic_permission taken 2 arguments])
-],[
- LB_CHECK_COMPILE([if 'generic_permission' take 4 arguments],
- generic_permission_4args, [
- #include <linux/fs.h>
- ],[
- generic_permission(NULL, 0, 0, NULL);
- ],[
- AC_DEFINE(HAVE_GENERIC_PERMISSION_4ARGS, 1,
- [generic_permission taken 4 arguments])
- ])
-])
-]) # LC_GENERIC_PERMISSION
-
-#
# LC_LM_XXX_LOCK_MANAGER_OPS
#
# 3.1 renames lock-manager ops(lock_manager_operations) from fl_xxx to lm_xxx
LC_OPENSSL_SSK
LC_OPENSSL_GETSEPOL
- # 2.6.32
- LC_BLK_QUEUE_MAX_SEGMENTS
-
- # 2.6.33
- LC_HAVE_XATTR_HANDLER_FLAGS
-
- # 2.6.34
- LC_HAVE_DQUOT_FS_DISK_QUOTA
- LC_HAVE_DQUOT_SUSPEND
- LC_HAVE_ADD_WAIT_QUEUE_EXCLUSIVE
-
# 2.6.35, 3.0.0
- LC_EXPORT_SIMPLE_SETATTR
LC_EXPORT_TRUNCATE_COMPLETE_PAGE
- # 2.6.36
- LC_FS_STRUCT_RWLOCK
- LC_SBOPS_EVICT_INODE
-
- # 2.6.37
- LC_KERNEL_LOCKED
- LC_FS_STRUCT_SEQCOUNT
- LC_DENTRY_PATH_RAW
-
- # 2.6.38
- LC_BLKDEV_GET_BY_DEV
- LC_GENERIC_PERMISSION
- LC_DCACHE_LOCK
- LC_INODE_I_RCU
- LC_D_COMPARE_7ARGS
- LC_D_DELETE_CONST
- LC_HAVE_BLK_PLUG
-
# 2.6.39
LC_HAVE_FHANDLE_SYSCALLS
LC_HAVE_FSTYPE_MOUNT
#include <lustre_patchless_compat.h>
#include <obd_support.h>
-#ifdef HAVE_FS_STRUCT_RWLOCK
-# define LOCK_FS_STRUCT(fs) write_lock(&(fs)->lock)
-# define UNLOCK_FS_STRUCT(fs) write_unlock(&(fs)->lock)
-#else
-# define LOCK_FS_STRUCT(fs) spin_lock(&(fs)->lock)
-# define UNLOCK_FS_STRUCT(fs) spin_unlock(&(fs)->lock)
-#endif
-
-#ifdef HAVE_FS_STRUCT_SEQCOUNT
-# define WRITE_FS_SEQ_BEGIN(fs) write_seqcount_begin(&(fs)->seq)
-# define WRITE_FS_SEQ_END(fs) write_seqcount_end(&(fs)->seq)
-#else
-# define WRITE_FS_SEQ_BEGIN(fs)
-# define WRITE_FS_SEQ_END(fs)
-#endif
-static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
- struct dentry *dentry)
-{
- struct path path;
- struct path old_pwd;
-
- path.mnt = mnt;
- path.dentry = dentry;
- path_get(&path);
- LOCK_FS_STRUCT(fs);
- WRITE_FS_SEQ_BEGIN(fs);
- old_pwd = fs->pwd;
- fs->pwd = path;
- WRITE_FS_SEQ_END(fs);
- UNLOCK_FS_STRUCT(fs);
-
- if (old_pwd.dentry)
- path_put(&old_pwd);
-}
-
#define current_ngroups current_cred()->group_info->ngroups
#define current_groups current_cred()->group_info->small_block
-/*
- * OBD need working random driver, thus all our
- * initialization routines must be called after device
- * driver initialization
- */
-#ifndef MODULE
-#undef module_init
-#define module_init(a) late_initcall(a)
-#endif
-
-#ifndef MODULE_ALIAS_FS
-#define MODULE_ALIAS_FS(name)
-#endif
-
-#ifdef HAVE_GENERIC_PERMISSION_2ARGS
-# define ll_generic_permission(inode, mask, flags, check_acl) \
- generic_permission(inode, mask)
-#elif defined HAVE_GENERIC_PERMISSION_4ARGS
-# define ll_generic_permission(inode, mask, flags, check_acl) \
- generic_permission(inode, mask, flags, check_acl)
-#else
-# define ll_generic_permission(inode, mask, flags, check_acl) \
- generic_permission(inode, mask, check_acl)
-#endif
-
#ifdef HAVE_4ARGS_VFS_SYMLINK
#define ll_vfs_symlink(dir, dentry, mnt, path, mode) \
vfs_symlink(dir, dentry, path, mode)
# define inode_dio_write_done(i) up_write(&(i)->i_alloc_sem)
#endif
-#ifndef HAVE_SIMPLE_SETATTR
-#define simple_setattr(dentry, ops) inode_setattr((dentry)->d_inode, ops)
-#endif
-
#ifndef HAVE_INIT_LIST_HEAD_RCU
static inline void INIT_LIST_HEAD_RCU(struct list_head *list)
{
}
#endif
-#ifndef HAVE_DQUOT_SUSPEND
-# define ll_vfs_dq_init vfs_dq_init
-# define ll_vfs_dq_drop vfs_dq_drop
-# define ll_vfs_dq_transfer vfs_dq_transfer
-# define ll_vfs_dq_off(sb, remount) vfs_dq_off(sb, remount)
-#else
-# define ll_vfs_dq_init dquot_initialize
-# define ll_vfs_dq_drop dquot_drop
-# define ll_vfs_dq_transfer dquot_transfer
-# define ll_vfs_dq_off(sb, remount) dquot_suspend(sb, -1)
-#endif
-
-#ifndef HAVE_BLKDEV_GET_BY_DEV
-# define blkdev_get_by_dev(dev, mode, holder) open_by_devnum(dev, mode)
-#endif
-
#ifdef HAVE_BVEC_ITER
#define bio_idx(bio) (bio->bi_iter.bi_idx)
#define bio_set_sector(bio, sector) (bio->bi_iter.bi_sector = sector)
#define bio_start_sector(bio) (bio->bi_sector)
#endif
-#ifndef HAVE_BLK_QUEUE_MAX_SEGMENTS
-#define blk_queue_max_segments(rq, seg) \
- do { blk_queue_max_phys_segments(rq, seg); \
- blk_queue_max_hw_segments(rq, seg); } while (0)
-#else
-#define queue_max_phys_segments(rq) queue_max_segments(rq)
-#define queue_max_hw_segments(rq) queue_max_segments(rq)
-#endif
-
-#ifdef HAVE_BLK_PLUG
-#define DECLARE_PLUG(plug) struct blk_plug plug
-#else /* !HAVE_BLK_PLUG */
-#define DECLARE_PLUG(name)
-#define blk_start_plug(plug) do {} while (0)
-#define blk_finish_plug(plug) do {} while (0)
-#endif
-
#ifdef HAVE_KMAP_ATOMIC_HAS_1ARG
#define ll_kmap_atomic(a, b) kmap_atomic(a)
#define ll_kunmap_atomic(a, b) kunmap_atomic(a)
#endif
#ifdef HAVE_IOP_XATTR
-#ifdef HAVE_XATTR_HANDLER_FLAGS
#define ll_setxattr generic_setxattr
#define ll_getxattr generic_getxattr
#define ll_removexattr generic_removexattr
-#else
-int ll_setxattr(struct dentry *dentry, const char *name,
- const void *value, size_t size, int flags);
-ssize_t ll_getxattr(struct dentry *dentry, const char *name,
- void *buf, size_t buf_size);
-int ll_removexattr(struct dentry *dentry, const char *name);
-#endif /* ! HAVE_XATTR_HANDLER_FLAGS */
#endif /* HAVE_IOP_XATTR */
#ifndef HAVE_VFS_SETXATTR
__vfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
const void *value, size_t size, int flags)
{
-# ifdef HAVE_XATTR_HANDLER_FLAGS
const struct xattr_handler *handler;
int rc;
rc = handler->set(dentry, name, value, size, flags, handler->flags);
# endif /* !HAVE_XATTR_HANDLER_INODE_PARAM */
return rc;
-# else /* !HAVE_XATTR_HANDLER_FLAGS */
- return ll_setxattr(dentry, name, value, size, flags);
-# endif /* HAVE_XATTR_HANDLER_FLAGS */
}
#endif /* HAVE_VFS_SETXATTR */
(sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGTERM) | \
sigmask(SIGQUIT) | sigmask(SIGALRM))
-/*
- * Wait Queue
- */
-#if !defined(HAVE___ADD_WAIT_QUEUE_EXCLUSIVE) && !defined(HAVE_WAIT_QUEUE_ENTRY)
-static inline void __add_wait_queue_exclusive(wait_queue_head_t *q,
- wait_queue_t *wait)
-{
- wait->flags |= WQ_FLAG_EXCLUSIVE;
- __add_wait_queue(q, wait);
-}
-#endif /* HAVE___ADD_WAIT_QUEUE_EXCLUSIVE */
-
/**
* wait_queue_t of Linux (version < 2.6.34) is a FIFO list for exclusively
* waiting threads, which is not always desirable because all threads will
}
#endif /* !HAVE_TRUNCATE_COMPLETE_PAGE */
-#ifdef HAVE_DCACHE_LOCK
-# define dget_dlock(d) dget_locked(d)
-# define ll_d_count(d) atomic_read(&(d)->d_count)
-#elif defined(HAVE_D_COUNT)
+#ifdef HAVE_D_COUNT
# define ll_d_count(d) d_count(d)
#else
# define ll_d_count(d) ((d)->d_count)
-#endif /* HAVE_DCACHE_LOCK */
+#endif /* HAVE_D_COUNT */
#ifndef HAVE_IN_COMPAT_SYSCALL
#define in_compat_syscall is_compat_task
MODULES := lustre
lustre-objs := dcache.o dir.o file.o llite_lib.o llite_nfs.o
lustre-objs += rw.o lproc_llite.o namei.o symlink.o llite_mmap.o
-@XATTR_HANDLER_TRUE@lustre-objs += xattr.o
-@XATTR_HANDLER_FALSE@lustre-objs += xattr26.o
-lustre-objs += xattr_cache.o
+lustre-objs += xattr.o xattr_cache.o
lustre-objs += rw26.o super25.o statahead.o xattr_security.o
lustre-objs += glimpse.o
lustre-objs += lcommon_cl.o
lustre-objs += vvp_dev.o vvp_page.o vvp_io.o vvp_object.o
lustre-objs += range_lock.o pcc.o
-EXTRA_DIST := $(lustre-objs:.o=.c) llite_internal.h rw26.c super25.c
-EXTRA_DIST += vvp_internal.h range_lock.h pcc.h
-
-@XATTR_HANDLER_TRUE@EXTRA_DIST += xattr26.c
-@XATTR_HANDLER_FALSE@EXTRA_DIST += xattr.c
+EXTRA_DIST := $(lustre-objs:.o=.c) xattr.c rw26.c super25.c
+EXTRA_DIST += llite_internal.h vvp_internal.h range_lock.h pcc.h
@INCLUDE_RULES@
* while d_in_lookup(). We will be called again when the lookup
* completes, and can give a different answer then.
*/
-#ifdef HAVE_D_COMPARE_7ARGS
-static int ll_dcompare(const struct dentry *parent, const struct inode *pinode,
- const struct dentry *dentry, const struct inode *inode,
- unsigned int len, const char *str,
- const struct qstr *name)
-#elif defined(HAVE_D_COMPARE_5ARGS)
+#if defined(HAVE_D_COMPARE_5ARGS)
static int ll_dcompare(const struct dentry *parent, const struct dentry *dentry,
unsigned int len, const char *str,
const struct qstr *name)
#elif defined(HAVE_D_COMPARE_4ARGS)
static int ll_dcompare(const struct dentry *dentry, unsigned int len,
const char *str, const struct qstr *name)
-#else
-static int ll_dcompare(struct dentry *parent, struct qstr *d_name,
- struct qstr *name)
#endif
{
-#if !defined(HAVE_D_COMPARE_7ARGS) && !defined(HAVE_D_COMPARE_5ARGS) && !defined(HAVE_D_COMPARE_4ARGS)
- /* XXX: (ugh !) d_name must be in-dentry structure */
- struct dentry *dentry = container_of(d_name, struct dentry, d_name);
- unsigned int len = d_name->len;
- const char *str = d_name->name;
-#endif
ENTRY;
if (len != name->len)
* - return 0 to cache the dentry
* Should NOT be called with the dcache lock, see fs/dcache.c
*/
-static int ll_ddelete(HAVE_D_DELETE_CONST struct dentry *de)
+static int ll_ddelete(const struct dentry *de)
{
ENTRY;
LASSERT(de);
d_unhashed((struct dentry *)de) ? "" : "hashed,",
list_empty(&de->d_subdirs) ? "" : "subdirs");
-#ifdef HAVE_DCACHE_LOCK
- LASSERT(ll_d_count(de) == 0);
-#else
/* kernel >= 2.6.38 last refcount is decreased after this function. */
LASSERT(ll_d_count(de) == 1);
-#endif
if (d_lustre_invalid((struct dentry *)de))
RETURN(1);
if (likely(lld != NULL)) {
spin_lock(&de->d_lock);
if (likely(de->d_fsdata == NULL)) {
-#ifdef HAVE_DCACHE_LOCK
- /* kernel >= 2.6.38 d_op is set in d_alloc() */
- de->d_op = &ll_d_ops;
- smp_mb();
-#endif
de->d_fsdata = lld;
__d_lustre_invalidate(de);
} else {
CDEBUG(D_INODE, "marking dentries for inode "DFID"(%p) invalid\n",
PFID(ll_inode2fid(inode)), inode);
- ll_lock_dcache(inode);
+ spin_lock(&inode->i_lock);
ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry) {
CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p "
"inode %p flags %d\n", dentry->d_name.len,
d_lustre_invalidate(dentry, 0);
}
- ll_unlock_dcache(inode);
+ spin_unlock(&inode->i_lock);
EXIT;
}
if (lookup_flags & LOOKUP_REVAL)
return 0;
-#ifndef HAVE_DCACHE_LOCK
if (lookup_flags & LOOKUP_RCU)
return -ECHILD;
-#endif
if (dentry_may_statahead(dir, dentry))
ll_statahead(dir, &dentry, dentry->d_inode == NULL);
* here to preserve get_cwd functionality on 2.6.
* Bug 10503 */
if (!dentry->d_inode->i_nlink) {
- ll_lock_dcache(inode);
+ spin_lock(&inode->i_lock);
d_lustre_invalidate(dentry, 0);
- ll_unlock_dcache(inode);
+ spin_unlock(&inode->i_lock);
}
ll_lookup_finish_locks(&oit, dentry);
#endif /* CONFIG_FS_POSIX_ACL */
#endif /* HAVE_IOP_SET_ACL */
-#ifndef HAVE_GENERIC_PERMISSION_2ARGS
-static int
-# ifdef HAVE_GENERIC_PERMISSION_4ARGS
-ll_check_acl(struct inode *inode, int mask, unsigned int flags)
-# else
-ll_check_acl(struct inode *inode, int mask)
-# endif
-{
-# ifdef CONFIG_FS_POSIX_ACL
- struct posix_acl *acl;
- int rc;
- ENTRY;
-
-# ifdef HAVE_GENERIC_PERMISSION_4ARGS
- if (flags & IPERM_FLAG_RCU)
- return -ECHILD;
-# endif
- acl = ll_get_acl(inode, ACL_TYPE_ACCESS);
-
- if (!acl)
- RETURN(-EAGAIN);
-
- rc = posix_acl_permission(inode, acl, mask);
- posix_acl_release(acl);
-
- RETURN(rc);
-# else /* !CONFIG_FS_POSIX_ACL */
- return -EAGAIN;
-# endif /* CONFIG_FS_POSIX_ACL */
-}
-#endif /* HAVE_GENERIC_PERMISSION_2ARGS */
-
-#ifdef HAVE_GENERIC_PERMISSION_4ARGS
-int ll_inode_permission(struct inode *inode, int mask, unsigned int flags)
-#else
-# ifdef HAVE_INODE_PERMISION_2ARGS
int ll_inode_permission(struct inode *inode, int mask)
-# else
-int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
-# endif
-#endif
{
int rc = 0;
struct ll_sb_info *sbi;
bool squash_id = false;
ENTRY;
-#ifdef MAY_NOT_BLOCK
if (mask & MAY_NOT_BLOCK)
return -ECHILD;
-#elif defined(HAVE_GENERIC_PERMISSION_4ARGS)
- if (flags & IPERM_FLAG_RCU)
- return -ECHILD;
-#endif
/* as root inode are NOT getting validated in lookup operation,
* need to do it before permission check. */
}
ll_stats_ops_tally(sbi, LPROC_LL_INODE_PERM, 1);
- rc = ll_generic_permission(inode, mask, flags, ll_check_acl);
+ rc = generic_permission(inode, mask);
/* restore current process's credentials and FS capability */
if (squash_id) {
revert_creds(old_cred);
struct lmv_user_md *lum, const char *name);
int ll_get_fid_by_name(struct inode *parent, const char *name,
int namelen, struct lu_fid *fid, struct inode **inode);
-#ifdef HAVE_GENERIC_PERMISSION_4ARGS
-int ll_inode_permission(struct inode *inode, int mask, unsigned int flags);
-#else
-# ifndef HAVE_INODE_PERMISION_2ARGS
-int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd);
-# else
int ll_inode_permission(struct inode *inode, int mask);
-# endif
-#endif
int ll_ioctl_check_project(struct inode *inode, struct fsxattr *fa);
int ll_ioctl_fsgetxattr(struct inode *inode, unsigned int cmd,
unsigned long arg);
*bits = it->it_lock_bits;
}
-static inline void ll_lock_dcache(struct inode *inode)
-{
-#ifdef HAVE_DCACHE_LOCK
- spin_lock(&dcache_lock);
-#else
- spin_lock(&inode->i_lock);
-#endif
-}
-
-static inline void ll_unlock_dcache(struct inode *inode)
-{
-#ifdef HAVE_DCACHE_LOCK
- spin_unlock(&dcache_lock);
-#else
- spin_unlock(&inode->i_lock);
-#endif
-}
-
static inline int d_lustre_invalid(const struct dentry *dentry)
{
struct ll_dentry_data *lld = ll_d2d(dentry);
CDEBUG(D_SUPER, "rootfid "DFID"\n", PFID(&sbi->ll_root_fid));
sb->s_op = &lustre_super_operations;
-#ifdef HAVE_XATTR_HANDLER_FLAGS
sb->s_xattr = ll_xattr_handlers;
-#endif
#if THREAD_SIZE >= 8192 /*b=17630*/
sb->s_export_op = &lustre_export_operations;
#endif
sbi->ll_fsname, err);
GOTO(out_root, err);
}
-#ifdef HAVE_DCACHE_LOCK
- sb->s_root->d_op = &ll_d_ops;
-#endif
sbi->ll_sdev_orig = sb->s_dev;
if (err)
GOTO(out_free_cfg, err);
-#ifndef HAVE_DCACHE_LOCK
/* kernel >= 2.6.38 store dentry operations in sb->s_d_op. */
sb->s_d_op = &ll_d_ops;
-#endif
+
/* UUID handling */
generate_random_uuid(uuid.b);
snprintf(sbi->ll_sb_uuid.uuid, UUID_SIZE, "%pU", uuid.b);
ll_i2sbi(inode)->ll_fsname,
PFID(ll_inode2fid(inode)), inode, nrpages);
-#ifdef HAVE_SBOPS_EVICT_INODE
ll_clear_inode(inode);
-#endif
clear_inode(inode);
EXIT;
if (rc < 0)
GOTO(ldata_free, rc);
-#ifdef HAVE_XATTR_HANDLER_FLAGS
rc = ll_xattr_list(inode, XATTR_NAME_LINK, XATTR_TRUSTED_T, buf.lb_buf,
buf.lb_len, OBD_MD_FLXATTR);
-#else
- rc = ll_getxattr(file_dentry(file), XATTR_NAME_LINK, buf.lb_buf,
- buf.lb_len);
-#endif /* HAVE_XATTR_HANDLER_FLAGS */
if (rc < 0)
GOTO(lb_free, rc);
struct dentry *dentry, *tmp_subdir;
DECLARE_LL_D_HLIST_NODE_PTR(p);
- ll_lock_dcache(dir);
+ spin_lock(&dir->i_lock);
ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry) {
spin_lock(&dentry->d_lock);
if (!list_empty(&dentry->d_subdirs)) {
}
spin_unlock(&dentry->d_lock);
}
- ll_unlock_dcache(dir);
+ spin_unlock(&dir->i_lock);
}
int ll_test_inode_by_fid(struct inode *inode, void *opaque)
discon_alias = invalid_alias = NULL;
- ll_lock_dcache(inode);
+ spin_lock(&inode->i_lock);
ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry) {
LASSERT(alias != dentry);
dget_dlock(alias);
spin_unlock(&alias->d_lock);
}
- ll_unlock_dcache(inode);
+ spin_unlock(&inode->i_lock);
return alias;
}
state->pccs_type = pcci->pcci_type;
state->pccs_open_count = count;
state->pccs_flags = ll_i2info(inode)->lli_pcc_state;
-#ifdef HAVE_DENTRY_PATH_RAW
path = dentry_path_raw(pcci->pcci_path.dentry, buf, buf_len);
if (IS_ERR(path))
GOTO(out_unlock, rc = PTR_ERR(path));
-#else
- path = "UNKNOWN";
-#endif
if (strlcpy(state->pccs_path, path, buf_len) >= buf_len)
GOTO(out_unlock, rc = -ENAMETOOLONG);
return &lli->lli_vfs_inode;
}
-#ifdef HAVE_INODE_I_RCU
static void ll_inode_destroy_callback(struct rcu_head *head)
{
struct inode *inode = container_of(head, struct inode, i_rcu);
{
call_rcu(&inode->i_rcu, ll_inode_destroy_callback);
}
-#else
-static void ll_destroy_inode(struct inode *inode)
-{
- struct ll_inode_info *ptr = ll_i2info(inode);
- OBD_SLAB_FREE_PTR(ptr, ll_inode_cachep);
-}
-#endif
/* exported operations */
struct super_operations lustre_super_operations =
{
.alloc_inode = ll_alloc_inode,
.destroy_inode = ll_destroy_inode,
-#ifdef HAVE_SBOPS_EVICT_INODE
.evict_inode = ll_delete_inode,
-#else
- .clear_inode = ll_clear_inode,
- .delete_inode = ll_delete_inode,
-#endif
.put_super = ll_put_super,
.statfs = ll_statfs,
.umount_begin = ll_umount_begin,
cl_env_put(cl_inode_fini_env, &cl_inode_fini_refcheck);
vvp_global_fini();
-#ifdef HAVE_INODE_I_RCU
/*
* Make sure all delayed rcu free inodes are flushed before we
* destroy cache.
*/
rcu_barrier();
-#endif
+
kmem_cache_destroy(ll_inode_cachep);
kmem_cache_destroy(ll_file_data_slab);
kmem_cache_destroy(pcc_inode_slab);
+++ /dev/null
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2017, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/xattr.h>
-#include <linux/selinux.h>
-
-#define DEBUG_SUBSYSTEM S_LLITE
-
-#include <obd_support.h>
-#include <lustre_dlm.h>
-#include <uapi/linux/lustre/lustre_ver.h>
-#include <lustre_eacl.h>
-
-#include "llite_internal.h"
-
-/* xattr related to IMA(Integrity Measurement Architecture) */
-#ifndef XATTR_NAME_IMA
-#define XATTR_NAME_IMA "security.ima"
-#endif
-#ifndef XATTR_NAME_EVM
-#define XATTR_NAME_EVM "security.evm"
-#endif
-
-static
-int get_xattr26_type(const char *name)
-{
- if (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS))
- return XATTR_ACL_ACCESS_T;
-
- if (!strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT))
- return XATTR_ACL_DEFAULT_T;
-
- if (!strncmp(name, XATTR_USER_PREFIX,
- sizeof(XATTR_USER_PREFIX) - 1))
- return XATTR_USER_T;
-
- if (!strncmp(name, XATTR_TRUSTED_PREFIX,
- sizeof(XATTR_TRUSTED_PREFIX) - 1))
- return XATTR_TRUSTED_T;
-
- if (!strncmp(name, XATTR_SECURITY_PREFIX,
- sizeof(XATTR_SECURITY_PREFIX) - 1))
- return XATTR_SECURITY_T;
-
- if (!strncmp(name, XATTR_LUSTRE_PREFIX,
- sizeof(XATTR_LUSTRE_PREFIX) - 1))
- return XATTR_LUSTRE_T;
-
- return XATTR_OTHER_T;
-}
-
-static
-int xattr_type_filter(struct ll_sb_info *sbi, int xattr_type)
-{
- if ((xattr_type == XATTR_ACL_ACCESS_T ||
- xattr_type == XATTR_ACL_DEFAULT_T) &&
- !(sbi->ll_flags & LL_SBI_ACL))
- return -EOPNOTSUPP;
-
- if (xattr_type == XATTR_USER_T && !(sbi->ll_flags & LL_SBI_USER_XATTR))
- return -EOPNOTSUPP;
- if (xattr_type == XATTR_TRUSTED_T && !cfs_capable(CFS_CAP_SYS_ADMIN))
- return -EPERM;
- if (xattr_type == XATTR_OTHER_T)
- return -EOPNOTSUPP;
-
- return 0;
-}
-
-static
-int ll_setxattr_common(struct inode *inode, const char *name,
- const void *value, size_t size,
- int flags, __u64 valid)
-{
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct ptlrpc_request *req = NULL;
- int xattr_type, rc;
- const char *pv = value;
- ENTRY;
-
- /*FIXME: enable IMA when the conditions are ready */
- if (strncmp(name, XATTR_NAME_IMA,
- sizeof(XATTR_NAME_IMA)) == 0 ||
- strncmp(name, XATTR_NAME_EVM,
- sizeof(XATTR_NAME_EVM)) == 0)
- return -EOPNOTSUPP;
-
- xattr_type = get_xattr26_type(name);
- rc = xattr_type_filter(sbi, xattr_type);
- if (rc)
- RETURN(rc);
-
- if ((xattr_type == XATTR_ACL_ACCESS_T ||
- xattr_type == XATTR_ACL_DEFAULT_T) &&
- !inode_owner_or_capable(inode))
- return -EPERM;
-
- /* b10667: ignore lustre special xattr for now */
- if (strcmp(name, XATTR_NAME_HSM) == 0 ||
- (xattr_type == XATTR_TRUSTED_T &&
- strcmp(name, XATTR_NAME_LOV) == 0) ||
- (xattr_type == XATTR_LUSTRE_T &&
- strcmp(name, "lustre.lov") == 0))
- RETURN(0);
-
- /* LU-549: Disable security.selinux when selinux is disabled */
- if (xattr_type == XATTR_SECURITY_T && !selinux_is_enabled() &&
- strcmp(name, "security.selinux") == 0)
- RETURN(-EOPNOTSUPP);
-
- /* In user.* namespace, only regular files and directories can have
- * extended attributes. */
- if (xattr_type == XATTR_USER_T) {
- if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
- RETURN(-EPERM);
- }
-
- rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), valid, name, pv,
- size, flags, ll_i2suppgid(inode), &req);
- if (rc) {
- if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
- LCONSOLE_INFO("Disabling user_xattr feature because "
- "it is not supported on the server\n");
- sbi->ll_flags &= ~LL_SBI_USER_XATTR;
- }
- RETURN(rc);
- }
-
- ptlrpc_req_finished(req);
- RETURN(0);
-}
-
-static int get_hsm_state(struct inode *inode, __u32 *hus_states)
-{
- struct md_op_data *op_data;
- struct hsm_user_state *hus;
- int rc;
-
- OBD_ALLOC_PTR(hus);
- if (hus == NULL)
- return -ENOMEM;
-
- op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
- LUSTRE_OPC_ANY, hus);
- if (!IS_ERR(op_data)) {
- rc = obd_iocontrol(LL_IOC_HSM_STATE_GET, ll_i2mdexp(inode),
- sizeof(*op_data), op_data, NULL);
- if (rc == 0)
- *hus_states = hus->hus_states;
- else
- CDEBUG(D_VFSTRACE, "obd_iocontrol failed. rc = %d\n",
- rc);
-
- ll_finish_md_op_data(op_data);
- } else {
- rc = PTR_ERR(op_data);
- CDEBUG(D_VFSTRACE, "Could not prepare the opdata. rc = %d\n",
- rc);
- }
- OBD_FREE_PTR(hus);
- return rc;
-}
-
-static int ll_adjust_lum(struct inode *inode, struct lov_user_md *lump)
-{
- struct lov_comp_md_v1 *comp_v1 = (struct lov_comp_md_v1 *)lump;
- struct lov_user_md *v1 = lump;
- bool release_checked = false;
- bool need_clear_release = false;
- __u16 entry_count = 1;
- bool is_composite = false;
- int rc = 0;
- int i;
-
- if (lump == NULL)
- return 0;
-
- if (lump->lmm_magic == LOV_USER_MAGIC_COMP_V1) {
- entry_count = comp_v1->lcm_entry_count;
- is_composite = true;
- }
-
- for (i = 0; i < entry_count; i++) {
- if (lump->lmm_magic == LOV_USER_MAGIC_COMP_V1)
- v1 = (struct lov_user_md *)((char *)comp_v1 +
- comp_v1->lcm_entries[i].lcme_offset);
-
- /* Attributes that are saved via getxattr will always
- * have the stripe_offset as 0. Instead, the MDS
- * should be allowed to pick the starting OST index.
- * b=17846 */
- if (!is_composite && v1->lmm_stripe_offset == 0)
- v1->lmm_stripe_offset = -1;
-
- /* Avoid anyone directly setting the RELEASED flag. */
- if (v1->lmm_pattern & LOV_PATTERN_F_RELEASED) {
- if (!release_checked) {
- __u32 state = HS_NONE;
- rc = get_hsm_state(inode, &state);
- if (rc)
- return rc;
- if (!(state & HS_ARCHIVED))
- need_clear_release = true;
- release_checked = true;
- }
- if (need_clear_release)
- v1->lmm_pattern ^= LOV_PATTERN_F_RELEASED;
- }
- }
-
- return rc;
-}
-
-static int ll_setstripe_ea(struct dentry *dentry, struct lov_user_md *lump,
- size_t size)
-{
- struct inode *inode = dentry->d_inode;
- int rc = 0;
-
- rc = ll_adjust_lum(inode, lump);
- if (rc)
- return rc;
-
- if (lump != NULL && S_ISREG(inode->i_mode)) {
- u64 it_flags = FMODE_WRITE;
- int lum_size;
-
- lum_size = ll_lov_user_md_size(lump);
- if (lum_size < 0 || size < lum_size)
- return -ERANGE;
-
- rc = ll_lov_setstripe_ea_info(inode, dentry, it_flags, lump,
- lum_size);
- /**
- * b=10667: ignore -EEXIST.
- * Silently eat error on setting trusted.lov/lustre.lov
- * attribute for SuSE 9, it added default option to copy
- * all attributes in 'cp' command. rsync, tar --xattrs
- * also will try to set LOVEA for existing files.
- */
- if (rc == -EEXIST)
- rc = 0;
- } else if (S_ISDIR(inode->i_mode)) {
- rc = ll_dir_setstripe(inode, lump, 0);
- }
-
- return rc;
-}
-
-int ll_setxattr(struct dentry *dentry, const char *name,
- const void *value, size_t size, int flags)
-{
- struct inode *inode = dentry->d_inode;
-
- LASSERT(inode);
- LASSERT(name);
-
- CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
- PFID(ll_inode2fid(inode)), inode, name);
-
- ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
-
- /* lustre/trusted.lov.xxx would be passed through xattr API */
- if (strcmp(name, XATTR_NAME_LOV) == 0 ||
- strcmp(name, XATTR_LUSTRE_LOV) == 0)
- return ll_setstripe_ea(dentry, (struct lov_user_md *)value,
- size);
- else if (strcmp(name, XATTR_NAME_LMA) == 0 ||
- strcmp(name, XATTR_NAME_LINK) == 0)
- return 0;
-
- return ll_setxattr_common(inode, name, value, size, flags,
- OBD_MD_FLXATTR);
-}
-
-int ll_removexattr(struct dentry *dentry, const char *name)
-{
- struct inode *inode = dentry->d_inode;
-
- LASSERT(inode);
- LASSERT(name);
-
- CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
- PFID(ll_inode2fid(inode)), inode, name);
-
- ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_REMOVEXATTR, 1);
- return ll_setxattr_common(inode, name, NULL, 0, 0,
- OBD_MD_FLXATTRRM);
-}
-
-int ll_getxattr_common(struct inode *inode, const char *name,
- void *buffer, size_t size, __u64 valid)
-{
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct ptlrpc_request *req = NULL;
- int xattr_type, rc;
- void *xdata;
- struct ll_inode_info *lli = ll_i2info(inode);
- ENTRY;
-
- CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
- PFID(ll_inode2fid(inode)), inode);
-
- /* listxattr have slightly different behavior from of ext3:
- * without 'user_xattr' ext3 will list all xattr names but
- * filtered out "^user..*"; we list them all for simplicity.
- */
- if (!name) {
- xattr_type = XATTR_OTHER_T;
- goto do_getxattr;
- }
-
- xattr_type = get_xattr26_type(name);
- rc = xattr_type_filter(sbi, xattr_type);
- if (rc)
- RETURN(rc);
-
- /* LU-549: Disable security.selinux when selinux is disabled */
- if (xattr_type == XATTR_SECURITY_T && !selinux_is_enabled() &&
- strcmp(name, "security.selinux") == 0)
- RETURN(-EOPNOTSUPP);
-
-#ifdef CONFIG_FS_POSIX_ACL
- /* posix acl is under protection of LOOKUP lock. when calling to this,
- * we just have path resolution to the target inode, so we have great
- * chance that cached ACL is uptodate.
- */
- if (xattr_type == XATTR_ACL_ACCESS_T) {
- struct posix_acl *acl;
-
- spin_lock(&lli->lli_lock);
- acl = posix_acl_dup(lli->lli_posix_acl);
- spin_unlock(&lli->lli_lock);
-
- if (!acl)
- RETURN(-ENODATA);
-
- rc = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
- posix_acl_release(acl);
- RETURN(rc);
- }
- if (xattr_type == XATTR_ACL_DEFAULT_T && !S_ISDIR(inode->i_mode))
- RETURN(-ENODATA);
-#endif
-
-do_getxattr:
- if (sbi->ll_xattr_cache_enabled &&
- xattr_type != XATTR_ACL_ACCESS_T &&
- (xattr_type != XATTR_SECURITY_T ||
- strcmp(name, "security.selinux") != 0)) {
- rc = ll_xattr_cache_get(inode, name, buffer, size, valid);
- if (rc == -EAGAIN)
- goto getxattr_nocache;
- if (rc < 0)
- GOTO(out_xattr, rc);
-
- /* Add "system.posix_acl_access" to the list */
- if (lli->lli_posix_acl != NULL && valid & OBD_MD_FLXATTRLS) {
- if (size == 0) {
- rc += sizeof(XATTR_NAME_ACL_ACCESS);
- } else if (size - rc >= sizeof(XATTR_NAME_ACL_ACCESS)) {
- memcpy(buffer + rc, XATTR_NAME_ACL_ACCESS,
- sizeof(XATTR_NAME_ACL_ACCESS));
- rc += sizeof(XATTR_NAME_ACL_ACCESS);
- } else {
- GOTO(out_xattr, rc = -ERANGE);
- }
- }
- } else {
-getxattr_nocache:
- rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), valid,
- name, size, &req);
- if (rc < 0)
- GOTO(out_xattr, rc);
-
- /* only detect the xattr size */
- if (size == 0)
- GOTO(out, rc);
-
- if (size < rc)
- GOTO(out, rc = -ERANGE);
-
- /* do not need swab xattr data */
- xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA,
- rc);
- if (!xdata)
- GOTO(out, rc = -EPROTO);
-
- memcpy(buffer, xdata, rc);
- }
-
- EXIT;
-
-out_xattr:
- if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
- LCONSOLE_INFO("%s: disabling user_xattr feature because "
- "it is not supported on the server: rc = %d\n",
- ll_i2sbi(inode)->ll_fsname, rc);
- sbi->ll_flags &= ~LL_SBI_USER_XATTR;
- }
-out:
- ptlrpc_req_finished(req);
- return rc;
-}
-
-static ssize_t ll_getxattr_lov(struct inode *inode, void *buf, size_t buf_size)
-{
- ssize_t rc;
-
- if (S_ISREG(inode->i_mode)) {
- struct cl_object *obj = ll_i2info(inode)->lli_clob;
- struct lu_env *env;
- struct cl_layout cl = {
- .cl_buf.lb_buf = buf,
- .cl_buf.lb_len = buf_size,
- };
- __u16 refcheck;
- __u32 magic;
-
- if (obj == NULL)
- RETURN(-ENODATA);
-
- env = cl_env_get(&refcheck);
- if (IS_ERR(env))
- RETURN(PTR_ERR(env));
-
- rc = cl_object_layout_get(env, obj, &cl);
- if (rc < 0)
- GOTO(out_env, rc);
-
- if (cl.cl_size == 0)
- GOTO(out_env, rc = -ENODATA);
-
- rc = cl.cl_size;
-
- if (buf_size == 0)
- GOTO(out_env, rc);
-
- LASSERT(buf != NULL && rc <= buf_size);
-
- /* Do not return layout gen for getxattr() since
- * otherwise it would confuse tar --xattr by
- * recognizing layout gen as stripe offset when the
- * file is restored. See LU-2809. */
- magic = ((struct lov_mds_md *)buf)->lmm_magic;
- if (magic == LOV_MAGIC_COMP_V1 || magic == LOV_MAGIC_FOREIGN)
- goto out_env;
-
- ((struct lov_mds_md *)buf)->lmm_layout_gen = 0;
-out_env:
- cl_env_put(env, &refcheck);
-
- RETURN(rc);
- } else if (S_ISDIR(inode->i_mode)) {
- struct lov_mds_md *lmm = NULL;
- int lmm_size = 0;
- struct ptlrpc_request *req = NULL;
-
- rc = ll_dir_getstripe(inode, (void **)&lmm, &lmm_size,
- &req, 0);
- if (rc < 0)
- GOTO(out_req, rc);
-
- if (buf_size == 0)
- GOTO(out_req, rc = lmm_size);
-
- if (buf_size < lmm_size)
- GOTO(out_req, rc = -ERANGE);
-
- memcpy(buf, lmm, lmm_size);
- GOTO(out_req, rc = lmm_size);
-out_req:
- if (req != NULL)
- ptlrpc_req_finished(req);
-
- return rc;
- } else {
- RETURN(-ENODATA);
- }
-}
-
-ssize_t ll_getxattr(struct dentry *dentry, const char *name, void *buf,
- size_t buf_size)
-{
- struct inode *inode = dentry->d_inode;
-
- LASSERT(inode);
- LASSERT(name);
-
- CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
- PFID(ll_inode2fid(inode)), inode, name);
-
- ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
-
- if (strcmp(name, XATTR_LUSTRE_LOV) == 0 ||
- strcmp(name, XATTR_NAME_LOV) == 0)
- return ll_getxattr_lov(inode, buf, buf_size);
- else
- return ll_getxattr_common(inode, name, buf, buf_size,
- OBD_MD_FLXATTR);
-}
-
-ssize_t ll_listxattr(struct dentry *dentry, char *buf, size_t buf_size)
-{
- struct inode *inode = dentry->d_inode;
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- char *xattr_name;
- ssize_t rc, rc2;
- size_t len, rem;
-
- CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
- PFID(ll_inode2fid(inode)), inode);
-
- ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LISTXATTR, 1);
-
- rc = ll_getxattr_common(inode, NULL, buf, buf_size, OBD_MD_FLXATTRLS);
- if (rc < 0)
- RETURN(rc);
-
- /* If we're being called to get the size of the xattr list
- * (buf_size == 0) then just assume that a lustre.lov xattr
- * exists. */
- if (buf_size == 0)
- RETURN(rc + sizeof(XATTR_LUSTRE_LOV));
-
- xattr_name = buf;
- rem = rc;
-
- while (rem > 0) {
- len = strnlen(xattr_name, rem - 1) + 1;
- rem -= len;
- if (xattr_type_filter(sbi, get_xattr26_type(xattr_name)) == 0) {
- /* Skip OK xattr type, leave it in buffer. */
- xattr_name += len;
- continue;
- }
-
- /* Move up remaining xattrs in buffer removing the
- * xattr that is not OK. */
- memmove(xattr_name, xattr_name + len, rem);
- rc -= len;
- }
-
- rc2 = ll_getxattr_lov(inode, NULL, 0);
- if (rc2 == -ENODATA)
- RETURN(rc);
-
- if (rc2 < 0)
- RETURN(rc2);
-
- if (buf_size < rc + sizeof(XATTR_LUSTRE_LOV))
- RETURN(-ERANGE);
-
- memcpy(buf + rc, XATTR_LUSTRE_LOV, sizeof(XATTR_LUSTRE_LOV));
-
- RETURN(rc + sizeof(XATTR_LUSTRE_LOV));
-}
#include <linux/selinux.h>
#include <linux/statfs.h>
#include <linux/version.h>
-#ifdef HAVE_KERNEL_LOCKED
-#include <linux/smp_lock.h>
-#endif
#include <llog_swab.h>
#include <lustre_disk.h>
child->d_name.name = name;
child->d_name.len = strlen(name);
- ll_vfs_dq_init(parent);
+ dquot_initialize(parent);
inode_lock(parent);
bh = osd_ldiskfs_find_entry(parent, &child->d_name, &de, NULL, NULL);
if (IS_ERR(bh))
child->d_parent = dird;
child->d_inode = NULL;
- ll_vfs_dq_init(dir);
+ dquot_initialize(dir);
inode_lock(dir);
bh = osd_ldiskfs_find_entry(dir, &child->d_name, &de, NULL, NULL);
if (IS_ERR(bh)) {
if (OBD_FAIL_CHECK(OBD_FAIL_OSD_COMPAT_INVALID_ENTRY))
inode->i_ino++;
- ll_vfs_dq_init(dir->d_inode);
+ dquot_initialize(dir->d_inode);
inode_lock(dir->d_inode);
rc = osd_ldiskfs_add_entry(info, osd, th, child, inode, NULL);
inode_unlock(dir->d_inode);
if (IS_ERR(jh))
RETURN(PTR_ERR(jh));
- ll_vfs_dq_init(src_parent);
- ll_vfs_dq_init(dir);
+ dquot_initialize(src_parent);
+ dquot_initialize(dir);
inode_lock(src_parent);
inode_lock(dir);
(attr->la_valid & LA_GID && attr->la_gid != i_gid_read(inode))) {
struct iattr iattr;
- ll_vfs_dq_init(inode);
+ dquot_initialize(inode);
iattr.ia_valid = 0;
if (attr->la_valid & LA_UID)
iattr.ia_valid |= ATTR_UID;
iattr.ia_uid = make_kuid(&init_user_ns, attr->la_uid);
iattr.ia_gid = make_kgid(&init_user_ns, attr->la_gid);
- rc = ll_vfs_dq_transfer(inode, &iattr);
+ rc = dquot_transfer(inode, &iattr);
if (rc) {
CERROR("%s: quota transfer failed: rc = %d. Is quota "
"enforcement enabled on the ldiskfs "
RETURN(fl);
/* Remove old PFID EA entry firstly. */
- ll_vfs_dq_init(inode);
+ dquot_initialize(inode);
rc = osd_removexattr(dentry, inode, XATTR_NAME_FID);
if (rc == -ENODATA) {
if ((fl & LU_XATTR_REPLACE) && !(fl & LU_XATTR_CREATE))
obj->oo_pfid_in_lma = 0;
}
} else {
- ll_vfs_dq_init(inode);
+ dquot_initialize(inode);
dentry->d_inode = inode;
dentry->d_sb = inode->i_sb;
rc = osd_removexattr(dentry, inode, name);
LASSERT(oh->ot_handle != NULL);
LASSERT(oh->ot_handle->h_transaction != NULL);
- ll_vfs_dq_init(dir);
+ dquot_initialize(dir);
dentry = osd_child_dentry_get(env, obj,
(char *)key, strlen((char *)key));
osd_get_ldiskfs_dirent_param(ldp, fid);
child = osd_child_dentry_get(info->oti_env, pobj, name, strlen(name));
child->d_fsdata = (void *)ldp;
- ll_vfs_dq_init(pobj->oo_inode);
+ dquot_initialize(pobj->oo_inode);
rc = osd_ldiskfs_add_entry(info, osd_obj2dev(pobj), oth->ot_handle,
child, cinode, hlock);
if (rc == 0 && OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_TYPE)) {
ldp = (struct ldiskfs_dentry_param *)osd_oti_get(env)->oti_ldp;
osd_get_ldiskfs_dirent_param(ldp, fid);
dentry->d_fsdata = (void *)ldp;
- ll_vfs_dq_init(dir);
+ dquot_initialize(dir);
rc = osd_ldiskfs_add_entry(info, dev, jh, dentry, inode, hlock);
/*
* It is too bad, we cannot reinsert the name entry back.
union {
#if defined(HAVE_DQUOT_QC_DQBLK)
struct qc_dqblk oti_qdq;
-#elif defined(HAVE_DQUOT_FS_DISK_QUOTA)
- struct fs_disk_quota oti_fdq;
#else
- struct if_dqblk oti_dqblk;
+ struct fs_disk_quota oti_fdq;
#endif
struct if_dqinfo oti_dqinfo;
};
{
struct dentry *dentry = &info->oti_child_dentry;
- ll_vfs_dq_init(inode);
+ dquot_initialize(inode);
dentry->d_inode = inode;
dentry->d_sb = inode->i_sb;
return osd_setxattr(dentry, inode, name, buf, buflen, fl);
int rc = 0;
bool fault_inject;
bool integrity_enabled;
- DECLARE_PLUG(plug);
+ struct blk_plug plug;
ENTRY;
fault_inject = OBD_FAIL_CHECK(OBD_FAIL_OST_INTEGRITY_FAULT);
unsigned int bi_size = bio_sectors(bio) << 9;
/* Dang! I have to fragment this I/O */
- CDEBUG(D_INODE, "bio++ sz %d vcnt %d(%d) "
- "sectors %d(%d) psg %d(%d) hsg %d(%d)\n",
+ CDEBUG(D_INODE,
+ "bio++ sz %d vcnt %d(%d) sectors %d(%d) psg %d(%d)\n",
bi_size, bio->bi_vcnt, bio->bi_max_vecs,
bio_sectors(bio),
queue_max_sectors(q),
bio->bi_phys_segments,
- queue_max_phys_segments(q),
- 0, queue_max_hw_segments(q));
+ queue_max_segments(q));
rc = osd_bio_integrity_handle(osd, bio,
iobuf, bio_start_page_idx,
fault_inject, integrity_enabled);
RETURN(rc);
isize = i_size_read(inode);
- ll_vfs_dq_init(inode);
+ dquot_initialize(inode);
for (i = 0; i < npages; i++) {
if (lnb[i].lnb_rc == -ENOSPC &&
LASSERT(handle != NULL);
LASSERT(inode != NULL);
- ll_vfs_dq_init(inode);
+ dquot_initialize(inode);
/* XXX: don't check: one declared chunk can be used many times */
/* osd_trans_exec_op(env, handle, OSD_OT_WRITE); */
LASSERT(dt_object_exists(dt));
LASSERT(osd_invariant(obj));
LASSERT(inode != NULL);
- ll_vfs_dq_init(inode);
+ dquot_initialize(inode);
LASSERT(th);
oh = container_of(th, struct osd_thandle, ot_super);
LASSERT(oi);
LASSERT(oi->oi_inode);
- ll_vfs_dq_init(oi->oi_inode);
+ dquot_initialize(oi->oi_inode);
bag = &oi->oi_dir.od_container;
ipd = osd_idx_ipd_get(oti->oti_env, bag);
LASSERT(oi);
LASSERT(oi->oi_inode);
- ll_vfs_dq_init(oi->oi_inode);
+ dquot_initialize(oi->oi_inode);
bag = &oi->oi_dir.od_container;
ipd = osd_idx_ipd_get(oti->oti_env, bag);
struct osd_thread_info *info = osd_oti_get(env);
#if defined(HAVE_DQUOT_QC_DQBLK)
struct qc_dqblk *dqblk = &info->oti_qdq;
-#elif defined(HAVE_DQUOT_FS_DISK_QUOTA)
- struct fs_disk_quota *dqblk = &info->oti_fdq;
#else
- struct if_dqblk *dqblk = &info->oti_dqblk;
+ struct fs_disk_quota *dqblk = &info->oti_fdq;
#endif
struct super_block *sb = osd_sb(osd_obj2dev(osd_dt_obj(dtobj)));
struct lquota_acct_rec *rec = (struct lquota_acct_rec *)dtrec;
__u64 id = *((__u64 *)dtkey);
int rc;
-#ifdef HAVE_DQUOT_KQID
struct kqid qid;
-#endif
int type;
ENTRY;
type = fid2type(lu_object_fid(&dtobj->do_lu));
memset(dqblk, 0, sizeof(*dqblk));
-#ifdef HAVE_DQUOT_KQID
qid = make_kqid(&init_user_ns, type, id);
rc = sb->s_qcop->get_dqblk(sb, qid, dqblk);
-#else
- rc = sb->s_qcop->get_dqblk(sb, type, (qid_t) id, dqblk);
-#endif
if (rc)
RETURN(rc);
#if defined(HAVE_DQUOT_QC_DQBLK)
rec->bspace = dqblk->d_space;
rec->ispace = dqblk->d_ino_count;
-#elif defined(HAVE_DQUOT_FS_DISK_QUOTA)
+#else
rec->bspace = dqblk->d_bcount;
rec->ispace = dqblk->d_icount;
-#else
- rec->bspace = dqblk->dqb_curspace;
- rec->ispace = dqblk->dqb_curinodes;
#endif
RETURN(+1);
}
rc = __osd_xattr_get(inode, dentry, XATTR_NAME_FID, ff, sizeof(*ff));
if (rc == sizeof(*ff)) {
/* 2) delete the old XATTR_NAME_FID */
- ll_vfs_dq_init(inode);
+ dquot_initialize(inode);
rc = osd_removexattr(dentry, inode, XATTR_NAME_FID);
if (rc)
GOTO(stop, rc);
# define ASSERT_KERNEL_CTXT(msg) do {} while(0)
#endif
+static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
+ struct dentry *dentry)
+{
+ struct path path;
+ struct path old_pwd;
+
+ path.mnt = mnt;
+ path.dentry = dentry;
+ path_get(&path);
+ spin_lock(&fs->lock);
+ write_seqcount_begin(&fs->seq);
+ old_pwd = fs->pwd;
+ fs->pwd = path;
+ write_seqcount_end(&fs->seq);
+ spin_unlock(&fs->lock);
+
+ if (old_pwd.dentry)
+ path_put(&old_pwd);
+}
+
/* push / pop to root of obd store */
void push_ctxt(struct lvfs_run_ctxt *save, struct lvfs_run_ctxt *new_ctx)
{