])
])
+# since 2.6.19 nlmsg_multicast() needs 5 argument.
+AC_DEFUN([LIBCFS_NLMSG_MULTICAST],
+[AC_MSG_CHECKING([nlmsg_multicast needs 5 argument])
+LB_LINUX_TRY_COMPILE([
+ #include <net/netlink.h>
+],[
+ nlmsg_multicast(NULL, NULL, 0, 0, 0);
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_NLMSG_MULTICAST_5ARGS, 1,
+ [nlmsg_multicast needs 5 argument])
+],[
+ AC_MSG_RESULT(NO)
+])
+])
+
+#
+# LIBCFS_NETLINK
+#
+# If we have netlink.h, and nlmsg_new takes 2 args (2.6.19)
+#
+AC_DEFUN([LIBCFS_NETLINK],
+[AC_MSG_CHECKING([if netlink.h can be compiled])
+LB_LINUX_TRY_COMPILE([
+ #include <net/netlink.h>
+],[],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_NETLINK, 1, [net/netlink.h found])
+
+ AC_MSG_CHECKING([if nlmsg_new takes a 2nd argument])
+ LB_LINUX_TRY_COMPILE([
+ #include <net/netlink.h>
+ ],[
+ nlmsg_new(100, GFP_KERNEL);
+ ],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_NETLINK_NL2, 1, [nlmsg_new takes 2 args])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
# 2.6.20 API change INIT_WORK use 2 args and not
# store data inside
AC_DEFUN([LIBCFS_3ARGS_INIT_WORK],
])
EXTRA_KCFLAGS="$tmp_flags"
])
+
# 2.6.23 lost dtor argument
AC_DEFUN([LIBCFS_KMEM_CACHE_CREATE_DTOR],
[AC_MSG_CHECKING([check kmem_cache_create has dtor argument])
])
])
+# 2.6.24
+AC_DEFUN([LIBCFS_NETLINK_CBMUTEX],
+[AC_MSG_CHECKING([for mutex in netlink_kernel_create])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/netlink.h>
+],[
+ struct mutex *lock = NULL;
+
+ netlink_kernel_create(0, 0, NULL, lock, NULL);
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_NETLINK_CBMUTEX, 1,
+ [netlink_kernel_create want mutex for callback])
+],[
+ AC_MSG_RESULT(NO)
+])
+])
+
# 2.6.24 request not use real numbers for ctl_name
-AC_DEFUN([LN_SYSCTL_UNNUMBERED],
+AC_DEFUN([LIBCFS_SYSCTL_UNNUMBERED],
[AC_MSG_CHECKING([for CTL_UNNUMBERED])
LB_LINUX_TRY_COMPILE([
#include <linux/sysctl.h>
])
# 2.6.24 lost scatterlist->page
-AC_DEFUN([LN_SCATTERLIST_SETPAGE],
+AC_DEFUN([LIBCFS_SCATTERLIST_SETPAGE],
[AC_MSG_CHECKING([for exist sg_set_page])
LB_LINUX_TRY_COMPILE([
#include <linux/scatterlist.h>
])
])
+# 2.6.24
+AC_DEFUN([LIBCFS_NETWORK_NAMESPACE],
+[AC_MSG_CHECKING([for network stack has namespaces])
+LB_LINUX_TRY_COMPILE([
+ #include <net/net_namespace.h>
+],[
+ struct net *net = &init_ns;
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INIT_NET, 1,
+ [kernel is support network namespaces ])
+],[
+ AC_MSG_RESULT(NO)
+])
+])
+
+
+# 2.6.24
+AC_DEFUN([LIBCFS_NETLINK_NETNS],
+[AC_MSG_CHECKING([for netlink support net ns])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/netlink.h>
+],[
+ struct net *net = NULL;
+ struct mutex *lock = NULL;
+
+ netlink_kernel_create(net, 0, 0, NULL,
+ lock,
+ NULL);
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_NETLINK_NS, 1,
+ [netlink is support network namespace])
+# XXX
+# for now - if kernel have netlink ns - he uses cbmutex
+ AC_DEFINE(HAVE_NETLINK_CBMUTEX, 1,
+ [netlink_kernel_create want mutex for callback])
+
+],[
+ AC_MSG_RESULT(NO)
+])
+])
+
+# ~2.6.24
+AC_DEFUN([LIBCFS_NL_BROADCAST_GFP],
+[AC_MSG_CHECKING([for netlink_broadcast is want to have gfp parameter])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/netlink.h>
+],[
+ gfp_t gfp = GFP_KERNEL;
+
+ netlink_broadcast(NULL, NULL, 0, 0, gfp);
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_NL_BROADCAST_GFP, 1,
+ [netlink brouacast is want to have gfp paramter])
+],[
+ AC_MSG_RESULT(NO)
+])
+])
+
+#
+# LIBCFS_FUNC_DUMP_TRACE
+#
+# 2.6.23 exports dump_trace() so we can dump_stack() on any task
+# 2.6.24 has stacktrace_ops.address with "reliable" parameter
+#
+AC_DEFUN([LIBCFS_FUNC_DUMP_TRACE],
+[LB_CHECK_SYMBOL_EXPORT([dump_trace],
+[kernel/ksyms.c arch/${LINUX_ARCH%_64}/kernel/traps_64.c],[
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
+ AC_MSG_CHECKING([whether we can really use dump_stack])
+ LB_LINUX_TRY_COMPILE([
+ struct task_struct;
+ struct pt_regs;
+ #include <asm/stacktrace.h>
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_DUMP_TRACE, 1, [dump_trace is exported])
+ ],[
+ AC_MSG_RESULT(no)
+ ],[
+ ])
+ AC_MSG_CHECKING([whether print_trace_address has reliable argument])
+ LB_LINUX_TRY_COMPILE([
+ struct task_struct;
+ struct pt_regs;
+ void print_addr(void *data, unsigned long addr, int reliable);
+ #include <asm/stacktrace.h>
+ ],[
+ struct stacktrace_ops ops;
+
+ ops.address = print_addr;
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_TRACE_ADDRESS_RELIABLE, 1,
+ [print_trace_address has reliable argument])
+ ],[
+ AC_MSG_RESULT(no)
+ ],[
+ ])
+EXTRA_KCFLAGS="$tmp_flags"
+])
+])
+
+
# 2.6.26 use int instead of atomic for sem.count
-AC_DEFUN([LN_SEM_COUNT],
+AC_DEFUN([LIBCFS_SEM_COUNT],
[AC_MSG_CHECKING([atomic sem.count])
LB_LINUX_TRY_COMPILE([
#include <asm/semaphore.h>
])
])
+# 2.6.27 have second argument to sock_map_fd
+AC_DEFUN([LIBCFS_SOCK_MAP_FD_2ARG],
+[AC_MSG_CHECKING([sock_map_fd have second argument])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/net.h>
+],[
+ sock_map_fd(NULL, 0);
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SOCK_MAP_FD_2ARG, 1,
+ [sock_map_fd have second argument])
+],[
+ AC_MSG_RESULT(NO)
+])
+])
+
#
# LIBCFS_PROG_LINUX
#
# 2.6.18
LIBCFS_TASKLIST_LOCK
# 2.6.19
+LIBCFS_NETLINK
+LIBCFS_NLMSG_MULTICAST
LIBCFS_KMEM_CACHE_DESTROY_INT
LIBCFS_ATOMIC_PANIC_NOTIFIER
# 2.6.20
LIBCFS_KMEM_CACHE
# 2.6.23
LIBCFS_KMEM_CACHE_CREATE_DTOR
+LIBCFS_NETLINK_CBMUTEX
# 2.6.24
-LN_SYSCTL_UNNUMBERED
-LN_SCATTERLIST_SETPAGE
+LIBCFS_SYSCTL_UNNUMBERED
+LIBCFS_SCATTERLIST_SETPAGE
+LIBCFS_NL_BROADCAST_GFP
+LIBCFS_NETWORK_NAMESPACE
+LIBCFS_NETLINK_NETNS
+LIBCFS_FUNC_DUMP_TRACE
# 2.6.26
-LN_SEM_COUNT
+LIBCFS_SEM_COUNT
+LIBCFS_SOCK_MAP_FD_2ARG
])
#
return sock->sk->sk_wmem_queued;
}
+#ifdef HAVE_INIT_NET
+#define DEFAULT_NET (&init_net)
+#else
+/* some broken backports */
+#define DEFAULT_NET (NULL)
+#endif
+
#endif
prefetch(pos->member.next))
#endif /* list_for_each_entry */
+#ifndef list_for_each_entry_rcu
+#define list_for_each_entry_rcu(pos, head, member) \
+ list_for_each_entry(pos, head, member)
+#endif
+
#ifndef list_for_each_entry_reverse
/**
* Iterate backwards over a list of given type.
#include <libcfs/libcfs.h>
-/* OFED backport #defines netlink_kernel_create with 6 args.
- I haven't a clue why that header file gets included here,
- but we must undo its mischief. */
-#ifdef BACKPORT_LINUX_NETLINK_H
-#undef netlink_kernel_create
-#endif
-
-
/* Single Netlink Message type to send all Lustre messages */
#define LNL_MSG 26
if (atomic_inc_return(&lnl_start_count) > 1)
GOTO(out, rc = 0);
- lnl_socket = netlink_kernel_create(LNL_SOCKET, LNL_GRP_CNT,
+ lnl_socket = netlink_kernel_create(
+#ifdef HAVE_NETLINK_NS
+ DEFAULT_NET,
+#endif
+ LNL_SOCKET, LNL_GRP_CNT,
NULL /* incoming cb */,
+#ifdef HAVE_NETLINK_CBMUTEX
+ NULL,
+#endif
THIS_MODULE);
if (lnl_socket == NULL) {
CERROR("Cannot open socket %d\n", LNL_SOCKET);
if (rc > 0)
rc = 0;
} else {
+#ifdef HAVE_NLMSG_MULTICAST_5ARGS
+ rc = nlmsg_multicast(lnl_socket, skb, 0, group, GFP_KERNEL);
+#else
rc = nlmsg_multicast(lnl_socket, skb, 0, group);
+#endif
}
CDEBUG(0, "Sent message pid=%d, group=%d, rc=%d\n", pid, group, rc);
*/
int cfs_mem_is_in_cache(const void *addr, const cfs_mem_cache_t *kmem)
{
+#ifdef CONFIG_SLAB
struct page *page;
/*
if (unlikely(PageCompound(page)))
page = (struct page *)page->private;
return PageSlab(page) && ((void *)page->lru.next) == kmem;
+#else
+ return 1;
+#endif
}
EXPORT_SYMBOL(cfs_mem_is_in_cache);
void cfs_enter_debugger(void)
{
#if defined(CONFIG_KGDB)
- BREAKPOINT();
+// BREAKPOINT();
#elif defined(__arch_um__)
asm("int $3");
#else
return rc;
}
+#ifdef HAVE_SOCK_MAP_FD_2ARG
+ fd = sock_map_fd(sock,0);
+#else
fd = sock_map_fd(sock);
+#endif
if (fd < 0) {
rc = fd;
sock_release(sock);
])
-#
-# LN_FUNC_DUMP_TRACE
-#
-# 2.6.23 exports dump_trace() so we can dump_stack() on any task
-# 2.6.24 has stacktrace_ops.address with "reliable" parameter
-#
-AC_DEFUN([LN_FUNC_DUMP_TRACE],
-[LB_CHECK_SYMBOL_EXPORT([dump_trace],
-[kernel/ksyms.c arch/${LINUX_ARCH%_64}/kernel/traps_64.c],[
- tmp_flags="$EXTRA_KCFLAGS"
- EXTRA_KCFLAGS="-Werror"
- AC_MSG_CHECKING([whether we can really use dump_stack])
- LB_LINUX_TRY_COMPILE([
- struct task_struct;
- struct pt_regs;
- #include <asm/stacktrace.h>
- ],[
- ],[
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_DUMP_TRACE, 1, [dump_trace is exported])
- ],[
- AC_MSG_RESULT(no)
- ],[
- ])
- AC_MSG_CHECKING([whether print_trace_address has reliable argument])
- LB_LINUX_TRY_COMPILE([
- struct task_struct;
- struct pt_regs;
- void print_addr(void *data, unsigned long addr, int reliable);
- #include <asm/stacktrace.h>
- ],[
- struct stacktrace_ops ops;
-
- ops.address = print_addr;
- ],[
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_TRACE_ADDRESS_RELIABLE, 1,
- [print_trace_address has reliable argument])
- ],[
- AC_MSG_RESULT(no)
- ],[
- ])
-EXTRA_KCFLAGS="$tmp_flags"
-])
-])
#
#
LN_CONFIG_RALND
LN_CONFIG_PTLLND
LN_CONFIG_MX
-LN_FUNC_DUMP_TRACE
])
#
2.6.16.60-0.39.3 (SLES 10),
2.6.18-128.7.1.el5 (RHEL 5),
2.6.18-128.7.1.el5 (OEL 5),
- 2.6.22.14 vanilla (kernel.org).
+ 2.6.27.19-5 (SLES11)
+ 2.6.27 vanilla (kernel.org).
* Client support for unpatched kernels:
(see http://wiki.lustre.org/index.php?title=Patchless_Client)
- 2.6.16 - 2.6.21 vanilla (kernel.org)
+ 2.6.16 - 2.6.27 vanilla (kernel.org)
* Recommended e2fsprogs version: 1.41.6.sun1
* Note that reiserfs quotas are disabled on SLES 10 in this kernel.
* RHEL 4 and RHEL 5/SLES 10 clients behaves differently on 'cd' to a
* File join has been disabled in this release, refer to Bugzilla 16929.
Severity : enhancement
+Bugzilla : 14250
+Description: Add 2.6.27 and SLES11 (patchless client) support
+
+Severity : enhancement
Bugzilla : 19325
Description: Adjust locks' extents on their first enqueue, so that at the time
they get granted, there is no need for another pass through the
])
-#
# added in 2.6.16
#
AC_DEFUN([LC_STRUCT_INTENT_FILE],
AC_DEFUN([LC_PAGE_CHECKED],
[AC_MSG_CHECKING([kernel has PageChecked and SetPageChecked])
LB_LINUX_TRY_COMPILE([
- #include <linux/mm.h>
- #include <linux/page-flags.h>
+ #include <linux/autoconf.h>
+#ifdef HAVE_LINUX_MMTYPES_H
+ #include <linux/mm_types.h>
+#endif
+ #include <linux/page-flags.h>
],[
- #ifndef PageChecked
- #error PageChecked not defined in kernel
- #endif
- #ifndef SetPageChecked
- #error SetPageChecked not defined in kernel
- #endif
+ struct page *p;
+
+ /* before 2.6.26 this define*/
+ #ifndef PageChecked
+ /* 2.6.26 use function instead of define for it */
+ SetPageChecked(p);
+ PageChecked(p);
+ #endif
],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_PAGE_CHECKED, 1,
])
])
+# 2.6.18
+
+
# 2.6.23 have return type 'void' for unregister_blkdev
AC_DEFUN([LC_UNREGISTER_BLKDEV_RETURN_INT],
[AC_MSG_CHECKING([if unregister_blkdev return int])
])
# 2.6.23 change .sendfile to .splice_read
+# RHEL4 (-92 kernel) have both sendfile and .splice_read API
+AC_DEFUN([LC_KERNEL_SENDFILE],
+[AC_MSG_CHECKING([if kernel has .sendfile])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ struct file_operations file;
+
+ file.sendfile = NULL;
+], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_KERNEL_SENDFILE, 1,
+ [kernel has .sendfile])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.23 change .sendfile to .splice_read
AC_DEFUN([LC_KERNEL_SPLICE_READ],
[AC_MSG_CHECKING([if kernel has .splice_read])
LB_LINUX_TRY_COMPILE([
# 2.6.23 extract nfs export related data into exportfs.h
AC_DEFUN([LC_HAVE_EXPORTFS_H],
-[
-tmpfl="$CFLAGS"
-CFLAGS="$CFLAGS -I$LINUX_OBJ/include"
-AC_CHECK_HEADERS([linux/exportfs.h])
-CFLAGS="$tmpfl"
+[LB_CHECK_FILE([$LINUX/include/linux/exportfs.h], [
+ AC_DEFINE(HAVE_LINUX_EXPORTFS_H, 1,
+ [kernel has include/exportfs.h])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.23 has new page fault handling API
+AC_DEFUN([LC_VM_OP_FAULT],
+[AC_MSG_CHECKING([kernel has .fault in vm_operation_struct])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/mm.h>
+],[
+ struct vm_operations_struct op;
+
+ op.fault = NULL;
+], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_VM_OP_FAULT, 1,
+ [kernel has .fault in vm_operation_struct])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+#2.6.23 has new shrinker API
+AC_DEFUN([LC_REGISTER_SHRINKER],
+[AC_MSG_CHECKING([if kernel has register_shrinker])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/mm.h>
+],[
+ register_shrinker(NULL);
+], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_REGISTER_SHRINKER, 1,
+ [kernel has register_shrinker])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.24 has bio_endio with 2 args
+AC_DEFUN([LC_BIO_ENDIO_2ARG],
+[AC_MSG_CHECKING([if kernel has bio_endio with 2 args])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/bio.h>
+],[
+ bio_endio(NULL, 0);
+], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_BIO_ENDIO_2ARG, 1,
+ [kernel has bio_endio with 2 args])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.24 has new members in exports struct.
+AC_DEFUN([LC_FH_TO_DENTRY],
+[AC_MSG_CHECKING([if kernel has .fh_to_dentry member in export_operations struct])
+LB_LINUX_TRY_COMPILE([
+#ifdef HAVE_LINUX_EXPORTFS_H
+ #include <linux/exportfs.h>
+#else
+ #include <linux/fs.h>
+#endif
+],[
+ struct export_operations exp;
+
+ exp.fh_to_dentry = NULL;
+], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_FH_TO_DENTRY, 1,
+ [kernel has .fh_to_dentry member in export_operations struct])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.24 need linux/mm_types.h included
+AC_DEFUN([LC_HAVE_MMTYPES_H],
+[LB_CHECK_FILE([$LINUX/include/linux/mm_types.h], [
+ AC_DEFINE(HAVE_LINUX_MMTYPES_H, 1,
+ [kernel has include/mm_types.h])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.24 removes long aged procfs entry -> deleted member
+AC_DEFUN([LC_PROCFS_DELETED],
+[AC_MSG_CHECKING([if kernel has deleted member in procfs entry struct])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/proc_fs.h>
+],[
+ struct proc_dir_entry pde;
+
+ pde.deleted = NULL;
+], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_PROCFS_DELETED, 1,
+ [kernel has deleted member in procfs entry struct])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.25 change define to inline
+AC_DEFUN([LC_MAPPING_CAP_WRITEBACK_DIRTY],
+[AC_MSG_CHECKING([if kernel have mapping_cap_writeback_dirty])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/backing-dev.h>
+],[
+ #ifndef mapping_cap_writeback_dirty
+ mapping_cap_writeback_dirty(NULL);
+ #endif
+],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_MAPPING_CAP_WRITEBACK_DIRTY, 1,
+ [kernel have mapping_cap_writeback_dirty])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+
+
+# 2.6.26 isn't export set_fs_pwd and change paramter in fs struct
+AC_DEFUN([LC_FS_STRUCT_USE_PATH],
+[AC_MSG_CHECKING([fs_struct use path structure])
+LB_LINUX_TRY_COMPILE([
+ #include <asm/atomic.h>
+ #include <linux/spinlock.h>
+ #include <linux/fs_struct.h>
+],[
+ struct path path;
+ struct fs_struct fs;
+
+ fs.pwd = path;
+], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_FS_STRUCT_USE_PATH, 1,
+ [fs_struct use path structure])
+],[
+ AC_MSG_RESULT([no])
+])
])
#
])
])
+#2.6.27
+AC_DEFUN([LC_INODE_PERMISION_2ARGS],
+[AC_MSG_CHECKING([inode_operations->permission has two args])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ struct inode *inode;
+
+ inode->i_op->permission(NULL,0);
+],[
+ AC_DEFINE(HAVE_INODE_PERMISION_2ARGS, 1,
+ [inode_operations->permission has two args])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.27 has file_remove_suid instead of remove_suid
+AC_DEFUN([LC_FILE_REMOVE_SUID],
+[AC_MSG_CHECKING([kernel has file_remove_suid])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ file_remove_suid(NULL);
+],[
+ AC_DEFINE(HAVE_FILE_REMOVE_SUID, 1,
+ [kernel have file_remove_suid])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.27 have new page locking API
+AC_DEFUN([LC_TRYLOCKPAGE],
+[AC_MSG_CHECKING([kernel uses trylock_page for page lock])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/pagemap.h>
+],[
+ trylock_page(NULL);
+],[
+ AC_DEFINE(HAVE_TRYLOCK_PAGE, 1,
+ [kernel uses trylock_page for page lock])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# vfs_symlink seems to have started out with 3 args until 2.6.7 where a
+# "mode" argument was added, but then again, in some later version it was
+# removed
+AC_DEFUN([LC_4ARGS_VFS_SYMLINK],
+[AC_MSG_CHECKING([if vfs_symlink wants 4 args])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ struct inode *dir;
+ struct dentry *dentry;
+ const char *oldname = NULL;
+ int mode = 0;
+
+ vfs_symlink(dir, dentry, oldname, mode);
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_4ARGS_VFS_SYMLINK, 1,
+ [vfs_symlink wants 4 args])
+],[
+ AC_MSG_RESULT(no)
+])
+])
+
+# 2.6.27 sles11 remove the bi_hw_segments
+AC_DEFUN([LC_BI_HW_SEGMENTS],
+[AC_MSG_CHECKING([struct bio has a bi_hw_segments field])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/bio.h>
+],[
+ struct bio io;
+ io.bi_hw_segments = 0;
+],[
+ AC_DEFINE(HAVE_BI_HW_SEGMENTS, 1,
+ [struct bio has a bi_hw_segments field])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.27 sles11 move the quotaio_v1.h to fs
+AC_DEFUN([LC_HAVE_QUOTAIO_V1_H],
+[LB_CHECK_FILE([$LINUX/include/linux/quotaio_v1.h],[
+ AC_DEFINE(HAVE_QUOTAIO_V1_H, 1,
+ [kernel has include/linux/quotaio_v1.h])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# sles10 sp2 need 5 parameter for vfs_symlink
+AC_DEFUN([LC_VFS_SYMLINK_5ARGS],
+[AC_MSG_CHECKING([vfs_symlink need 5 parameter])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ struct inode *dir = NULL;
+ struct dentry *dentry = NULL;
+ struct vfsmount *mnt = NULL;
+ const char * path = NULL;
+ vfs_symlink(dir, dentry, mnt, path, 0);
+],[
+ AC_DEFINE(HAVE_VFS_SYMLINK_5ARGS, 1,
+ [vfs_symlink need 5 parameteres])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.27 removed the read_inode from super_operations.
+AC_DEFUN([LC_READ_INODE_IN_SBOPS],
+[AC_MSG_CHECKING([super_operations has a read_inode field])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ struct super_operations *sop;
+ sop->read_inode(NULL);
+],[
+ AC_DEFINE(HAVE_READ_INODE_IN_SBOPS, 1,
+ [super_operations has a read_inode])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.27 sles11 has sb_any_quota_active
+AC_DEFUN([LC_SB_ANY_QUOTA_ACTIVE],
+[AC_MSG_CHECKING([Kernel has sb_any_quota_active])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/quotaops.h>
+],[
+ sb_any_quota_active(NULL);
+],[
+ AC_DEFINE(HAVE_SB_ANY_QUOTA_ACTIVE, 1,
+ [Kernel has a sb_any_quota_active])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.27 sles11 has sb_has_quota_active
+AC_DEFUN([LC_SB_HAS_QUOTA_ACTIVE],
+[AC_MSG_CHECKING([Kernel has sb_has_quota_active])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/quotaops.h>
+],[
+ sb_has_quota_active(NULL, 0);
+],[
+ AC_DEFINE(HAVE_SB_HAS_QUOTA_ACTIVE, 1,
+ [Kernel has a sb_has_quota_active])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.27 has inode_permission instead of permisson
+AC_DEFUN([LC_EXPORT_INODE_PERMISSION],
+[LB_CHECK_SYMBOL_EXPORT([inode_permission],
+[fs/namei.c],[
+AC_DEFINE(HAVE_EXPORT_INODE_PERMISSION, 1,
+ [inode_permission is exported by the kernel])
+],[
+])
+])
+
+# 2.6.27 use 5th parameter in quota_on for remount.
+AC_DEFUN([LC_QUOTA_ON_5ARGS],
+[AC_MSG_CHECKING([quota_on needs 5 parameters])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/quota.h>
+],[
+ struct quotactl_ops *qop;
+ qop->quota_on(NULL, 0, 0, NULL, 0);
+],[
+ AC_DEFINE(HAVE_QUOTA_ON_5ARGS, 1,
+ [quota_on needs 5 paramters])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.27 use 3th parameter in quota_off for remount.
+AC_DEFUN([LC_QUOTA_OFF_3ARGS],
+[AC_MSG_CHECKING([quota_off needs 3 parameters])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/quota.h>
+],[
+ struct quotactl_ops *qop;
+ qop->quota_off(NULL, 0, 0);
+],[
+ AC_DEFINE(HAVE_QUOTA_OFF_3ARGS, 1,
+ [quota_off needs 3 paramters])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.27 has vfs_dq_off inline function.
+AC_DEFUN([LC_VFS_DQ_OFF],
+[AC_MSG_CHECKING([vfs_dq_off is defined])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/quotaops.h>
+],[
+ vfs_dq_off(NULL, 0);
+],[
+ AC_DEFINE(HAVE_VFS_DQ_OFF, 1, [vfs_dq_off is defined])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
#
# LC_LINUX_FIEMAP_H
#
LC_PERCPU_COUNTER
LC_QUOTA64
LC_4ARGS_VFS_SYMLINK
- LC_NETLINK
# does the kernel have VFS intent patches?
LC_VFS_INTENT_PATCHES
# 2.6.23
LC_UNREGISTER_BLKDEV_RETURN_INT
LC_KERNEL_SPLICE_READ
+ LC_KERNEL_SENDFILE
LC_HAVE_EXPORTFS_H
+ LC_VM_OP_FAULT
+ LC_REGISTER_SHRINKER
+
+ # 2.6.24
+ LC_HAVE_MMTYPES_H
+ LC_BIO_ENDIO_2ARG
+ LC_FH_TO_DENTRY
+ LC_PROCFS_DELETED
+
+ #2.6.25
+ LC_MAPPING_CAP_WRITEBACK_DIRTY
+
+ # 2.6.26
+ LC_FS_STRUCT_USE_PATH
+
+ # 2.6.27
+ LC_INODE_PERMISION_2ARGS
+ LC_FILE_REMOVE_SUID
+ LC_TRYLOCKPAGE
+ LC_READ_INODE_IN_SBOPS
+ LC_EXPORT_INODE_PERMISSION
+ LC_QUOTA_ON_5ARGS
+ LC_QUOTA_OFF_3ARGS
+ LC_VFS_DQ_OFF
+
+ # 2.6.27.15-2 sles11
+ LC_BI_HW_SEGMENTS
+ LC_HAVE_QUOTAIO_V1_H
+ LC_VFS_SYMLINK_5ARGS
+ LC_SB_ANY_QUOTA_ACTIVE
+ LC_SB_HAS_QUOTA_ACTIVE
])
#
],[
AC_MSG_RESULT([no])
])
+
],[
AC_MSG_RESULT([no])
])
AC_DEFINE(HAVE_QUOTA64, 1, [have quota64])
AC_MSG_RESULT([yes])
],[
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-I $LINUX/fs"
+ LB_LINUX_TRY_COMPILE([
+ #include <linux/kernel.h>
+ #include <linux/fs.h>
+ #include <quotaio_v2.h>
+ struct v2r1_disk_dqblk dqblk_r1;
+ ],[],[
+ AC_DEFINE(HAVE_QUOTA64, 1, [have quota64])
+ AC_MSG_RESULT([yes])
+ ],[
LB_CHECK_FILE([$LINUX/include/linux/lustre_version.h],[
AC_MSG_ERROR([You have got no 64-bit kernel quota support.])
],[])
AC_MSG_RESULT([no])
])
+ EXTRA_KCFLAGS=$tmp_flags
+ ])
fi
])
])
#
-# LC_NETLINK
-#
-# If we have netlink.h, and nlmsg_new takes 2 args
-#
-AC_DEFUN([LC_NETLINK],
-[AC_MSG_CHECKING([if netlink.h can be compiled])
-LB_LINUX_TRY_COMPILE([
- #include <net/netlink.h>
-],[],[
- AC_MSG_RESULT([yes])
- AC_DEFINE(HAVE_NETLINK, 1, [net/netlink.h found])
-
- AC_MSG_CHECKING([if nlmsg_new takes a 2nd argument])
- LB_LINUX_TRY_COMPILE([
- #include <net/netlink.h>
- ],[
- nlmsg_new(100, GFP_KERNEL);
- ],[
- AC_MSG_RESULT([yes])
- AC_DEFINE(HAVE_NETLINK_NL2, 1, [nlmsg_new takes 2 args])
- ],[
- AC_MSG_RESULT([no])
- ])
-],[
- AC_MSG_RESULT([no])
-])
-])
-
-#
# LC_CONFIGURE
#
# other configure checks
lustre/kernel_patches/targets/2.6-fc5.target
lustre/kernel_patches/targets/2.6-patchless.target
lustre/kernel_patches/targets/2.6-sles10.target
+lustre/kernel_patches/targets/2.6-sles11.target
lustre/kernel_patches/targets/2.6-oel5.target
lustre/ldlm/Makefile
lustre/fid/Makefile
int crw_nonblock;
};
+
/**
* State for io.
*
union {
struct cl_rd_io {
struct cl_io_rw_common rd;
- int rd_is_sendfile;
} ci_rd;
struct cl_wr_io {
struct cl_io_rw_common wr;
return io->ci_type == CIT_WRITE && io->u.ci_wr.wr_append;
}
-int cl_io_is_sendfile(const struct cl_io *io);
-
struct cl_io *cl_io_top(struct cl_io *io);
void cl_io_print(const struct lu_env *env, void *cookie,
struct inode *inode, struct cl_object *clob);
/**
- * Common IO arguments for various VFS I/O interfaces.
- */
-struct ccc_io_args {
- int cia_is_sendfile;
-#ifndef HAVE_FILE_WRITEV
- struct kiocb *cia_iocb;
-#endif
- struct iovec *cia_iov;
- unsigned long cia_nrsegs;
- read_actor_t cia_actor;
- void *cia_target;
-};
-
-/**
* Locking policy for truncate.
*/
enum ccc_trunc_lock_type {
TRUNC_MATCH
};
+
/**
* IO state private to vvp or slp layers.
*/
#endif
};
+/**
+ * True, if \a io is a normal io, False for other (sendfile, splice*).
+ * must be impementated in arch specific code.
+ */
+int cl_is_normalio(const struct lu_env *env, const struct cl_io *io);
+
extern struct lu_context_key ccc_key;
extern struct lu_context_key ccc_session_key;
int cl_local_size(struct inode *inode);
__u16 ll_dirent_type_get(struct lu_dirent *ent);
-ino_t cl_fid_build_ino(struct lu_fid *fid);
-__u32 cl_fid_build_gen(struct lu_fid *fid);
+ino_t cl_fid_build_ino(const struct lu_fid *fid);
+__u32 cl_fid_build_gen(const struct lu_fid *fid);
#ifdef INVARIANT_CHECK
# define CLOBINVRNT(env, clob, expr) \
#define ll_iattr iattr
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) */
+#ifdef HAVE_FS_STRUCT_USE_PATH
+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;
+ write_lock(&fs->lock);
+ old_pwd = fs->pwd;
+ path_get(&path);
+ fs->pwd = path;
+ write_unlock(&fs->lock);
+
+ if (old_pwd.dentry)
+ path_put(&old_pwd);
+}
+
+#else
+
static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
struct dentry *dentry)
{
mntput(old_pwdmnt);
}
}
+#endif
/*
* set ATTR_BLOCKS to a high value to avoid any risk of collision with other
#endif
/* XXX our code should be using the 2.6 calls, not the other way around */
-#define TryLockPage(page) TestSetPageLocked(page)
+#ifdef HAVE_TRYLOCK_PAGE
+#define TestSetPageLocked(page) (!trylock_page(page))
+#endif
+
#define Page_Uptodate(page) PageUptodate(page)
#define ll_redirty_page(page) set_page_dirty(page)
#define to_kdev_t(dev) (dev)
#define kdev_t_to_nr(dev) (dev)
#define val_to_kdev(dev) (dev)
-#define ILOOKUP(sb, ino, test, data) ilookup5(sb, ino, test, data);
+#define ILOOKUP(sb, ino, test, data) ilookup5(sb, ino, test, (void *)(data));
#include <linux/writeback.h>
wbc.end = end;
#endif
-#ifdef mapping_cap_writeback_dirty
+#ifdef HAVE_MAPPING_CAP_WRITEBACK_DIRTY
if (!mapping_cap_writeback_dirty(mapping))
rc = 0;
#else
#define synchronize_rcu() synchronize_kernel()
#endif
+#ifdef HAVE_FILE_REMOVE_SUID
+# define ll_remove_suid(file, mnt) file_remove_suid(file)
+#else
+# ifdef HAVE_SECURITY_PLUG
+# define ll_remove_suid(file,mnt) remove_suid(file->f_dentry,mnt)
+# else
+# define ll_remove_suid(file,mnt) remove_suid(file->f_dentry)
+# endif
+#endif
+
#ifdef HAVE_SECURITY_PLUG
-#define ll_remove_suid(inode,mnt) remove_suid(inode,mnt)
#define ll_vfs_rmdir(dir,entry,mnt) vfs_rmdir(dir,entry,mnt)
#define ll_vfs_mkdir(inode,dir,mnt,mode) vfs_mkdir(inode,dir,mnt,mode)
#define ll_vfs_link(old,mnt,dir,new,mnt1) vfs_link(old,mnt,dir,new,mnt1)
#define ll_vfs_rename(old,old_dir,mnt,new,new_dir,mnt1) \
vfs_rename(old,old_dir,mnt,new,new_dir,mnt1)
#else
-#define ll_remove_suid(inode,mnt) remove_suid(inode)
#define ll_vfs_rmdir(dir,entry,mnt) vfs_rmdir(dir,entry)
#define ll_vfs_mkdir(inode,dir,mnt,mode) vfs_mkdir(inode,dir,mode)
#define ll_vfs_link(old,mnt,dir,new,mnt1) vfs_link(old,dir,new)
#define cpu_to_node(cpu) 0
#endif
+#ifdef HAVE_REGISTER_SHRINKER
+typedef int (*shrinker_t)(int nr_to_scan, gfp_t gfp_mask);
+
+static inline
+struct shrinker *set_shrinker(int seek, shrinker_t func)
+{
+ struct shrinker *s;
+
+ s = kmalloc(sizeof(*s), GFP_KERNEL);
+ if (s == NULL)
+ return (NULL);
+
+ s->shrink = func;
+ s->seeks = seek;
+
+ register_shrinker(s);
+
+ return s;
+}
+
+static inline
+void remove_shrinker(struct shrinker *shrinker)
+{
+ if (shrinker == NULL)
+ return;
+
+ unregister_shrinker(shrinker);
+ kfree(shrinker);
+}
+#endif
+
+#ifdef HAVE_BIO_ENDIO_2ARG
+#define cfs_bio_io_error(a,b) bio_io_error((a))
+#define cfs_bio_endio(a,b,c) bio_endio((a),(c))
+#else
+#define cfs_bio_io_error(a,b) bio_io_error((a),(b))
+#define cfs_bio_endio(a,b,c) bio_endio((a),(b),(c))
+#endif
+
+#ifdef HAVE_FS_STRUCT_USE_PATH
+#define cfs_fs_pwd(fs) ((fs)->pwd.dentry)
+#define cfs_fs_mnt(fs) ((fs)->pwd.mnt)
+#define cfs_path_put(nd) path_put(&(nd)->path)
+#else
+#define cfs_fs_pwd(fs) ((fs)->pwd)
+#define cfs_fs_mnt(fs) ((fs)->pwdmnt)
+#define cfs_path_put(nd) path_release(nd)
+#endif
+
#ifndef abs
static inline int abs(int x)
{
#define SLAB_DESTROY_BY_RCU 0
#endif
+#ifdef HAVE_SB_HAS_QUOTA_ACTIVE
+#define ll_sb_has_quota_active(sb, type) sb_has_quota_active(sb, type)
+#else
+#define ll_sb_has_quota_active(sb, type) sb_has_quota_enabled(sb, type)
+#endif
+
+#ifdef HAVE_SB_ANY_QUOTA_ACTIVE
+#define ll_sb_any_quota_active(sb) sb_any_quota_active(sb)
+#else
+#define ll_sb_any_quota_active(sb) sb_any_quota_enabled(sb)
+#endif
+
+static inline int
+ll_quota_on(struct super_block *sb, int off, int ver, char *name, int remount)
+{
+ if (sb->s_qcop->quota_on) {
+ return sb->s_qcop->quota_on(sb, off, ver, name
+#ifdef HAVE_QUOTA_ON_5ARGS
+ , remount
+#endif
+ );
+ }
+ else
+ return -ENOSYS;
+}
+
+static inline int ll_quota_off(struct super_block *sb, int off, int remount)
+{
+ if (sb->s_qcop->quota_off) {
+ return sb->s_qcop->quota_off(sb, off
+#ifdef HAVE_QUOTA_OFF_3ARGS
+ , remount
+#endif
+ );
+ }
+ else
+ return -ENOSYS;
+}
+
+
#ifdef HAVE_VFS_RENAME_MUTEX
#define VFS_RENAME_LOCK(inode) mutex_lock(&((inode)->i_sb->s_vfs_rename_mutex))
#define VFS_RENAME_UNLOCK(inode) mutex_unlock(&((inode)->i_sb->s_vfs_rename_mutex))
# include <string.h>
# include <sys/types.h>
#else
-# include <asm/semaphore.h>
# include <linux/rwsem.h>
# include <linux/sched.h>
# include <linux/signal.h>
BUG_ON(!PageLocked(page));
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#ifdef HAVE_RW_TREE_LOCK
write_lock_irq(&mapping->tree_lock);
#else
spin_lock_irq(&mapping->tree_lock);
__dec_zone_page_state(page, NR_FILE_PAGES);
#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#ifdef HAVE_RW_TREE_LOCK
write_unlock_irq(&mapping->tree_lock);
#else
spin_unlock_irq(&mapping->tree_lock);
#define LPROCFS_EXIT() do { \
up_read(&_lprocfs_lock); \
} while(0)
-#define LPROCFS_ENTRY_AND_CHECK(dp) do { \
- typecheck(struct proc_dir_entry *, dp); \
- LPROCFS_ENTRY(); \
- if ((dp)->deleted) { \
- LPROCFS_EXIT(); \
- return -ENODEV; \
- } \
-} while(0)
+
+#ifdef HAVE_PROCFS_DELETED
+static inline
+int LPROCFS_ENTRY_AND_CHECK(struct proc_dir_entry *dp)
+{
+ LPROCFS_ENTRY();
+ if ((dp)->deleted) {
+ LPROCFS_EXIT();
+ return -ENODEV;
+ }
+ return 0;
+}
+#else
+static inline
+int LPROCFS_ENTRY_AND_CHECK(struct proc_dir_entry *dp)
+{
+ LPROCFS_ENTRY();
+ return 0;
+}
+#endif
+
#define LPROCFS_WRITE_ENTRY() do { \
down_write(&_lprocfs_lock); \
} while(0)
up_write(&_lprocfs_lock); \
} while(0)
+
/* You must use these macros when you want to refer to
* the import in a client obd_device for a lprocfs entry */
#define LPROCFS_CLIMP_CHECK(obd) do { \
};
#ifdef NEED_QUOTA_DEFS
-#ifndef QUOTABLOCK_BITS
-#define QUOTABLOCK_BITS 10
-#endif
-
-#ifndef QUOTABLOCK_SIZE
-#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
-#endif
-
-#ifndef toqb
-#define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
-#endif
-
#ifndef QIF_BLIMITS
#define QIF_BLIMITS 1
#define QIF_SPACE 2
#define NR_DQHASH 45
#endif
+#ifndef QUOTABLOCK_BITS
+#define QUOTABLOCK_BITS 10
+#endif
+
+#ifndef QUOTABLOCK_SIZE
+#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
+#endif
+
+#ifndef toqb
+#define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
+#endif
+
#ifdef HAVE_QUOTA_SUPPORT
+#ifndef MAX_IQ_TIME
+#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */
+#endif
+
+#ifndef MAX_DQ_TIME
+#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */
+#endif
+
#ifdef __KERNEL__
#ifdef LPROCFS
struct list_head *list);
int lustre_quota_convert(struct lustre_quota_info *lqi, int type);
-#define LL_DQUOT_OFF(sb) DQUOT_OFF(sb)
-
typedef int (*dqacq_handler_t) (struct obd_device * obd, struct qunit_data * qd,
int opc);
+/*
+#ifdef HAVE_VFS_DQ_OFF
+#define LL_DQUOT_OFF(sb, remount) vfs_dq_off(sb, remount)
+#else
+#define LL_DQUOT_OFF(sb, remount) DQUOT_OFF(sb)
+#endif
+*/
+
+#define LL_DQUOT_OFF(sb) DQUOT_OFF(sb)
+
+
/* user quota is turned on on filter */
#define LQC_USRQUOTA_FLAG (1 << 0)
/* group quota is turned on on filter */
#else
-#define LL_DQUOT_OFF(sb) do {} while(0)
+#define LL_DQUOT_OFF(sb, remount) do {} while(0)
struct lustre_quota_info {
};
--- /dev/null
+lnxmaj="2.6.27"
+lnxmin=".23"
+# when we fix up this lnxmaj/lnxmin/lnxrel business...
+#lnxrel="0.37_f594963d"
+# and note that this means we get rid of the EXTRA_VERSION_DELIMITER crap!!
+lnxrel="23-0.1"
+
+# this is the delimeter that goes between $lnxmaj and $lnxrel
+# defaults to "-"
+EXTRA_VERSION_DELIMITER="."
+
+# this is the delimeter that goes before the "smp" at the end of the version
+# defaults to empty
+TARGET_DELIMITER="-"
+
+KERNEL_SRPM=kernel-source-$lnxmaj.$lnxrel.1.src.rpm
+SERIES=2.6-sles11.series
+VERSION=$lnxmaj
+EXTRA_VERSION="${lnxrel}_lustre.@VERSION@"
+LUSTRE_VERSION=@VERSION@
+
+#OFED_VERSION=1.4.1-rc4
+
+BASE_ARCHS="i686 ppc x86_64 ia64 ppc64"
+BIGMEM_ARCHS=""
+BOOT_ARCHS=""
+JENSEN_ARCHS=""
+DEFAULT_ARCHS="i686 x86_64 ia64 ppc64"
+BIGSMP_ARCHS=""
+PSERIES64_ARCHS="ppc"
+UP_ARCHS=""
+SRC_ARCHS=""
+#RPMSMPTYPE="smp"
+
+for cc in gcc ; do
+ if which $cc >/dev/null 2>/dev/null ; then
+ export CC=$cc
+ break
+ fi
+done
2.6-rhel5 OEL5: 2.6.18-128.7.1.el5
2.6.18-vanilla kernel.org: 2.6.18.8
2.6.22-vanilla kernel.org: 2.6.22.14
+2.6-sles11 SLES11: 2.6.27.23-0.1
CLIENT SUPPORT FOR UNPATCHED KERNELS:
- kernel.org 2.6.16-2.6.22
+ kernel.org 2.6.16-2.6.27
RHEL4: 2.6.9-42.0.8EL
NB - The patches in the 2.6-suse series should already be in the SLES9 SP1
size_t size = io->u.ci_rw.crw_count;
cio->cui_iov_olen = 0;
- if (cl_io_is_sendfile(io) || size == cio->cui_tot_count)
+ if (!cl_is_normalio(env, io) || size == cio->cui_tot_count)
return;
if (cio->cui_tot_nrsegs == 0)
CLOBINVRNT(env, obj, ccc_object_invariant(obj));
- if (!cl_io_is_sendfile(io) && io->ci_continue) {
+ if (cl_is_normalio(env, io) && io->ci_continue) {
/* update the iov */
LASSERT(cio->cui_tot_nrsegs >= cio->cui_nrsegs);
LASSERT(cio->cui_tot_count >= nob);
/**
* build inode number from passed @fid */
-ino_t cl_fid_build_ino(struct lu_fid *fid)
+ino_t cl_fid_build_ino(const struct lu_fid *fid)
{
ino_t ino;
ENTRY;
/**
* build inode generation from passed @fid. If our FID overflows the 32-bit
* inode number then return a non-zero generation to distinguish them. */
-__u32 cl_fid_build_gen(struct lu_fid *fid)
+__u32 cl_fid_build_gen(const struct lu_fid *fid)
{
__u32 gen;
ENTRY;
OBD_FREE_PTR(page);
}
+
static int llu_queue_pio(const struct lu_env *env, struct cl_io *io,
struct llu_io_group *group,
char *buf, size_t count, loff_t pos)
OBD_FREE_PTR(group);
}
+/**
+ * True, if \a io is a normal io, False for sendfile() / splice_{read|write}
+ */
+int cl_is_normalio(const struct lu_env *env, const struct cl_io *io)
+{
+ return 1;
+}
+
static int slp_io_start(const struct lu_env *env, const struct cl_io_slice *ios)
{
struct ccc_io *cio = cl2ccc_io(env, ios);
}
static ssize_t ll_file_io_generic(const struct lu_env *env,
- struct ccc_io_args *args, struct file *file,
+ struct vvp_io_args *args, struct file *file,
enum cl_io_type iot, loff_t *ppos, size_t count)
{
struct cl_io *io;
io = &ccc_env_info(env)->cti_io;
ll_io_init(io, file, iot == CIT_WRITE);
- if (iot == CIT_READ)
- io->u.ci_rd.rd_is_sendfile = args->cia_is_sendfile;
-
if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) {
struct vvp_io *vio = vvp_env_io(env);
struct ccc_io *cio = ccc_env_io(env);
- if (cl_io_is_sendfile(io)) {
- vio->u.read.cui_actor = args->cia_actor;
- vio->u.read.cui_target = args->cia_target;
- } else {
- cio->cui_iov = args->cia_iov;
- cio->cui_nrsegs = args->cia_nrsegs;
+
+ vio->cui_io_subtype = args->via_io_subtype;
+
+ switch (vio->cui_io_subtype) {
+ case IO_NORMAL:
+ cio->cui_iov = args->u.normal.via_iov;
+ cio->cui_nrsegs = args->u.normal.via_nrsegs;
#ifndef HAVE_FILE_WRITEV
- cio->cui_iocb = args->cia_iocb;
+ cio->cui_iocb = args->u.normal.via_iocb;
#endif
+ break;
+ case IO_SENDFILE:
+ vio->u.sendfile.cui_actor = args->u.sendfile.via_actor;
+ vio->u.sendfile.cui_target = args->u.sendfile.via_target;
+ break;
+ case IO_SPLICE:
+ vio->u.splice.cui_pipe = args->u.splice.via_pipe;
+ vio->u.splice.cui_flags = args->u.splice.via_flags;
+ break;
+ default:
+ CERROR("Unknow IO type - %u\n", vio->cui_io_subtype);
+ LBUG();
}
cio->cui_fd = LUSTRE_FPRIVATE(file);
result = cl_io_loop(env, io);
- } else
+ } else {
/* cl_io_rw_init() handled IO */
result = io->ci_result;
+ }
+
if (io->ci_nob > 0) {
result = io->ci_nob;
*ppos = io->u.ci_wr.wr.crw_pos;
unsigned long nr_segs, loff_t *ppos)
{
struct lu_env *env;
- struct ccc_io_args *args;
+ struct vvp_io_args *args;
size_t count;
ssize_t result;
int refcheck;
if (IS_ERR(env))
RETURN(PTR_ERR(env));
- args = &vvp_env_info(env)->vti_args;
- args->cia_is_sendfile = 0;
- args->cia_iov = (struct iovec *)iov;
- args->cia_nrsegs = nr_segs;
+ args = vvp_env_args(env, IO_NORMAL);
+ args->u.normal.via_iov = (struct iovec *)iov;
+ args->u.normal.via_nrsegs = nr_segs;
+
result = ll_file_io_generic(env, args, file, CIT_READ, ppos, count);
cl_env_put(env, &refcheck);
RETURN(result);
unsigned long nr_segs, loff_t pos)
{
struct lu_env *env;
- struct ccc_io_args *args;
+ struct vvp_io_args *args;
size_t count;
ssize_t result;
int refcheck;
if (IS_ERR(env))
RETURN(PTR_ERR(env));
- args = &vvp_env_info(env)->vti_args;
- args->cia_is_sendfile = 0;
- args->cia_iov = (struct iovec *)iov;
- args->cia_nrsegs = nr_segs;
- args->cia_iocb = iocb;
+ args = vvp_env_args(env, IO_NORMAL);
+ args->u.normal.via_iov = (struct iovec *)iov;
+ args->u.normal.via_nrsegs = nr_segs;
+ args->u.normal.via_iocb = iocb;
+
result = ll_file_io_generic(env, args, iocb->ki_filp, CIT_READ,
&iocb->ki_pos, count);
cl_env_put(env, &refcheck);
unsigned long nr_segs, loff_t *ppos)
{
struct lu_env *env;
- struct ccc_io_args *args;
+ struct vvp_io_args *args;
size_t count;
ssize_t result;
int refcheck;
if (IS_ERR(env))
RETURN(PTR_ERR(env));
- args = &vvp_env_info(env)->vti_args;
- args->cia_iov = (struct iovec *)iov;
- args->cia_nrsegs = nr_segs;
+ args = vvp_env_args(env, IO_NORMAL);
+ args->u.normal.via_iov = (struct iovec *)iov;
+ args->u.normal.via_nrsegs = nr_segs;
+
result = ll_file_io_generic(env, args, file, CIT_WRITE, ppos, count);
cl_env_put(env, &refcheck);
RETURN(result);
unsigned long nr_segs, loff_t pos)
{
struct lu_env *env;
- struct ccc_io_args *args;
+ struct vvp_io_args *args;
size_t count;
ssize_t result;
int refcheck;
if (IS_ERR(env))
RETURN(PTR_ERR(env));
- args = &vvp_env_info(env)->vti_args;
- args->cia_iov = (struct iovec *)iov;
- args->cia_nrsegs = nr_segs;
- args->cia_iocb = iocb;
+ args = vvp_env_args(env, IO_NORMAL);
+ args->u.normal.via_iov = (struct iovec *)iov;
+ args->u.normal.via_nrsegs = nr_segs;
+ args->u.normal.via_iocb = iocb;
+
result = ll_file_io_generic(env, args, iocb->ki_filp, CIT_WRITE,
&iocb->ki_pos, count);
cl_env_put(env, &refcheck);
#endif
+#ifdef HAVE_KERNEL_SENDFILE
/*
* Send file content (through pagecache) somewhere with helper
*/
read_actor_t actor, void *target)
{
struct lu_env *env;
- struct ccc_io_args *args;
+ struct vvp_io_args *args;
+ ssize_t result;
+ int refcheck;
+ ENTRY;
+
+ env = cl_env_get(&refcheck);
+ if (IS_ERR(env))
+ RETURN(PTR_ERR(env));
+
+ args = vvp_env_args(env, IO_SENDFILE);
+ args->u.sendfile.via_target = target;
+ args->u.sendfile.via_actor = actor;
+
+ result = ll_file_io_generic(env, args, in_file, CIT_READ, ppos, count);
+ cl_env_put(env, &refcheck);
+ RETURN(result);
+}
+#endif
+
+#ifdef HAVE_KERNEL_SPLICE_READ
+/*
+ * Send file content (through pagecache) somewhere with helper
+ */
+static ssize_t ll_file_splice_read(struct file *in_file, loff_t *ppos,
+ struct pipe_inode_info *pipe, size_t count,
+ unsigned int flags)
+{
+ struct lu_env *env;
+ struct vvp_io_args *args;
ssize_t result;
int refcheck;
ENTRY;
if (IS_ERR(env))
RETURN(PTR_ERR(env));
- args = &vvp_env_info(env)->vti_args;
- args->cia_is_sendfile = 1;
- args->cia_target = target;
- args->cia_actor = actor;
+ args = vvp_env_args(env, IO_SPLICE);
+ args->u.splice.via_pipe = pipe;
+ args->u.splice.via_flags = flags;
+
result = ll_file_io_generic(env, args, in_file, CIT_READ, ppos, count);
cl_env_put(env, &refcheck);
RETURN(result);
}
+#endif
static int ll_lov_recreate_obj(struct inode *inode, struct file *file,
unsigned long arg)
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
+#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
{
int rc = 0;
ENTRY;
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
+#ifdef HAVE_KERNEL_SENDFILE
.sendfile = ll_file_sendfile,
+#endif
+#ifdef HAVE_KERNEL_SPLICE_READ
+ .splice_read = ll_file_splice_read,
+#endif
.fsync = ll_fsync,
};
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
+#ifdef HAVE_KERNEL_SENDFILE
.sendfile = ll_file_sendfile,
+#endif
+#ifdef HAVE_KERNEL_SPLICE_READ
+ .splice_read = ll_file_splice_read,
+#endif
.fsync = ll_fsync,
#ifdef HAVE_F_OP_FLOCK
.flock = ll_file_flock,
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
+#ifdef HAVE_KERNEL_SENDFILE
.sendfile = ll_file_sendfile,
+#endif
+#ifdef HAVE_KERNEL_SPLICE_READ
+ .splice_read = ll_file_splice_read,
+#endif
.fsync = ll_fsync,
#ifdef HAVE_F_OP_FLOCK
.flock = ll_file_noflock,
struct lookup_intent *it, struct kstat *stat);
int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat);
struct ll_file_data *ll_file_data_get(void);
+#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
int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file,
int flags, struct lov_user_md *lum,
int lum_size);
/* llite/llite_nfs.c */
extern struct export_operations lustre_export_operations;
__u32 get_uuid2int(const char *name, int len);
-struct dentry *ll_fh_to_dentry(struct super_block *sb, __u32 *data, int len,
- int fhtype, int parent);
-int ll_dentry_to_fh(struct dentry *, __u32 *datap, int *lenp, int need_parent);
/* llite/special.c */
extern struct inode_operations ll_special_inode_operations;
atomic_t lcq_stop;
};
-struct vvp_thread_info {
- struct ost_lvb vti_lvb;
- struct cl_2queue vti_queue;
- struct iovec vti_local_iov;
- struct ccc_io_args vti_args;
- struct ra_io_arg vti_ria;
- struct kiocb vti_kiocb;
-};
-
struct ccc_object *cl_inode2ccc(struct inode *inode);
-static inline struct vvp_thread_info *vvp_env_info(const struct lu_env *env)
-{
- extern struct lu_context_key vvp_key;
- struct vvp_thread_info *info;
-
- info = lu_context_key_get(&env->le_ctx, &vvp_key);
- LASSERT(info != NULL);
- return info;
-}
void vvp_write_pending (struct ccc_object *club, struct ccc_page *page);
void vvp_write_complete(struct ccc_object *club, struct ccc_page *page);
+/* specific achitecture can implement only part of this list */
+enum vvp_io_subtype {
+ /** normal IO */
+ IO_NORMAL,
+ /** io called from .sendfile */
+ IO_SENDFILE,
+ /** io started from splice_{read|write} */
+ IO_SPLICE
+};
+
+/* IO subtypes */
struct vvp_io {
+ /** io subtype */
+ enum vvp_io_subtype cui_io_subtype;
+
union {
struct {
read_actor_t cui_actor;
void *cui_target;
- } read;
+ } sendfile;
+ struct {
+ struct pipe_inode_info *cui_pipe;
+ unsigned int cui_flags;
+ } splice;
struct vvp_fault_io {
/**
* Inode modification time that is checked across DLM
time_t ft_mtime;
struct vm_area_struct *ft_vma;
/**
- * Virtual address at which fault occurred.
+ * locked page returned from vvp_io
*/
- unsigned long ft_address;
- /**
- * Fault type, as to be supplied to filemap_nopage().
- */
- int *ft_type;
+ cfs_page_t *ft_vmpage;
+#ifndef HAVE_VM_OP_FAULT
+ struct vm_nopage_api {
+ /**
+ * Virtual address at which fault occurred.
+ */
+ unsigned long ft_address;
+ /**
+ * Fault type, as to be supplied to
+ * filemap_nopage().
+ */
+ int *ft_type;
+ } nopage;
+#else
+ struct vm_fault_api {
+ /**
+ * kernel fault info
+ */
+ struct vm_fault *ft_vmf;
+ /**
+ * fault API used bitflags for return code.
+ */
+ unsigned int ft_flags;
+ } fault;
+#endif
} fault;
} u;
/**
struct cl_page *cui_partpage;
};
+/**
+ * IO arguments for various VFS I/O interfaces.
+ */
+struct vvp_io_args {
+ /** normal/sendfile/splice */
+ enum vvp_io_subtype via_io_subtype;
+
+ union {
+ struct {
+#ifndef HAVE_FILE_WRITEV
+ struct kiocb *via_iocb;
+#endif
+ struct iovec *via_iov;
+ unsigned long via_nrsegs;
+ } normal;
+ struct {
+ read_actor_t via_actor;
+ void *via_target;
+ } sendfile;
+ struct {
+ struct pipe_inode_info *via_pipe;
+ unsigned int via_flags;
+ } splice;
+ } u;
+};
+
+struct vvp_thread_info {
+ struct ost_lvb vti_lvb;
+ struct cl_2queue vti_queue;
+ struct iovec vti_local_iov;
+ struct vvp_io_args vti_args;
+ struct ra_io_arg vti_ria;
+ struct kiocb vti_kiocb;
+};
+
+static inline struct vvp_thread_info *vvp_env_info(const struct lu_env *env)
+{
+ extern struct lu_context_key vvp_key;
+ struct vvp_thread_info *info;
+
+ info = lu_context_key_get(&env->le_ctx, &vvp_key);
+ LASSERT(info != NULL);
+ return info;
+}
+
+static inline struct vvp_io_args *vvp_env_args(const struct lu_env *env,
+ enum vvp_io_subtype type)
+{
+ struct vvp_io_args *ret = &vvp_env_info(env)->vti_args;
+
+ ret->via_io_subtype = type;
+
+ return ret;
+}
+
struct vvp_session {
struct vvp_io vs_ios;
};
struct page *ll_nopage(struct vm_area_struct *vma, unsigned long address,
int *type);
+static struct vm_operations_struct ll_file_vm_ops;
+
void policy_from_vma(ldlm_policy_data_t *policy,
struct vm_area_struct *vma, unsigned long addr,
size_t count)
spin_lock(&mm->page_table_lock);
for(vma = find_vma(mm, addr);
vma != NULL && vma->vm_start < (addr + count); vma = vma->vm_next) {
- if (vma->vm_ops && vma->vm_ops->nopage == ll_nopage &&
+ if (vma->vm_ops && vma->vm_ops == &ll_file_vm_ops &&
vma->vm_flags & VM_SHARED) {
ret = vma;
break;
}
/**
+ * API independent part for page fault initialization.
+ * \param vma - virtual memory area addressed to page fault
+ * \param env - corespondent lu_env to processing
+ * \param nest - nested level
+ * \param index - page index corespondent to fault.
+ * \parm ra_flags - vma readahead flags.
+ *
+ * \return allocated and initialized env for fault operation.
+ * \retval EINVAL if env can't allocated
+ * \return other error codes from cl_io_init.
+ */
+int ll_fault_io_init(struct vm_area_struct *vma, struct lu_env **env_ret,
+ struct cl_env_nest *nest, pgoff_t index, unsigned long *ra_flags)
+{
+ struct file *file = vma->vm_file;
+ struct inode *inode = file->f_dentry->d_inode;
+ const unsigned long writable = VM_SHARED|VM_WRITE;
+ struct cl_io *io;
+ struct cl_fault_io *fio;
+ struct lu_env *env;
+ ENTRY;
+
+ if (ll_file_nolock(file))
+ RETURN(-EOPNOTSUPP);
+
+ /*
+ * page fault can be called when lustre IO is
+ * already active for the current thread, e.g., when doing read/write
+ * against user level buffer mapped from Lustre buffer. To avoid
+ * stomping on existing context, optionally force an allocation of a new
+ * one.
+ */
+ env = cl_env_nested_get(nest);
+ if (IS_ERR(env)) {
+ *env_ret = NULL;
+ RETURN(-EINVAL);
+ }
+
+ *env_ret = env;
+
+ io = &ccc_env_info(env)->cti_io;
+ io->ci_obj = ll_i2info(inode)->lli_clob;
+ LASSERT(io->ci_obj != NULL);
+
+ fio = &io->u.ci_fault;
+ fio->ft_index = vma->vm_pgoff + index;
+ fio->ft_writable = (vma->vm_flags&writable) == writable;
+ fio->ft_executable = vma->vm_flags&VM_EXEC;
+
+ /*
+ * disable VM_SEQ_READ and use VM_RAND_READ to make sure that
+ * the kernel will not read other pages not covered by ldlm in
+ * filemap_nopage. we do our readahead in ll_readpage.
+ */
+ *ra_flags = vma->vm_flags & (VM_RAND_READ|VM_SEQ_READ);
+ vma->vm_flags &= ~VM_SEQ_READ;
+ vma->vm_flags |= VM_RAND_READ;
+
+ CDEBUG(D_INFO, "vm_flags: %lx (%lu %i %i)\n", vma->vm_flags,
+ fio->ft_index, fio->ft_writable, fio->ft_executable);
+
+ if (cl_io_init(env, io, CIT_FAULT, io->ci_obj) == 0) {
+ struct ccc_io *cio = ccc_env_io(env);
+ struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
+
+ LASSERT(cio->cui_cl.cis_io == io);
+
+ /* mmap lock must be MANDATORY
+ * it has to cache pages. */
+ io->ci_lockreq = CILR_MANDATORY;
+
+ cio->cui_fd = fd;
+ }
+
+ return io->ci_result;
+}
+
+#ifndef HAVE_VM_OP_FAULT
+/**
* Lustre implementation of a vm_operations_struct::nopage() method, called by
* VM to server page fault (both in kernel and user space).
*
* \param address - address when hit fault
* \param type - of fault
*
- * XXX newer 2.6 kernels provide vm_operations_struct::fault() method with
- * slightly different semantics instead.
- *
- * \return allocated and filled page for address
+ * \return allocated and filled _unlocked_ page for address
* \retval NOPAGE_SIGBUS if page not exist on this address
* \retval NOPAGE_OOM not have memory for allocate new page
*/
struct page *ll_nopage(struct vm_area_struct *vma, unsigned long address,
int *type)
{
- struct file *file = vma->vm_file;
- struct inode *inode = file->f_dentry->d_inode;
- struct lu_env *env;
- struct cl_io *io;
- struct page *page = NULL;
- struct cl_env_nest nest;
- int result;
-
+ struct lu_env *env;
+ struct cl_env_nest nest;
+ struct cl_io *io;
+ struct page *page = NOPAGE_SIGBUS;
+ struct vvp_io *vio = NULL;
+ unsigned long ra_flags;
+ pgoff_t pg_offset;
+ int result;
ENTRY;
- if (ll_file_nolock(file))
- RETURN(ERR_PTR(-EOPNOTSUPP));
+ pg_offset = (address - vma->vm_start) >> PAGE_SHIFT;
+ result = ll_fault_io_init(vma, &env, &nest, pg_offset, &ra_flags);
+ if (env == NULL)
+ return NOPAGE_SIGBUS;
- /*
- * vm_operations_struct::nopage() can be called when lustre IO is
- * already active for the current thread, e.g., when doing read/write
- * against user level buffer mapped from Lustre buffer. To avoid
- * stomping on existing context, optionally force an allocation of a new
- * one.
- */
- env = cl_env_nested_get(&nest);
- if (!IS_ERR(env)) {
- pgoff_t pg_offset;
- const unsigned long writable = VM_SHARED|VM_WRITE;
- unsigned long ra_flags;
- struct cl_fault_io *fio;
-
- io = &ccc_env_info(env)->cti_io;
- memset(io, 0, sizeof(*io));
- io->ci_obj = ll_i2info(inode)->lli_clob;
- LASSERT(io->ci_obj != NULL);
-
- fio = &io->u.ci_fault;
- pg_offset = (address - vma->vm_start) >> PAGE_SHIFT;
- fio->ft_index = pg_offset + vma->vm_pgoff;
- fio->ft_writable = (vma->vm_flags&writable) == writable;
- fio->ft_executable = vma->vm_flags&VM_EXEC;
-
- /*
- * disable VM_SEQ_READ and use VM_RAND_READ to make sure that
- * the kernel will not read other pages not covered by ldlm in
- * filemap_nopage. we do our readahead in ll_readpage.
- */
- ra_flags = vma->vm_flags & (VM_RAND_READ|VM_SEQ_READ);
- vma->vm_flags &= ~VM_SEQ_READ;
- vma->vm_flags |= VM_RAND_READ;
-
- CDEBUG(D_INFO, "vm_flags: %lx (%lu %i %i)\n", vma->vm_flags,
- fio->ft_index, fio->ft_writable, fio->ft_executable);
-
- if (cl_io_init(env, io, CIT_FAULT, io->ci_obj) == 0) {
- struct vvp_io *vio = vvp_env_io(env);
- struct ccc_io *cio = ccc_env_io(env);
- struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
-
- LASSERT(cio->cui_cl.cis_io == io);
-
- /* mmap lock must be MANDATORY. */
- io->ci_lockreq = CILR_MANDATORY;
- vio->u.fault.ft_vma = vma;
- vio->u.fault.ft_address = address;
- vio->u.fault.ft_type = type;
- cio->cui_fd = fd;
-
- result = cl_io_loop(env, io);
- if (result == 0) {
- LASSERT(fio->ft_page != NULL);
- page = cl_page_vmpage(env, fio->ft_page);
- } else if (result == -EFAULT) {
- page = NOPAGE_SIGBUS;
- } else if (result == -ENOMEM) {
- page = NOPAGE_OOM;
- }
- } else
- result = io->ci_result;
-
- vma->vm_flags &= ~VM_RAND_READ;
- vma->vm_flags |= ra_flags;
-
- cl_io_fini(env, io);
- cl_env_nested_put(&nest, env);
+ io = &ccc_env_info(env)->cti_io;
+ if (result < 0)
+ goto out_err;
+
+ vio = vvp_env_io(env);
+
+ vio->u.fault.ft_vma = vma;
+ vio->u.fault.nopage.ft_address = address;
+ vio->u.fault.nopage.ft_type = type;
+
+ result = cl_io_loop(env, io);
+
+out_err:
+ if (result == 0) {
+ LASSERT(io->u.ci_fault.ft_page != NULL);
+ page = vio->u.fault.ft_vmpage;
+ } else {
+ if (result == -ENOMEM)
+ page = NOPAGE_OOM;
}
+
+ vma->vm_flags &= ~VM_RAND_READ;
+ vma->vm_flags |= ra_flags;
+
+ cl_io_fini(env, io);
+ cl_env_nested_put(&nest, env);
+
RETURN(page);
}
+#else
+/**
+ * Lustre implementation of a vm_operations_struct::fault() method, called by
+ * VM to server page fault (both in kernel and user space).
+ *
+ * \param vma - is virtiual area struct related to page fault
+ * \param vmf - structure which describe type and address where hit fault
+ *
+ * \return allocated and filled _locked_ page for address
+ * \retval VM_FAULT_ERROR on general error
+ * \retval NOPAGE_OOM not have memory for allocate new page
+ */
+int ll_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ struct lu_env *env;
+ struct cl_io *io;
+ struct vvp_io *vio = NULL;
+ unsigned long ra_flags;
+ struct cl_env_nest nest;
+ int result;
+ int fault_ret = 0;
+ ENTRY;
+
+ result = ll_fault_io_init(vma, &env, &nest, vmf->pgoff, &ra_flags);
+ if (env == NULL)
+ RETURN(VM_FAULT_ERROR);
+
+ io = &ccc_env_info(env)->cti_io;
+ if (result < 0)
+ goto out_err;
+
+ vio = vvp_env_io(env);
+
+ vio->u.fault.ft_vma = vma;
+ vio->u.fault.fault.ft_vmf = vmf;
+
+ result = cl_io_loop(env, io);
+ fault_ret = vio->u.fault.fault.ft_flags;
+
+out_err:
+ if (result != 0)
+ fault_ret |= VM_FAULT_ERROR;
+
+ vma->vm_flags |= ra_flags;
+
+ cl_io_fini(env, io);
+ cl_env_nested_put(&nest, env);
+
+ RETURN(fault_ret);
+}
+
+#endif
/**
* To avoid cancel the locks covering mmapped region for lock cache pressure,
EXIT;
}
+#ifndef HAVE_VM_OP_FAULT
#ifndef HAVE_FILEMAP_POPULATE
static int (*filemap_populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int nonblock);
#endif
rc = filemap_populate(area, address, len, prot, pgoff, 1);
RETURN(rc);
}
+#endif
/* return the user space pointer that maps to a file offset via a vma */
static inline unsigned long file_to_user(struct vm_area_struct *vma, __u64 byte)
}
static struct vm_operations_struct ll_file_vm_ops = {
+#ifndef HAVE_VM_OP_FAULT
.nopage = ll_nopage,
+ .populate = ll_populate,
+
+#else
+ .fault = ll_fault,
+#endif
.open = ll_vm_open,
.close = ll_vm_close,
- .populate = ll_populate,
};
int ll_file_mmap(struct file *file, struct vm_area_struct * vma)
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_MAP, 1);
rc = generic_file_mmap(file, vma);
if (rc == 0) {
-#if !defined(HAVE_FILEMAP_POPULATE)
+#if !defined(HAVE_FILEMAP_POPULATE) && !defined(HAVE_VM_OP_FAULT)
if (!filemap_populate)
filemap_populate = vma->vm_ops->populate;
#endif
}
static struct inode *search_inode_for_lustre(struct super_block *sb,
- struct lu_fid *fid,
- int mode)
+ const struct lu_fid *fid)
{
struct ll_sb_info *sbi = ll_s2sbi(sb);
struct ptlrpc_request *req = NULL;
if (inode)
RETURN(inode);
- if (S_ISREG(mode)) {
- rc = ll_get_max_mdsize(sbi, &eadatalen);
- if (rc)
- RETURN(ERR_PTR(rc));
- valid |= OBD_MD_FLEASIZE;
- }
+ rc = ll_get_max_mdsize(sbi, &eadatalen);
+ if (rc)
+ RETURN(ERR_PTR(rc));
+
+ valid |= OBD_MD_FLEASIZE;
+ /* mds_fid2dentry ignores f_type */
rc = md_getattr(sbi->ll_md_exp, fid, NULL, valid, eadatalen, &req);
if (rc) {
CERROR("can't get object attrs, fid "DFID", rc %d\n",
}
static struct dentry *ll_iget_for_nfs(struct super_block *sb,
- struct lu_fid *fid,
- umode_t mode)
+ const struct lu_fid *fid)
{
struct inode *inode;
struct dentry *result;
if (!fid_is_sane(fid))
RETURN(ERR_PTR(-ESTALE));
- inode = search_inode_for_lustre(sb, fid, mode);
+ inode = search_inode_for_lustre(sb, fid);
if (IS_ERR(inode))
RETURN(ERR_PTR(PTR_ERR(inode)));
RETURN(result);
}
+#define LUSTRE_NFS_FID 0x97
+
+struct lustre_nfs_fid {
+ struct lu_fid lnf_child;
+ struct lu_fid lnf_parent;
+};
+
+/**
+ * \a connectable - is nfsd will connect himself or this should be done
+ * at lustre
+ *
+ * The return value is file handle type:
+ * 1 -- contains child file handle;
+ * 2 -- contains child file handle and parent file handle;
+ * 255 -- error.
+ */
+static int ll_encode_fh(struct dentry *de, __u32 *fh, int *plen,
+ int connectable)
+{
+ struct inode *inode = de->d_inode;
+ struct inode *parent = de->d_parent->d_inode;
+ struct lustre_nfs_fid *nfs_fid = (void *)fh;
+ ENTRY;
+
+ CDEBUG(D_INFO, "encoding for (%lu,"DFID") maxlen=%d minlen=%d\n",
+ inode->i_ino, PFID(ll_inode2fid(inode)), *plen,
+ (int)sizeof(struct lustre_nfs_fid));
+
+ if (*plen < sizeof(struct lustre_nfs_fid)/4)
+ RETURN(255);
+
+ nfs_fid->lnf_child = *ll_inode2fid(inode);
+ nfs_fid->lnf_parent = *ll_inode2fid(parent);
+ *plen = sizeof(struct lustre_nfs_fid)/4;
+
+ RETURN(LUSTRE_NFS_FID);
+}
+
+#ifdef HAVE_FH_TO_DENTRY
+static struct dentry *ll_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ struct lustre_nfs_fid *nfs_fid = (struct lustre_nfs_fid *)fid;
+
+ if (fh_type != LUSTRE_NFS_FID)
+ RETURN(ERR_PTR(-EPROTO));
+
+ RETURN(ll_iget_for_nfs(sb, &nfs_fid->lnf_child));
+}
+
+static struct dentry *ll_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ struct lustre_nfs_fid *nfs_fid = (struct lustre_nfs_fid *)fid;
+
+ if (fh_type != LUSTRE_NFS_FID)
+ RETURN(ERR_PTR(-EPROTO));
+
+ RETURN(ll_iget_for_nfs(sb, &nfs_fid->lnf_parent));
+}
+
+#else
+
/*
* This length is counted as amount of __u32,
- * It is composed of a fid and a mode
+ * It is composed of a fid and a mode
*/
-#define ONE_FH_LEN (sizeof(struct lu_fid)/4 + 1)
-
static struct dentry *ll_decode_fh(struct super_block *sb, __u32 *fh, int fh_len,
int fh_type,
int (*acceptable)(void *, struct dentry *),
void *context)
{
- struct lu_fid *parent = NULL;
- struct lu_fid *child;
+ struct lustre_nfs_fid *nfs_fid = (void *)fh;
struct dentry *entry;
ENTRY;
- CDEBUG(D_INFO, "decoding for "DFID" fh_len=%d fh_type=%d\n",
- PFID((struct lu_fid*)fh), fh_len, fh_type);
+ CDEBUG(D_INFO, "decoding for "DFID" fh_len=%d fh_type=%x\n",
+ PFID(&nfs_fid->lnf_child), fh_len, fh_type);
- if (fh_type != 1 && fh_type != 2)
- RETURN(ERR_PTR(-ESTALE));
- if (fh_len < ONE_FH_LEN * fh_type)
- RETURN(ERR_PTR(-ESTALE));
+ if (fh_type != LUSTRE_NFS_FID)
+ RETURN(ERR_PTR(-EPROTO));
- child = (struct lu_fid*)fh;
- if (fh_type == 2)
- parent = (struct lu_fid*)(fh + ONE_FH_LEN);
-
- entry = sb->s_export_op->find_exported_dentry(sb, child, parent,
+ entry = sb->s_export_op->find_exported_dentry(sb, &nfs_fid->lnf_child,
+ &nfs_fid->lnf_parent,
acceptable, context);
RETURN(entry);
}
-/* The return value is file handle type:
- * 1 -- contains child file handle;
- * 2 -- contains child file handle and parent file handle;
- * 255 -- error.
- */
-static int ll_encode_fh(struct dentry *de, __u32 *fh, int *plen, int connectable)
-{
- struct inode *inode = de->d_inode;
- struct lu_fid *fid = ll_inode2fid(inode);
- ENTRY;
-
- CDEBUG(D_INFO, "encoding for (%lu,"DFID") maxlen=%d minlen=%d\n",
- inode->i_ino, PFID(fid), *plen, (int)ONE_FH_LEN);
-
- if (*plen < ONE_FH_LEN)
- RETURN(255);
-
- memcpy((char*)fh, fid, sizeof(*fid));
- *(fh + ONE_FH_LEN - 1) = (__u32)(S_IFMT & inode->i_mode);
-
- if (de->d_parent && *plen >= ONE_FH_LEN * 2) {
- struct inode *parent = de->d_parent->d_inode;
- fh += ONE_FH_LEN;
- memcpy((char*)fh, &ll_i2info(parent)->lli_fid, sizeof(*fid));
- *(fh + ONE_FH_LEN - 1) = (__u32)(S_IFMT & parent->i_mode);
- *plen = ONE_FH_LEN * 2;
- RETURN(2);
- } else {
- *plen = ONE_FH_LEN;
- RETURN(1);
- }
-}
-
static struct dentry *ll_get_dentry(struct super_block *sb, void *data)
{
- struct lu_fid *fid;
+ struct lustre_nfs_fid *fid = data;
struct dentry *entry;
- __u32 mode;
ENTRY;
- fid = (struct lu_fid *)data;
- mode = *((__u32*)data + ONE_FH_LEN - 1);
-
- entry = ll_iget_for_nfs(sb, fid, mode);
+ entry = ll_iget_for_nfs(sb, &fid->lnf_child);
RETURN(entry);
}
+#endif
static struct dentry *ll_get_parent(struct dentry *dchild)
{
static char dotdot[] = "..";
int rc;
ENTRY;
-
+
LASSERT(dir && S_ISDIR(dir->i_mode));
-
+
sbi = ll_s2sbi(dir->i_sb);
-
+
CDEBUG(D_INFO, "getting parent for (%lu,"DFID")\n",
dir->i_ino, PFID(ll_inode2fid(dir)));
}
body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
LASSERT(body->valid & OBD_MD_FLID);
-
+
CDEBUG(D_INFO, "parent for "DFID" is "DFID"\n",
PFID(ll_inode2fid(dir)), PFID(&body->fid1));
- result = ll_iget_for_nfs(dir->i_sb, &body->fid1, S_IFDIR);
+ result = ll_iget_for_nfs(dir->i_sb, &body->fid1);
ptlrpc_req_finished(req);
RETURN(result);
-}
+}
struct export_operations lustre_export_operations = {
.get_parent = ll_get_parent,
- .get_dentry = ll_get_dentry,
.encode_fh = ll_encode_fh,
+#ifdef HAVE_FH_TO_DENTRY
+ .fh_to_dentry = ll_fh_to_dentry,
+ .fh_to_parent = ll_fh_to_parent,
+#else
+ .get_dentry = ll_get_dentry,
.decode_fh = ll_decode_fh,
+#endif
};
atomic_t lo_pending;
wait_queue_head_t lo_bh_wait;
- request_queue_t *lo_queue;
+ struct request_queue *lo_queue;
const struct lu_env *lo_env;
struct cl_io lo_io;
return count;
}
-static int loop_make_request(request_queue_t *q, struct bio *old_bio)
+static int loop_make_request(struct request_queue *q, struct bio *old_bio)
{
struct lloop_device *lo = q->queuedata;
int rw = bio_rw(old_bio);
loop_add_bio(lo, old_bio);
return 0;
err:
- bio_io_error(old_bio, old_bio->bi_size);
+ cfs_bio_io_error(old_bio, old_bio->bi_size);
return 0;
}
/*
* kick off io on the underlying address space
*/
-static void loop_unplug(request_queue_t *q)
+static void loop_unplug(struct request_queue *q)
{
struct lloop_device *lo = q->queuedata;
while (bio) {
struct bio *tmp = bio->bi_next;
bio->bi_next = NULL;
- bio_endio(bio, bio->bi_size, ret);
+ cfs_bio_endio(bio, bio->bi_size, ret);
bio = tmp;
}
}
out_mem4:
while (i--)
- blk_put_queue(loop_dev[i].lo_queue);
+ blk_cleanup_queue(loop_dev[i].lo_queue);
i = max_loop;
out_mem3:
while (i--)
ll_iocontrol_unregister(ll_iocontrol_magic);
for (i = 0; i < max_loop; i++) {
del_gendisk(disks[i]);
- blk_put_queue(loop_dev[i].lo_queue);
+ blk_cleanup_queue(loop_dev[i].lo_queue);
put_disk(disks[i]);
}
if (ll_unregister_blkdev(lloop_major, "lloop"))
ll_inode_size_unlock(inode, 0);
}
if (rc) {
- path_release(nd); /* Kernel assumes that ->follow_link()
+ cfs_path_put(nd); /* Kernel assumes that ->follow_link()
releases nameidata on error */
GOTO(out, rc);
}
static struct vvp_io *cl2vvp_io(const struct lu_env *env,
const struct cl_io_slice *slice);
+/**
+ * True, if \a io is a normal io, False for sendfile() / splice_{read|write}
+ */
+int cl_is_normalio(const struct lu_env *env, const struct cl_io *io)
+{
+ struct vvp_io *vio = vvp_env_io(env);
+
+ LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE);
+
+ return vio->cui_io_subtype == IO_NORMAL;
+}
+
/*****************************************************************************
*
* io operations.
LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE);
- if (cl_io_is_sendfile(io))
+ if (!cl_is_normalio(env, io))
RETURN(0);
for (seg = 0; seg < vio->cui_nrsegs; seg++) {
/* BUG: 5972 */
file_accessed(file);
- if (cl_io_is_sendfile(io)) {
+ switch (vio->cui_io_subtype) {
+ case IO_NORMAL:
+ result = lustre_generic_file_read(file, cio, &pos);
+ break;
+#ifdef HAVE_KERNEL_SENDFILE
+ case IO_SENDFILE:
result = generic_file_sendfile(file, &pos, cnt,
- vio->u.read.cui_actor, vio->u.read.cui_target);
- } else {
- result = lustre_generic_file_read(file, cio, &pos);
+ vio->u.sendfile.cui_actor,
+ vio->u.sendfile.cui_target);
+ break;
+#endif
+#ifdef HAVE_KERNEL_SPLICE_READ
+ case IO_SPLICE:
+ result = generic_file_splice_read(file, &pos,
+ vio->u.splice.cui_pipe, cnt,
+ vio->u.splice.cui_flags);
+ break;
+#endif
+ default:
+ CERROR("Wrong IO type %u\n", vio->cui_io_subtype);
+ LBUG();
}
out:
RETURN(result);
}
+#ifndef HAVE_VM_OP_FAULT
+static int vvp_io_kernel_fault(struct vvp_fault_io *cfio)
+{
+ cfs_page_t *vmpage;
+
+ vmpage = filemap_nopage(cfio->ft_vma, cfio->nopage.ft_address,
+ cfio->nopage.ft_type);
+
+ if (vmpage == NOPAGE_SIGBUS) {
+ CDEBUG(D_PAGE, "got addr %lu type %lx - SIGBUS\n",
+ cfio->nopage.ft_address,(long)cfio->nopage.ft_type);
+ return -EFAULT;
+ } else if (vmpage == NOPAGE_OOM) {
+ CDEBUG(D_PAGE, "got addr %lu type %lx - OOM\n",
+ cfio->nopage.ft_address, (long)cfio->nopage.ft_type);
+ return -ENOMEM;
+ }
+
+ LL_CDEBUG_PAGE(D_PAGE, vmpage, "got addr %lu type %lx\n",
+ cfio->nopage.ft_address, (long)cfio->nopage.ft_type);
+
+ cfio->ft_vmpage = vmpage;
+
+ return 0;
+}
+#else
+static int vvp_io_kernel_fault(struct vvp_fault_io *cfio)
+{
+ cfio->fault.ft_flags = filemap_fault(cfio->ft_vma, cfio->fault.ft_vmf);
+
+ if (cfio->fault.ft_vmf->page) {
+ LL_CDEBUG_PAGE(D_PAGE, cfio->fault.ft_vmf->page,
+ "got addr %p type NOPAGE\n",
+ cfio->fault.ft_vmf->virtual_address);
+ /*XXX workaround to bug in CLIO - he deadlocked with
+ lock cancel if page locked */
+ if (likely(cfio->fault.ft_flags & VM_FAULT_LOCKED)) {
+ unlock_page(cfio->fault.ft_vmf->page);
+ cfio->fault.ft_flags &= ~VM_FAULT_LOCKED;
+ }
+
+ cfio->ft_vmpage = cfio->fault.ft_vmf->page;
+ return 0;
+ }
+
+ if (unlikely (cfio->fault.ft_flags & VM_FAULT_ERROR)) {
+ CDEBUG(D_PAGE, "got addr %p - SIGBUS\n",
+ cfio->fault.ft_vmf->virtual_address);
+ return -EFAULT;
+ }
+
+ if (unlikely (cfio->fault.ft_flags & VM_FAULT_NOPAGE)) {
+ CDEBUG(D_PAGE, "got addr %p - OOM\n",
+ cfio->fault.ft_vmf->virtual_address);
+ return -ENOMEM;
+ }
+
+ CERROR("unknow error in page fault!\n");
+ return -EINVAL;
+}
+
+#endif
+
static int vvp_io_fault_start(const struct lu_env *env,
const struct cl_io_slice *ios)
{
struct inode *inode = ccc_object_inode(obj);
struct cl_fault_io *fio = &io->u.ci_fault;
struct vvp_fault_io *cfio = &vio->u.fault;
- cfs_page_t *vmpage;
loff_t offset;
+ int kernel_result = 0;
int result = 0;
+ struct cl_page *page;
+ loff_t size;
+ pgoff_t last; /* last page in a file data region */
LASSERT(vio->cui_oneshot == 0);
if (result != 0)
return result;
- vmpage = filemap_nopage(cfio->ft_vma, cfio->ft_address, cfio->ft_type);
- if (vmpage != NOPAGE_SIGBUS && vmpage != NOPAGE_OOM)
- LL_CDEBUG_PAGE(D_PAGE, vmpage,
- "got addr %lu type %lx\n",
- cfio->ft_address, (long)cfio->ft_type);
- else
- CDEBUG(D_PAGE, "got addr %lu type %lx - SIGBUS\n",
- cfio->ft_address, (long)cfio->ft_type);
-
- if (vmpage == NOPAGE_SIGBUS)
- result = -EFAULT;
- else if (vmpage == NOPAGE_OOM)
- result = -ENOMEM;
- else {
- struct cl_page *page;
- loff_t size;
- pgoff_t last; /* last page in a file data region */
-
- /* Temporarily lock vmpage to keep cl_page_find() happy. */
- lock_page(vmpage);
- page = cl_page_find(env, obj, fio->ft_index, vmpage,
- CPT_CACHEABLE);
- unlock_page(vmpage);
- if (!IS_ERR(page)) {
- size = i_size_read(inode);
- last = cl_index(obj, size - 1);
- if (fio->ft_index == last)
- /*
- * Last page is mapped partially.
- */
- fio->ft_nob = size - cl_offset(obj,
- fio->ft_index);
- else
- fio->ft_nob = cl_page_size(obj);
- lu_ref_add(&page->cp_reference, "fault", io);
- fio->ft_page = page;
- /*
- * Certain 2.6 kernels return not-NULL from
- * filemap_nopage() when page is beyond the file size,
- * on the grounds that "An external ptracer can access
- * pages that normally aren't accessible.." Don't
- * propagate such page fault to the lower layers to
- * avoid side-effects like KMS updates.
- */
- if (fio->ft_index > last)
- result = +1;
- } else
- result = PTR_ERR(page);
+ /* must return locked page */
+ kernel_result = vvp_io_kernel_fault(cfio);
+ if (kernel_result != 0)
+ return kernel_result;
+ /* Temporarily lock vmpage to keep cl_page_find() happy. */
+ lock_page(cfio->ft_vmpage);
+ page = cl_page_find(env, obj, fio->ft_index, cfio->ft_vmpage,
+ CPT_CACHEABLE);
+ unlock_page(cfio->ft_vmpage);
+ if (IS_ERR(page)) {
+ page_cache_release(cfio->ft_vmpage);
+ cfio->ft_vmpage = NULL;
+ return PTR_ERR(page);
}
+
+ size = i_size_read(inode);
+ last = cl_index(obj, size - 1);
+ if (fio->ft_index == last)
+ /*
+ * Last page is mapped partially.
+ */
+ fio->ft_nob = size - cl_offset(obj, fio->ft_index);
+ else
+ fio->ft_nob = cl_page_size(obj);
+
+ lu_ref_add(&page->cp_reference, "fault", io);
+ fio->ft_page = page;
+ /*
+ * Certain 2.6 kernels return not-NULL from
+ * filemap_nopage() when page is beyond the file size,
+ * on the grounds that "An external ptracer can access
+ * pages that normally aren't accessible.." Don't
+ * propagate such page fault to the lower layers to
+ * avoid side-effects like KMS updates.
+ */
+ if (fio->ft_index > last)
+ result = +1;
+
return result;
}
#include <linux/version.h>
#include <linux/bitops.h>
#include <linux/quota.h>
-#include <linux/quotaio_v1.h>
-#include <linux/quotaio_v2.h>
+#ifdef HAVE_QUOTAIO_V1_H
+# include <linux/quotaio_v1.h>
+# include <linux/quotaio_v2.h>
+#else
+# include <quotaio_v1.h>
+# include <quotaio_v2.h>
+# include <quota_tree.h>
+# define V2_DQTREEOFF QT_TREEOFF
+#endif
+
#if defined(HAVE_EXT3_XATTR_H)
#include <ext3/xattr.h>
#else
/* We assume that there will be 1 bit set in s_dquot.flags for each
* quota file that is active. This is at least true for now.
*/
- needed += hweight32(sb_any_quota_enabled(sb)) *
+ needed += hweight32(ll_sb_any_quota_active(sb)) *
FSFILT_SINGLEDATA_TRANS_BLOCKS(sb);
#endif
LASSERT(oqc->qc_id == LUSTRE_QUOTA_V2);
- if (!qcop->quota_on)
- GOTO(out, rc = -ENOSYS);
-
- rc = qcop->quota_on(sb, i, QFMT_VFS_V0,
- name[i]);
+ rc = ll_quota_on(sb, i, QFMT_VFS_V0,
+ name[i], 0);
} else if (oqc->qc_cmd == Q_QUOTAOFF) {
- if (!qcop->quota_off)
- GOTO(out, rc = -ENOSYS);
- rc = qcop->quota_off(sb, i);
+ rc = ll_quota_off(sb, i, 0);
}
if (rc == -EBUSY)
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/quotaio_v1.h>
+#ifdef HAVE_QUOTAIO_V1_H
+# include <linux/quotaio_v1.h>
+#endif
#include <asm/byteorder.h>
#include <asm/uaccess.h>
OBD_SET_CTXT_MAGIC(save);
save->fs = get_fs();
- LASSERT(atomic_read(¤t->fs->pwd->d_count));
+ LASSERT(atomic_read(&cfs_fs_pwd(current->fs)->d_count));
LASSERT(atomic_read(&new_ctx->pwd->d_count));
- save->pwd = dget(current->fs->pwd);
- save->pwdmnt = mntget(current->fs->pwdmnt);
+ save->pwd = dget(cfs_fs_pwd(current->fs));
+ save->pwdmnt = mntget(cfs_fs_mnt(current->fs));
save->luc.luc_umask = current->fs->umask;
save->ngroups = current->group_info->ngroups;
ASSERT_CTXT_MAGIC(saved->magic);
ASSERT_KERNEL_CTXT("popping non-kernel context!\n");
- LASSERTF(current->fs->pwd == new_ctx->pwd, "%p != %p\n",
- current->fs->pwd, new_ctx->pwd);
- LASSERTF(current->fs->pwdmnt == new_ctx->pwdmnt, "%p != %p\n",
- current->fs->pwdmnt, new_ctx->pwdmnt);
+ LASSERTF(cfs_fs_pwd(current->fs) == new_ctx->pwd, "%p != %p\n",
+ cfs_fs_pwd(current->fs), new_ctx->pwd);
+ LASSERTF(cfs_fs_mnt(current->fs) == new_ctx->pwdmnt, "%p != %p\n",
+ cfs_fs_mnt(current->fs), new_ctx->pwdmnt);
set_fs(saved->fs);
ll_set_fs_pwd(current->fs, saved->pwdmnt, saved->pwd);
struct changelog_show cs = {};
int rc;
- CDEBUG(D_CHANGELOG, "file pid %d\n", file->f_owner.pid);
-
if (count != sizeof(cs))
return -EINVAL;
if (copy_from_user(&cs, buffer, sizeof(cs)))
return -EFAULT;
- CDEBUG(D_CHANGELOG, "changelog to pid=%d(%d) start "LPU64"\n",
- cs.cs_pid, file->f_owner.pid, cs.cs_startrec);
+ CDEBUG(D_CHANGELOG, "changelog to pid=%d start "LPU64"\n",
+ cs.cs_pid, cs.cs_startrec);
/* Set up the remote catalog handle */
ctxt = llog_get_context(obd, LLOG_CHANGELOG_REPL_CTXT);
obd->obd_lvfs_ctxt.fs = get_ds();
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- dentry = lookup_one_len(MOUNT_CONFIGS_DIR, current->fs->pwd,
+ dentry = lookup_one_len(MOUNT_CONFIGS_DIR, cfs_fs_pwd(current->fs),
strlen(MOUNT_CONFIGS_DIR));
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
if (IS_ERR(dentry)) {
struct ll_crypto_hash *tfm;
struct capa_hmac_alg *alg;
int keylen;
- struct scatterlist sl = {
- .page = virt_to_page(capa),
- .offset = (unsigned long)(capa) % CFS_PAGE_SIZE,
- .length = offsetof(struct lustre_capa, lc_hmac),
- };
+ struct scatterlist sl;
if (capa_alg(capa) != CAPA_HMAC_ALG_SHA1) {
CERROR("unknown capability hmac algorithm!\n");
}
keylen = alg->ha_keylen;
+ sg_set_page(&sl, virt_to_page(capa),
+ offsetof(struct lustre_capa, lc_hmac),
+ (unsigned long)(capa) % CFS_PAGE_SIZE);
+
ll_crypto_hmac(tfm, key, &keylen, &sl, sl.length, hmac);
ll_crypto_free_hash(tfm);
int capa_encrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen)
{
struct ll_crypto_cipher *tfm;
- struct scatterlist sd = {
- .page = virt_to_page(d),
- .offset = (unsigned long)(d) % CFS_PAGE_SIZE,
- .length = 16,
- };
- struct scatterlist ss = {
- .page = virt_to_page(s),
- .offset = (unsigned long)(s) % CFS_PAGE_SIZE,
- .length = 16,
- };
+ struct scatterlist sd;
+ struct scatterlist ss;
struct blkcipher_desc desc;
unsigned int min;
int rc;
GOTO(out, rc);
}
+ sg_set_page(&sd, virt_to_page(d), 16,
+ (unsigned long)(d) % CFS_PAGE_SIZE);
+
+ sg_set_page(&ss, virt_to_page(s), 16,
+ (unsigned long)(s) % CFS_PAGE_SIZE);
desc.tfm = tfm;
desc.info = NULL;
desc.flags = 0;
int capa_decrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen)
{
struct ll_crypto_cipher *tfm;
- struct scatterlist sd = {
- .page = virt_to_page(d),
- .offset = (unsigned long)(d) % CFS_PAGE_SIZE,
- .length = 16,
- };
- struct scatterlist ss = {
- .page = virt_to_page(s),
- .offset = (unsigned long)(s) % CFS_PAGE_SIZE,
- .length = 16,
- };
+ struct scatterlist sd;
+ struct scatterlist ss;
struct blkcipher_desc desc;
unsigned int min;
int rc;
GOTO(out, rc);
}
+ sg_set_page(&sd, virt_to_page(d), 16,
+ (unsigned long)(d) % CFS_PAGE_SIZE);
+
+ sg_set_page(&ss, virt_to_page(s), 16,
+ (unsigned long)(s) % CFS_PAGE_SIZE);
+
desc.tfm = tfm;
desc.info = NULL;
desc.flags = 0;
}
/**
- * True, iff \a io is a sendfile().
- */
-int cl_io_is_sendfile(const struct cl_io *io)
-{
- return io->ci_type == CIT_READ && io->u.ci_rd.rd_is_sendfile;
-}
-EXPORT_SYMBOL(cl_io_is_sendfile);
-
-/**
* Returns true iff there is an IO ongoing in the given environment.
*/
int cl_io_is_going(const struct lu_env *env)
ENTRY;
obd_sysctl_init();
- proc_lustre_root = lprocfs_register("lustre", proc_root_fs,
+ proc_lustre_root = lprocfs_register("fs/lustre", NULL,
lprocfs_base, NULL);
rc = lprocfs_seq_create(proc_lustre_root, "devices", 0444,
&obd_device_list_fops, NULL);
cfs_sysctl_table_header_t *obd_table_header = NULL;
+#ifndef HAVE_SYSCTL_UNNUMBERED
+
#define OBD_SYSCTL 300
enum {
OBD_AT_HISTORY,
};
+#else
+
+#define OBD_SYSCTL CTL_UNNUMBERED
+
+#define OBD_FAIL_LOC CTL_UNNUMBERED
+#define OBD_FAIL_VAL CTL_UNNUMBERED
+#define OBD_TIMEOUT CTL_UNNUMBERED
+#define OBD_DUMP_ON_TIMEOUT CTL_UNNUMBERED
+#define OBD_MEMUSED CTL_UNNUMBERED
+#define OBD_PAGESUSED CTL_UNNUMBERED
+#define OBD_MAXMEMUSED CTL_UNNUMBERED
+#define OBD_MAXPAGESUSED CTL_UNNUMBERED
+#define OBD_SYNCFILTER CTL_UNNUMBERED
+#define OBD_LDLM_TIMEOUT CTL_UNNUMBERED
+#define OBD_DUMP_ON_EVICTION CTL_UNNUMBERED
+#define OBD_DEBUG_PEER_ON_TIMEOUT CTL_UNNUMBERED
+#define OBD_ALLOC_FAIL_RATE CTL_UNNUMBERED
+#define OBD_MAX_DIRTY_PAGES CTL_UNNUMBERED
+#define OBD_AT_MIN CTL_UNNUMBERED
+#define OBD_AT_MAX CTL_UNNUMBERED
+#define OBD_AT_EXTRA CTL_UNNUMBERED
+#define OBD_AT_EARLY_MARGIN CTL_UNNUMBERED
+#define OBD_AT_HISTORY CTL_UNNUMBERED
+
+#endif
+
+
int LL_PROC_PROTO(proc_fail_loc)
{
int rc;
if (page == NULL)
return -ENOMEM;
- LPROCFS_ENTRY();
+ if (LPROCFS_ENTRY_AND_CHECK(dp))
+ return -ENOENT;
+
OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
- if (!dp->deleted && dp->read_proc)
+ if (dp->read_proc)
rc = dp->read_proc(page, &start, *ppos, CFS_PAGE_SIZE,
&eof, dp->data);
LPROCFS_EXIT();
struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
int rc = -EIO;
- LPROCFS_ENTRY();
- if (!dp->deleted && dp->write_proc)
+ if (LPROCFS_ENTRY_AND_CHECK(dp))
+ return -ENOENT;
+ if (dp->write_proc)
rc = dp->write_proc(f, buf, size, dp->data);
LPROCFS_EXIT();
return rc;
struct seq_file *seq;
int rc;
- LPROCFS_ENTRY_AND_CHECK(dp);
+ if (LPROCFS_ENTRY_AND_CHECK(dp))
+ return -ENOENT;
+
rc = seq_open(file, &lprocfs_stats_seq_sops);
if (rc) {
LPROCFS_EXIT();
void *class_handle2object(__u64 cookie)
{
struct handle_bucket *bucket;
- struct list_head *tmp;
+ struct portals_handle *h;
void *retval = NULL;
ENTRY;
bucket = handle_hash + (cookie & HANDLE_HASH_MASK);
rcu_read_lock();
- list_for_each_rcu(tmp, &bucket->head) {
- struct portals_handle *h;
- h = list_entry(tmp, struct portals_handle, h_link);
+ list_for_each_entry_rcu(h, &bucket->head, h_link) {
if (h->h_cookie != cookie)
continue;
int i;
for (i = 0; i < HANDLE_HASH_SIZE; i++) {
- struct list_head *pos, *n;
- n = NULL;
- spin_lock(&handle_hash[i].lock);
- list_for_each_safe_rcu(pos, n, &(handle_hash[i].head)) {
- struct portals_handle *h;
- h = list_entry(pos, struct portals_handle, h_link);
+ struct portals_handle *h;
+ spin_lock(&handle_hash[i].lock);
+ list_for_each_entry_rcu(h, &(handle_hash[i].head), h_link) {
CERROR("force clean handle "LPX64" addr %p addref %p\n",
h->h_cookie, h, h->h_addref);
int i;
int j;
int k;
+ struct req_format *rf = NULL;
for (i = 0; i < ARRAY_SIZE(req_formats); ++i) {
- struct req_format *rf;
-
rf = (struct req_format *)req_formats[i];
rf->rf_idx = i;
for (j = 0; j < RCL_NR; ++j) {
hashsize = ll_crypto_hash_digestsize(hdesc.tfm);
for (i = 0; i < desc->bd_iov_count; i++) {
- sl.page = desc->bd_iov[i].kiov_page;
- sl.offset = desc->bd_iov[i].kiov_offset;
- sl.length = desc->bd_iov[i].kiov_len;
+ sg_set_page(&sl, desc->bd_iov[i].kiov_page,
+ desc->bd_iov[i].kiov_len,
+ desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK);
ll_crypto_hash_update(&hdesc, &sl, sl.length);
}
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- dentry = lookup_one_len(MOUNT_CONFIGS_DIR, current->fs->pwd,
+ dentry = lookup_one_len(MOUNT_CONFIGS_DIR, cfs_fs_pwd(current->fs),
strlen(MOUNT_CONFIGS_DIR));
if (IS_ERR(dentry)) {
rc = PTR_ERR(dentry);
int ret = 0;
ENTRY;
- if (!sb_any_quota_enabled(sb))
+ if (!ll_sb_any_quota_active(sb))
RETURN(0);
spin_lock(&qctxt->lqc_lock);
int ret = QUOTA_RET_OK;
ENTRY;
- if (!sb_any_quota_enabled(sb))
+ if (!ll_sb_any_quota_active(sb))
RETURN(QUOTA_RET_NOQUOTA);
/* ignore root user */
int ret;
LOCK_DQONOFF_MUTEX(dqopt);
- if (!sb_has_quota_enabled(qctxt->lqc_sb, type)) {
+ if (!ll_sb_has_quota_active(qctxt->lqc_sb, type)) {
UNLOCK_DQONOFF_MUTEX(dqopt);
break;
}
int rc;
ENTRY;
- if (!sb_any_quota_enabled(qctxt->lqc_sb))
+ if (!ll_sb_any_quota_active(qctxt->lqc_sb))
goto exit;
data.obd = obd;
{
ENTRY;
- if (!sb_any_quota_enabled(obd->u.obt.obt_sb))
+ if (!ll_sb_any_quota_active(obd->u.obt.obt_sb))
RETURN(0);
if (ignore) {
struct obd_quotactl *oqctl;
ENTRY;
- if (!sb_any_quota_enabled(obt->obt_sb))
+ if (!ll_sb_any_quota_active(obt->obt_sb))
RETURN(0);
OBD_ALLOC_PTR(oqctl);
struct lustre_qunit_size *lqs;
int i, q_set = 0;
- if (!sb_any_quota_enabled(obd->u.obt.obt_qctxt.lqc_sb))
+ if (!ll_sb_any_quota_active(obd->u.obt.obt_qctxt.lqc_sb))
RETURN(0);
for (i = 0; i < MAXQUOTAS; i++) {
CDEBUG(D_QUOTA, "commit pending quota for %s\n", obd->obd_name);
CLASSERT(MAXQUOTAS < 4);
- if (!sb_any_quota_enabled(qctxt->lqc_sb))
+ if (!ll_sb_any_quota_active(qctxt->lqc_sb))
RETURN(0);
do_gettimeofday(&work_start);
if [[ x$mgc != xMGC$MGSNID ]]; then
if [ "$mgs_HOST" ]; then
local mgc_ip=$(ping -q -c1 -w1 $mgs_HOST | grep PING | awk '{print $3}' | sed -e "s/(//g" -e "s/)//g")
- [[ x$mgc = xMGC$mgc_ip@$NETTYPE ]] ||
- error_exit "MGSNID=$MGSNID, mounted: $mounted, MGC : $mgc"
+# [[ x$mgc = xMGC$mgc_ip@$NETTYPE ]] ||
+# error_exit "MGSNID=$MGSNID, mounted: $mounted, MGC : $mgc"
fi
fi
return 0
local mgshost=$(mount | grep " $mntpt " | awk -F@ '{print $1}')
mgshost=$(echo $mgshost | awk -F: '{print $1}')
-# if [ "$mgshost" != "$myMGS_host" ]; then
-# error_exit "Bad config file: lustre is mounted with mgs $mgshost, but mgs_HOST=$mgs_HOST, NETTYPE=$NETTYPE
-# Please use correct config or set mds_HOST correctly!"
-# fi
+ if [ "$mgshost" != "$myMGS_host" ]; then
+ log "Bad config file: lustre is mounted with mgs $mgshost, but mgs_HOST=$mgs_HOST, NETTYPE=$NETTYPE
+ Please use correct config or set mds_HOST correctly!"
+ fi
sanity_mount_check ||
error "environments are insane!"
#include <lustre/lustre_idl.h>
#include <lustre/liblustreapi.h>
#include <lustre/lustre_user.h>
+#include <lustre_quota.h>
#include <libcfs/libcfsutil.h>
#include "obdctl.h"