[Pkg-lustre-svn-commit] updated: [c163f35] Initial Import of client side patch to support 2.6.30
Patrick Winnertz
winnie at debian.org
Thu Aug 20 11:50:27 UTC 2009
The following commit has been merged in the lustre-1.6 branch:
commit c163f35d4fd0d993ca4a8d1dcde310249a0fa452
Author: Patrick Winnertz <winnie at debian.org>
Date: Wed Aug 19 10:48:32 2009 +0200
Initial Import of client side patch to support 2.6.30
- CAUTION!! this patch is not tested!
Signed-off-by: Patrick Winnertz <winnie at debian.org>
diff --git a/debian/patches/00list b/debian/patches/00list
index 11125b0..135e8c2 100644
--- a/debian/patches/00list
+++ b/debian/patches/00list
@@ -10,7 +10,7 @@ no-darwin.dpatch
remove-set_tunables.dpatch
libsysio.dpatch
bug12769-ql-fix.dpatch
-patchless_support_2.6.26.dpatch
+patchless_support_2.6.30.dpatch
#server_support_2.6.27.dpatch
# Debian patches
bash_completion.dpatch
diff --git a/debian/patches/patchless_support_2.6.26.dpatch b/debian/patches/patchless_support_2.6.30.dpatch
similarity index 87%
copy from debian/patches/patchless_support_2.6.26.dpatch
copy to debian/patches/patchless_support_2.6.30.dpatch
index 0d5c413..75108ee 100755
--- a/debian/patches/patchless_support_2.6.26.dpatch
+++ b/debian/patches/patchless_support_2.6.30.dpatch
@@ -6,8 +6,8 @@
@DPATCH@
diff -urNad lustre~/lnet/autoconf/lustre-lnet.m4 lustre/lnet/autoconf/lustre-lnet.m4
---- lustre~/lnet/autoconf/lustre-lnet.m4 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lnet/autoconf/lustre-lnet.m4 2009-03-13 09:45:02.000000000 +0100
+--- lustre~/lnet/autoconf/lustre-lnet.m4 2009-08-19 09:51:08.000000000 +0200
++++ lustre/lnet/autoconf/lustre-lnet.m4 2009-08-19 10:40:29.000000000 +0200
@@ -1362,6 +1362,22 @@
])
])
@@ -40,10 +40,206 @@ diff -urNad lustre~/lnet/autoconf/lustre-lnet.m4 lustre/lnet/autoconf/lustre-lne
])
#
+diff -urNad lustre~/lnet/include/lnet/types.h lustre/lnet/include/lnet/types.h
+--- lustre~/lnet/include/lnet/types.h 2008-08-07 11:50:16.000000000 +0200
++++ lustre/lnet/include/lnet/types.h 2009-08-19 10:46:25.000000000 +0200
+@@ -39,6 +39,33 @@
+
+ #include <libcfs/libcfs.h>
+
++/*
++** dropped from linux/kernel.h
++*/
++
++#ifdef KERNEL_2_6_26
++
++#define NIPQUAD(addr) \
++ ((unsigned char *)&addr)[0], \
++ ((unsigned char *)&addr)[1], \
++ ((unsigned char *)&addr)[2], \
++ ((unsigned char *)&addr)[3]
++
++#if defined(__LITTLE_ENDIAN)
++#define HIPQUAD(addr) \
++ ((unsigned char *)&addr)[3], \
++ ((unsigned char *)&addr)[2], \
++ ((unsigned char *)&addr)[1], \
++ ((unsigned char *)&addr)[0]
++#elif defined(__BIG_ENDIAN)
++#define HIPQUAD NIPQUAD
++#else
++#error "Undefined byteorder??"
++#endif /* __LITTLE_ENDIAN */
++
++#endif
++
++
+ #define LNET_RESERVED_PORTAL 0 /* portals reserved for lnet's own use */
+
+ typedef __u64 lnet_nid_t;
+diff -urNad lustre~/lnet/libcfs/linux/linux-curproc.c lustre/lnet/libcfs/linux/linux-curproc.c
+--- lustre~/lnet/libcfs/linux/linux-curproc.c 2008-11-20 10:27:06.000000000 +0100
++++ lustre/lnet/libcfs/linux/linux-curproc.c 2009-08-19 10:46:25.000000000 +0200
+@@ -41,6 +41,7 @@
+ */
+
+ #include <linux/sched.h>
++#include <linux/fs_struct.h> /* struct fs_struct unknown within linux/sched.h -- bug or feature? */
+
+ #define DEBUG_SUBSYSTEM S_LNET
+
+@@ -54,22 +55,38 @@
+
+ uid_t cfs_curproc_uid(void)
+ {
++#ifdef HAS_STRUCT_CRED
++ return current->real_cred->uid;
++#else
+ return current->uid;
++#endif
+ }
+
+ gid_t cfs_curproc_gid(void)
+ {
++#ifdef HAS_STRUCT_CRED
++ return current->real_cred->gid;
++#else
+ return current->gid;
++#endif
+ }
+
+ uid_t cfs_curproc_fsuid(void)
+ {
++#ifdef HAS_STRUCT_CRED
++ return current->real_cred->fsuid;
++#else
+ return current->fsuid;
++#endif
+ }
+
+ gid_t cfs_curproc_fsgid(void)
+ {
++#ifdef HAS_STRUCT_CRED
++ return current->real_cred->fsgid;
++#else
+ return current->fsgid;
++#endif
+ }
+
+ pid_t cfs_curproc_pid(void)
+@@ -83,7 +100,11 @@
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
+ task_lock(current);
++# ifdef HAS_STRUCT_CRED
++ nr = current->real_cred->group_info->ngroups;
++# else
+ nr = current->group_info->ngroups;
++# endif
+ task_unlock(current);
+ #else
+ nr = current->ngroups;
+@@ -95,8 +116,13 @@
+ {
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
+ task_lock(current);
++# ifdef HAS_STRUCT_CRED
++ size = min_t(int, size, current->real_cred->group_info->ngroups);
++ memcpy(array, current->real_cred->group_info->blocks[0], size * sizeof(__u32));
++# else
+ size = min_t(int, size, current->group_info->ngroups);
+ memcpy(array, current->group_info->blocks[0], size * sizeof(__u32));
++# endif
+ task_unlock(current);
+ #else
+ LASSERT(size <= NGROUPS);
+@@ -127,17 +153,36 @@
+
+ void cfs_cap_raise(cfs_cap_t cap)
+ {
++#ifdef HAS_STRUCT_CRED
++ /* lustre/include/liblustre.h: #define cfs_current() current */
++ struct cred *new = prepare_creds();
++
++ cap_raise(new->cap_effective, cfs_cap_unpack(cap));
++ commit_creds(new);
++#else
+ cap_raise(cfs_current()->cap_effective, cfs_cap_unpack(cap));
++#endif
+ }
+
+ void cfs_cap_lower(cfs_cap_t cap)
+ {
++#ifdef HAS_STRUCT_CRED
++ struct cred *new = prepare_creds();
++
++ cap_lower(new->cap_effective, cfs_cap_unpack(cap));
++ commit_creds(new);
++#else
+ cap_lower(cfs_current()->cap_effective, cfs_cap_unpack(cap));
++#endif
+ }
+
+ int cfs_cap_raised(cfs_cap_t cap)
+ {
++#ifdef HAS_STRUCT_CRED
++ return cap_raised(cfs_current()->real_cred->cap_effective, cfs_cap_unpack(cap));
++#else
+ return cap_raised(cfs_current()->cap_effective, cfs_cap_unpack(cap));
++#endif
+ }
+
+ void cfs_kernel_cap_pack(cfs_kernel_cap_t kcap, cfs_cap_t *cap)
+@@ -170,13 +215,22 @@
+ cfs_cap_t cfs_curproc_cap_pack(void)
+ {
+ cfs_cap_t cap;
++#ifdef HAS_STRUCT_CRED
++ cfs_kernel_cap_pack(current->real_cred->cap_effective, &cap);
++#else
+ cfs_kernel_cap_pack(current->cap_effective, &cap);
++#endif
+ return cap;
+ }
+
+ void cfs_curproc_cap_unpack(cfs_cap_t cap)
+ {
++#ifdef HAS_STRUCT_CRED
++ /* warning: passing argument 1 of 'cfs_kernel_cap_unpack' discards qualifiers from pointer target type --azi */
++ cfs_kernel_cap_unpack((kernel_cap_t *)¤t->real_cred->cap_effective, cap);
++#else
+ cfs_kernel_cap_unpack(¤t->cap_effective, cap);
++#endif
+ }
+
+ int cfs_capable(cfs_cap_t cap)
+diff -urNad lustre~/lnet/libcfs/linux/linux-module.c lustre/lnet/libcfs/linux/linux-module.c
+--- lustre~/lnet/libcfs/linux/linux-module.c 2008-09-15 20:44:53.000000000 +0200
++++ lustre/lnet/libcfs/linux/linux-module.c 2009-08-19 10:46:25.000000000 +0200
+@@ -139,7 +139,11 @@
+ struct cfs_psdev_file pfile;
+ int rc = 0;
+
++#ifdef HAS_STRUCT_CRED
++ if (current->real_cred->fsuid != 0)
++#else
+ if (current->fsuid != 0)
++#endif
+ return -EACCES;
+
+ if ( _IOC_TYPE(cmd) != IOC_LIBCFS_TYPE ||
diff -urNad lustre~/lnet/libcfs/linux/linux-prim.c lustre/lnet/libcfs/linux/linux-prim.c
---- lustre~/lnet/libcfs/linux/linux-prim.c 2008-08-07 11:51:06.000000000 +0200
-+++ lustre/lnet/libcfs/linux/linux-prim.c 2009-03-13 09:45:02.000000000 +0100
-@@ -49,7 +49,7 @@
+--- lustre~/lnet/libcfs/linux/linux-prim.c 2009-08-19 09:51:08.000000000 +0200
++++ lustre/lnet/libcfs/linux/linux-prim.c 2009-08-19 10:46:25.000000000 +0200
+@@ -40,6 +40,7 @@
+ #endif
+ #include <linux/module.h>
+ #include <linux/kernel.h>
++#include <linux/fs_struct.h> /* required for copy_fs_struct() */
+ #include <libcfs/libcfs.h>
+
+ #if defined(CONFIG_KGDB)
+@@ -49,7 +50,7 @@
void cfs_enter_debugger(void)
{
#if defined(CONFIG_KGDB)
@@ -53,8 +249,8 @@ diff -urNad lustre~/lnet/libcfs/linux/linux-prim.c lustre/lnet/libcfs/linux/linu
asm("int $3");
#else
diff -urNad lustre~/lnet/libcfs/linux/linux-tcpip.c lustre/lnet/libcfs/linux/linux-tcpip.c
---- lustre~/lnet/libcfs/linux/linux-tcpip.c 2008-08-07 11:51:07.000000000 +0200
-+++ lustre/lnet/libcfs/linux/linux-tcpip.c 2009-03-13 09:45:02.000000000 +0100
+--- lustre~/lnet/libcfs/linux/linux-tcpip.c 2009-08-19 09:51:08.000000000 +0200
++++ lustre/lnet/libcfs/linux/linux-tcpip.c 2009-08-19 10:40:29.000000000 +0200
@@ -63,7 +63,11 @@
return rc;
}
@@ -68,8 +264,8 @@ diff -urNad lustre~/lnet/libcfs/linux/linux-tcpip.c lustre/lnet/libcfs/linux/lin
rc = fd;
sock_release(sock);
diff -urNad lustre~/lnet/lnet/api-ni.c lustre/lnet/lnet/api-ni.c
---- lustre~/lnet/lnet/api-ni.c 2009-03-12 10:21:27.000000000 +0100
-+++ lustre/lnet/lnet/api-ni.c 2009-03-13 09:45:02.000000000 +0100
+--- lustre~/lnet/lnet/api-ni.c 2009-08-19 09:51:08.000000000 +0200
++++ lustre/lnet/lnet/api-ni.c 2009-08-19 10:40:29.000000000 +0200
@@ -1032,7 +1032,7 @@
#ifdef __KERNEL__
if (lnd == NULL) {
@@ -80,8 +276,8 @@ diff -urNad lustre~/lnet/lnet/api-ni.c lustre/lnet/lnet/api-ni.c
lnd = lnet_find_lnd_by_type(lnd_type);
diff -urNad lustre~/lustre/autoconf/lustre-core.m4 lustre/lustre/autoconf/lustre-core.m4
---- lustre~/lustre/autoconf/lustre-core.m4 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/autoconf/lustre-core.m4 2009-03-13 09:45:02.000000000 +0100
+--- lustre~/lustre/autoconf/lustre-core.m4 2009-08-19 09:51:08.000000000 +0200
++++ lustre/lustre/autoconf/lustre-core.m4 2009-08-19 10:40:29.000000000 +0200
@@ -1106,15 +1106,20 @@
AC_DEFUN([LC_PAGE_CHECKED],
[AC_MSG_CHECKING([kernel has PageChecked and SetPageChecked])
@@ -147,7 +343,7 @@ diff -urNad lustre~/lustre/autoconf/lustre-core.m4 lustre/lustre/autoconf/lustre
AC_DEFUN([LC_KERNEL_SPLICE_READ],
[AC_MSG_CHECKING([if kernel has .splice_read])
LB_LINUX_TRY_COMPILE([
-@@ -1268,11 +1295,240 @@
+@@ -1268,11 +1295,397 @@
# 2.6.23 extract nfs export related data into exportfs.h
AC_DEFUN([LC_HAVE_EXPORTFS_H],
@@ -390,10 +586,167 @@ diff -urNad lustre~/lustre/autoconf/lustre-core.m4 lustre/lustre/autoconf/lustre
+ AC_MSG_RESULT(no)
+])
+EXTRA_KCFLAGS="$tmp_flags"
++])
++
++
++# 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 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])
++])
++])
++
++# 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 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])
++])
])
#
-@@ -1372,8 +1628,31 @@
+@@ -1372,8 +1785,45 @@
LC_FS_RENAME_DOES_D_MOVE
# 2.6.23
LC_UNREGISTER_BLKDEV_RETURN_INT
@@ -421,11 +774,25 @@ diff -urNad lustre~/lustre/autoconf/lustre-core.m4 lustre/lustre/autoconf/lustre
+ LC_INODE_PERMISION_2ARGS
+ LC_FILE_REMOVE_SUID
+ LC_TRYLOCKPAGE
-+ LC_RW_TREE_LOCK
++ LC_RW_TREE_LOCK
++ #done until here
++ LC_READ_INODE_IN_SBOPS #done
++ LC_EXPORT_INODE_PERMISSION #done
++ LC_QUOTA_ON_5ARGS #done
++ LC_QUOTA_OFF_3ARGS #done
++ LC_VFS_DQ_OFF #done
++
++ # 2.6.27.15-2 sles11
++ LC_BI_HW_SEGMENTS #done
++ LC_HAVE_QUOTAIO_V1_H #done
++ LC_VFS_SYMLINK_5ARGS #done
++ LC_SB_ANY_QUOTA_ACTIVE
++ LC_SB_HAS_QUOTA_ACTIVE
++
])
#
-@@ -1606,6 +1885,7 @@
+@@ -1606,6 +2056,7 @@
],[
AC_MSG_RESULT([no])
])
@@ -434,8 +801,8 @@ diff -urNad lustre~/lustre/autoconf/lustre-core.m4 lustre/lustre/autoconf/lustre
AC_MSG_RESULT([no])
])
diff -urNad lustre~/lustre/autoconf/lustre-core.m4.orig lustre/lustre/autoconf/lustre-core.m4.orig
---- lustre~/lustre/autoconf/lustre-core.m4.orig 1970-01-01 00:00:00.000000000 +0000
-+++ lustre/lustre/autoconf/lustre-core.m4.orig 2009-03-13 09:45:02.000000000 +0100
+--- lustre~/lustre/autoconf/lustre-core.m4.orig 1970-01-01 01:00:00.000000000 +0100
++++ lustre/lustre/autoconf/lustre-core.m4.orig 2009-08-19 10:40:29.000000000 +0200
@@ -0,0 +1,2075 @@
+#* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+#* vim:expandtab:shiftwidth=8:tabstop=8:
@@ -2512,9 +2879,1023 @@ diff -urNad lustre~/lustre/autoconf/lustre-core.m4.orig lustre/lustre/autoconf/l
+esac
+
+])
+diff -urNad lustre~/lustre/include/liblustre.h lustre/lustre/include/liblustre.h
+--- lustre~/lustre/include/liblustre.h 2009-08-19 09:51:08.000000000 +0200
++++ lustre/lustre/include/liblustre.h 2009-08-19 10:46:25.000000000 +0200
+@@ -586,6 +586,55 @@
+ int signal;
+ };
+
++#ifdef HAS_STRUCT_CRED
++
++struct cred {
++// atomic_t usage;
++// uid_t uid; /* real UID of the task */
++// gid_t gid; /* real GID of the task */
++// uid_t suid; /* saved UID of the task */
++// gid_t sgid; /* saved GID of the task */
++// uid_t euid; /* effective UID of the task */
++// gid_t egid; /* effective GID of the task */
++uid_t fsuid; /* UID for VFS ops */
++gid_t fsgid; /* GID for VFS ops */
++// unsigned securebits; /* SUID-less security management */
++// kernel_cap_t cap_inheritable; /* caps our children can inherit */
++// kernel_cap_t cap_permitted; /* caps we're permitted */
++cfs_cap_t cap_effective; /* caps we can actually use */
++// kernel_cap_t cap_bset; /* capability bounding set */
++// #ifdef CONFIG_KEYS
++// unsigned char jit_keyring; /* default keyring to attach requested
++ // * keys to */
++// struct key *thread_keyring; /* keyring private to this thread */
++// struct key *request_key_auth; /* assumed request_key authority */
++// struct thread_group_cred *tgcred; /* thread-group shared credentials */
++// #endif
++// #ifdef CONFIG_SECURITY
++// void *security; /* subjective LSM security */
++// #endif
++// struct user_struct *user; /* real user ID subscription */
++// struct group_info *group_info; /* supplementary groups for euid/fsgid */
++// struct rcu_head rcu; /* RCU deletion hook */
++};
++
++struct task_struct {
++ int state;
++ struct signal pending;
++ char comm[32];
++ int pid;
++ struct cred *real_cred;
++ struct cred *cred;
++// int fsuid;
++// int fsgid;
++ int max_groups;
++ int ngroups;
++ gid_t *groups;
++// cfs_cap_t cap_effective;
++};
++
++#else
++
+ struct task_struct {
+ int state;
+ struct signal pending;
+@@ -599,6 +648,8 @@
+ cfs_cap_t cap_effective;
+ };
+
++#endif
++
+ typedef struct task_struct cfs_task_t;
+ #define cfs_current() current
+ #define cfs_curproc_pid() (current->pid)
+@@ -607,6 +658,14 @@
+ extern struct task_struct *current;
+ int in_group_p(gid_t gid);
+
++#ifdef HAS_STRUCT_CRED_INVALID
++/* since 2.6.29 the task credentials are kept in a
++** const struct cred *cread / *real_cred */
++# define current_cred current->real_cred
++#else
++# define current_cred current
++#endif
++
+ #define set_current_state(foo) do { current->state = foo; } while (0)
+
+ #define init_waitqueue_entry(q,p) do { (q)->process = p; } while (0)
+diff -urNad lustre~/lustre/include/liblustre.h.orig lustre/lustre/include/liblustre.h.orig
+--- lustre~/lustre/include/liblustre.h.orig 1970-01-01 01:00:00.000000000 +0100
++++ lustre/lustre/include/liblustre.h.orig 2009-08-19 09:51:08.000000000 +0200
+@@ -0,0 +1,917 @@
++/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
++ * vim:expandtab:shiftwidth=8:tabstop=8:
++ *
++ * 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.sun.com/software/products/lustre/docs/GPLv2.pdf
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ *
++ * GPL HEADER END
++ */
++/*
++ * Copyright 2008 Sun Microsystems, Inc. All rights reserved
++ * Use is subject to license terms.
++ */
++/*
++ * This file is part of Lustre, http://www.lustre.org/
++ * Lustre is a trademark of Sun Microsystems, Inc.
++ *
++ * lustre/include/liblustre.h
++ *
++ * User-space Lustre headers.
++ */
++
++#ifndef LIBLUSTRE_H__
++#define LIBLUSTRE_H__
++
++#ifdef __KERNEL__
++#error Kernel files should not #include <liblustre.h>
++#else
++/*
++ * The userspace implementations of linux/spinlock.h vary; we just
++ * include our own for all of them
++ */
++#define __LINUX_SPINLOCK_H
++#endif
++
++#include <sys/mman.h>
++#ifdef HAVE_STDINT_H
++# include <stdint.h>
++#endif
++#ifdef HAVE_ASM_PAGE_H
++# include <asm/page.h>
++#endif
++#ifdef HAVE_SYS_USER_H
++# include <sys/user.h>
++#endif
++#ifdef HAVE_SYS_IOCTL_H
++# include <sys/ioctl.h>
++#endif
++#ifndef _IOWR
++# include "ioctl.h"
++#endif
++
++#include <stdio.h>
++#include <sys/ioctl.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++#include <sys/stat.h>
++#ifdef HAVE_SYS_VFS_H
++# include <sys/vfs.h>
++#endif
++#include <unistd.h>
++#include <fcntl.h>
++
++#include <libcfs/list.h>
++#include <lnet/lnet.h>
++#include <libcfs/kp30.h>
++#include <libcfs/user-bitops.h>
++
++/* definitions for liblustre */
++
++#ifdef __CYGWIN__
++
++#define CFS_PAGE_SHIFT 12
++#define CFS_PAGE_SIZE (1UL << CFS_PAGE_SHIFT)
++#define CFS_PAGE_MASK (~((__u64)CFS_PAGE_SIZE-1))
++#define loff_t long long
++#define ERESTART 2001
++typedef unsigned short umode_t;
++
++#endif
++
++#ifndef CURRENT_SECONDS
++# define CURRENT_SECONDS time(0)
++#endif
++
++#ifndef ARRAY_SIZE
++#define ARRAY_SIZE(a) ((sizeof (a))/(sizeof ((a)[0])))
++#endif
++
++/* This is because lprocfs_status.h gets included here indirectly. It would
++ * be much better to just avoid lprocfs being included into liblustre entirely
++ * but that requires more header surgery than I can handle right now.
++ */
++#ifndef smp_processor_id
++#define smp_processor_id() 0
++#endif
++#ifndef num_online_cpus
++#define num_online_cpus() 1
++#endif
++#ifndef num_possible_cpus
++#define num_possible_cpus() 1
++#endif
++
++/* always adopt 2.5 definitions */
++#define KERNEL_VERSION(a,b,c) ((a)*100+(b)*10+c)
++#define LINUX_VERSION_CODE KERNEL_VERSION(2,5,0)
++
++#ifndef page_private
++#define page_private(page) ((page)->private)
++#define set_page_private(page, v) ((page)->private = (v))
++#endif
++
++static inline void inter_module_put(void *a)
++{
++ return;
++}
++
++void *inter_module_get(char *arg);
++
++/* cheats for now */
++
++struct work_struct {
++ void (*ws_task)(void *arg);
++ void *ws_arg;
++};
++
++static inline void prepare_work(struct work_struct *q, void (*t)(void *),
++ void *arg)
++{
++ q->ws_task = t;
++ q->ws_arg = arg;
++ return;
++}
++
++static inline void schedule_work(struct work_struct *q)
++{
++ q->ws_task(q->ws_arg);
++}
++
++
++#define strnlen(a,b) strlen(a)
++static inline void *kmalloc(int size, int prot)
++{
++ return malloc(size);
++}
++#define vmalloc malloc
++#define vfree free
++#define kfree(a) free(a)
++#define GFP_KERNEL 1
++#define GFP_HIGHUSER 1
++#define GFP_ATOMIC 1
++#define GFP_NOFS 1
++#define IS_ERR(a) ((unsigned long)(a) > (unsigned long)-1000L)
++#define PTR_ERR(a) ((long)(a))
++#define ERR_PTR(a) ((void*)((long)(a)))
++
++typedef struct {
++ void *cwd;
++}mm_segment_t;
++
++typedef int (read_proc_t)(char *page, char **start, off_t off,
++ int count, int *eof, void *data);
++
++struct file; /* forward ref */
++typedef int (write_proc_t)(struct file *file, const char *buffer,
++ unsigned long count, void *data);
++
++#define NIPQUAD(addr) \
++ ((unsigned char *)&addr)[0], \
++ ((unsigned char *)&addr)[1], \
++ ((unsigned char *)&addr)[2], \
++ ((unsigned char *)&addr)[3]
++
++#if defined(__LITTLE_ENDIAN)
++#define HIPQUAD(addr) \
++ ((unsigned char *)&addr)[3], \
++ ((unsigned char *)&addr)[2], \
++ ((unsigned char *)&addr)[1], \
++ ((unsigned char *)&addr)[0]
++#elif defined(__BIG_ENDIAN)
++#define HIPQUAD NIPQUAD
++#else
++#error "Undefined byteorder??"
++#endif /* __LITTLE_ENDIAN */
++
++/* bits ops */
++
++/* a long can be more than 32 bits, so use BITS_PER_LONG
++ * to allow the compiler to adjust the bit shifting accordingly
++ */
++
++static __inline__ int ext2_set_bit(int nr, void *addr)
++{
++ return set_bit(nr, addr);
++}
++
++static __inline__ int ext2_clear_bit(int nr, void *addr)
++{
++ return clear_bit(nr, addr);
++}
++
++static __inline__ int ext2_test_bit(int nr, void *addr)
++{
++ return test_bit(nr, addr);
++}
++
++/* modules */
++
++struct module {
++ int count;
++};
++
++static inline void MODULE_AUTHOR(char *name)
++{
++ printf("%s\n", name);
++}
++#define MODULE_DESCRIPTION(name) MODULE_AUTHOR(name)
++#define MODULE_LICENSE(name) MODULE_AUTHOR(name)
++
++#define THIS_MODULE NULL
++#define __init
++#define __exit
++
++/* devices */
++
++static inline int misc_register(void *foo)
++{
++ return 0;
++}
++
++static inline int misc_deregister(void *foo)
++{
++ return 0;
++}
++
++static inline int request_module(char *name)
++{
++ return (-EINVAL);
++}
++
++#define __MOD_INC_USE_COUNT(m) do {} while (0)
++#define __MOD_DEC_USE_COUNT(m) do {} while (0)
++#define MOD_INC_USE_COUNT do {} while (0)
++#define MOD_DEC_USE_COUNT do {} while (0)
++static inline void __module_get(struct module *module)
++{
++}
++
++static inline int try_module_get(struct module *module)
++{
++ return 1;
++}
++
++static inline void module_put(struct module *module)
++{
++}
++
++/* module initialization */
++extern int init_obdclass(void);
++extern int ptlrpc_init(void);
++extern int ldlm_init(void);
++extern int osc_init(void);
++extern int lov_init(void);
++extern int mdc_init(void);
++extern int mgc_init(void);
++extern int echo_client_init(void);
++
++
++
++/* general stuff */
++
++#define EXPORT_SYMBOL(S)
++
++struct rcu_head { };
++
++typedef struct { } spinlock_t;
++typedef __u64 kdev_t;
++
++#define SPIN_LOCK_UNLOCKED (spinlock_t) { }
++#define LASSERT_SPIN_LOCKED(lock) do {} while(0)
++#define LASSERT_SEM_LOCKED(sem) do {} while(0)
++
++static inline void spin_lock(spinlock_t *l) {return;}
++static inline void spin_unlock(spinlock_t *l) {return;}
++static inline void spin_lock_init(spinlock_t *l) {return;}
++static inline void local_irq_save(unsigned long flag) {return;}
++static inline void local_irq_restore(unsigned long flag) {return;}
++static inline int spin_is_locked(spinlock_t *l) {return 1;}
++
++static inline void spin_lock_bh(spinlock_t *l) {}
++static inline void spin_unlock_bh(spinlock_t *l) {}
++static inline void spin_lock_irqsave(spinlock_t *a, unsigned long b) {}
++static inline void spin_unlock_irqrestore(spinlock_t *a, unsigned long b) {}
++
++typedef spinlock_t rwlock_t;
++#define RW_LOCK_UNLOCKED SPIN_LOCK_UNLOCKED
++#define read_lock(l) spin_lock(l)
++#define read_unlock(l) spin_unlock(l)
++#define write_lock(l) spin_lock(l)
++#define write_unlock(l) spin_unlock(l)
++#define rwlock_init(l) spin_lock_init(l)
++
++#define min(x,y) ((x)<(y) ? (x) : (y))
++#define max(x,y) ((x)>(y) ? (x) : (y))
++
++#ifndef min_t
++#define min_t(type,x,y) \
++ ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
++#endif
++#ifndef max_t
++#define max_t(type,x,y) \
++ ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
++#endif
++
++#define simple_strtol strtol
++
++/* registering symbols */
++#ifndef ERESTARTSYS
++#define ERESTARTSYS ERESTART
++#endif
++#define HZ 1
++
++/* random */
++
++void get_random_bytes(void *ptr, int size);
++
++/* memory */
++
++/* memory size: used for some client tunables */
++#define num_physpages (256 * 1024) /* 1GB */
++
++static inline int copy_from_user(void *a,void *b, int c)
++{
++ memcpy(a,b,c);
++ return 0;
++}
++
++static inline int copy_to_user(void *a,void *b, int c)
++{
++ memcpy(a,b,c);
++ return 0;
++}
++
++
++/* slabs */
++typedef struct {
++ int size;
++} kmem_cache_t;
++#define SLAB_HWCACHE_ALIGN 0
++static inline kmem_cache_t *
++kmem_cache_create(const char *name, size_t objsize, size_t cdum,
++ unsigned long d,
++ void (*e)(void *, kmem_cache_t *, unsigned long),
++ void (*f)(void *, kmem_cache_t *, unsigned long))
++{
++ kmem_cache_t *c;
++ c = malloc(sizeof(*c));
++ if (!c)
++ return NULL;
++ c->size = objsize;
++ CDEBUG(D_MALLOC, "alloc slab cache %s at %p, objsize %d\n",
++ name, c, (int)objsize);
++ return c;
++};
++
++static inline int kmem_cache_destroy(kmem_cache_t *a)
++{
++ CDEBUG(D_MALLOC, "destroy slab cache %p, objsize %u\n", a, a->size);
++ free(a);
++ return 0;
++}
++
++/* struct page decl moved out from here into portals/include/libcfs/user-prim.h */
++
++/* 2.4 defines */
++#define PAGE_LIST_ENTRY list
++#define PAGE_LIST(page) ((page)->list)
++
++#define kmap(page) (page)->addr
++#define kunmap(a) do {} while (0)
++
++static inline cfs_page_t *alloc_pages(int mask, unsigned long order)
++{
++ cfs_page_t *pg = malloc(sizeof(*pg));
++
++ if (!pg)
++ return NULL;
++#if 0 //#ifdef MAP_ANONYMOUS
++ pg->addr = mmap(0, PAGE_SIZE << order, PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
++#else
++ pg->addr = malloc(CFS_PAGE_SIZE << order);
++#endif
++
++ if (!pg->addr) {
++ free(pg);
++ return NULL;
++ }
++ return pg;
++}
++#define cfs_alloc_pages(mask, order) alloc_pages((mask), (order))
++
++#define alloc_page(mask) alloc_pages((mask), 0)
++#define cfs_alloc_page(mask) alloc_page(mask)
++
++static inline void __free_pages(cfs_page_t *pg, int what)
++{
++#if 0 //#ifdef MAP_ANONYMOUS
++ munmap(pg->addr, PAGE_SIZE);
++#else
++ free(pg->addr);
++#endif
++ free(pg);
++}
++#define __cfs_free_pages(pg, order) __free_pages((pg), (order))
++
++#define __free_page(page) __free_pages((page), 0)
++#define free_page(page) __free_page(page)
++#define __cfs_free_page(page) __cfs_free_pages((page), 0)
++
++static inline cfs_page_t* __grab_cache_page(unsigned long index)
++{
++ cfs_page_t *pg = alloc_pages(0, 0);
++
++ if (pg)
++ pg->index = index;
++ return pg;
++}
++
++#define grab_cache_page(index) __grab_cache_page(index)
++#define page_cache_release(page) __free_pages(page, 0)
++
++/* arithmetic */
++#define do_div(a,b) \
++ ({ \
++ unsigned long remainder;\
++ remainder = (a) % (b); \
++ (a) = (a) / (b); \
++ (remainder); \
++ })
++
++/* VFS stuff */
++#define ATTR_MODE 0x0001
++#define ATTR_UID 0x0002
++#define ATTR_GID 0x0004
++#define ATTR_SIZE 0x0008
++#define ATTR_ATIME 0x0010
++#define ATTR_MTIME 0x0020
++#define ATTR_CTIME 0x0040
++#define ATTR_ATIME_SET 0x0080
++#define ATTR_MTIME_SET 0x0100
++#define ATTR_FORCE 0x0200 /* Not a change, but a change it */
++#define ATTR_ATTR_FLAG 0x0400
++#define ATTR_RAW 0x0800 /* file system, not vfs will massage attrs */
++#define ATTR_FROM_OPEN 0x1000 /* called from open path, ie O_TRUNC */
++#define ATTR_CTIME_SET 0x2000
++#define ATTR_KILL_SUID 0
++#define ATTR_KILL_SGID 0
++
++struct iattr {
++ unsigned int ia_valid;
++ umode_t ia_mode;
++ uid_t ia_uid;
++ gid_t ia_gid;
++ loff_t ia_size;
++ time_t ia_atime;
++ time_t ia_mtime;
++ time_t ia_ctime;
++ unsigned int ia_attr_flags;
++};
++#define ll_iattr_struct iattr
++
++#define IT_OPEN 0x0001
++#define IT_CREAT 0x0002
++#define IT_READDIR 0x0004
++#define IT_GETATTR 0x0008
++#define IT_LOOKUP 0x0010
++#define IT_UNLINK 0x0020
++#define IT_GETXATTR 0x0040
++#define IT_EXEC 0x0080
++#define IT_PIN 0x0100
++
++#define IT_FL_LOCKED 0x0001
++#define IT_FL_FOLLOWED 0x0002 /* set by vfs_follow_link */
++
++#define INTENT_MAGIC 0x19620323
++
++struct lustre_intent_data {
++ int it_disposition;
++ int it_status;
++ __u64 it_lock_handle;
++ void *it_data;
++ int it_lock_mode;
++ int it_int_flags;
++};
++struct lookup_intent {
++ int it_magic;
++ void (*it_op_release)(struct lookup_intent *);
++ int it_op;
++ int it_flags;
++ int it_create_mode;
++ union {
++ struct lustre_intent_data lustre;
++ } d;
++};
++
++static inline void intent_init(struct lookup_intent *it, int op, int flags)
++{
++ memset(it, 0, sizeof(*it));
++ it->it_magic = INTENT_MAGIC;
++ it->it_op = op;
++ it->it_flags = flags;
++}
++
++
++struct dentry {
++ int d_count;
++};
++
++struct vfsmount {
++ void *pwd;
++};
++
++/* semaphores */
++struct rw_semaphore {
++ int count;
++};
++
++/* semaphores */
++struct semaphore {
++ int count;
++};
++
++/* use the macro's argument to avoid unused warnings */
++#define down(a) do { (void)a; } while (0)
++#define mutex_down(a) down(a)
++#define up(a) do { (void)a; } while (0)
++#define mutex_up(a) up(a)
++#define down_read(a) do { (void)a; } while (0)
++#define up_read(a) do { (void)a; } while (0)
++#define down_write(a) do { (void)a; } while (0)
++#define up_write(a) do { (void)a; } while (0)
++#define sema_init(a,b) do { (void)a; } while (0)
++#define init_rwsem(a) do { (void)a; } while (0)
++#define DECLARE_MUTEX(name) \
++ struct semaphore name = { 1 }
++static inline void init_MUTEX (struct semaphore *sem)
++{
++ sema_init(sem, 1);
++}
++static inline void init_MUTEX_LOCKED (struct semaphore *sem)
++{
++ sema_init(sem, 0);
++}
++
++#define init_mutex(s) init_MUTEX(s)
++
++typedef struct {
++ struct list_head sleepers;
++} wait_queue_head_t;
++
++typedef struct {
++ struct list_head sleeping;
++ void *process;
++} wait_queue_t;
++
++struct signal {
++ int signal;
++};
++
++struct task_struct {
++ int state;
++ struct signal pending;
++ char comm[32];
++ int pid;
++ int fsuid;
++ int fsgid;
++ int max_groups;
++ int ngroups;
++ gid_t *groups;
++ cfs_cap_t cap_effective;
++};
++
++typedef struct task_struct cfs_task_t;
++#define cfs_current() current
++#define cfs_curproc_pid() (current->pid)
++#define cfs_curproc_comm() (current->comm)
++
++extern struct task_struct *current;
++int in_group_p(gid_t gid);
++
++#define set_current_state(foo) do { current->state = foo; } while (0)
++
++#define init_waitqueue_entry(q,p) do { (q)->process = p; } while (0)
++#define add_wait_queue(q,p) do { list_add(&(q)->sleepers, &(p)->sleeping); } while (0)
++#define del_wait_queue(p) do { list_del(&(p)->sleeping); } while (0)
++#define remove_wait_queue(q,p) do { list_del(&(p)->sleeping); } while (0)
++
++#define DECLARE_WAIT_QUEUE_HEAD(HEAD) \
++ wait_queue_head_t HEAD = { \
++ .sleepers = CFS_LIST_HEAD_INIT(HEAD.sleepers) \
++ }
++#define init_waitqueue_head(l) CFS_INIT_LIST_HEAD(&(l)->sleepers)
++#define wake_up(l) do { int a = 0; a++; } while (0)
++#define TASK_INTERRUPTIBLE 0
++#define TASK_UNINTERRUPTIBLE 1
++#define TASK_RUNNING 2
++
++#define wait_event_interruptible(wq, condition) \
++({ \
++ struct l_wait_info lwi; \
++ int timeout = 100000000;/* for ever */ \
++ int ret; \
++ \
++ lwi = LWI_TIMEOUT(timeout, NULL, NULL); \
++ ret = l_wait_event(NULL, condition, &lwi); \
++ \
++ ret; \
++})
++
++#define in_interrupt() (0)
++
++#define schedule() do {} while (0)
++static inline int schedule_timeout(signed long t)
++{
++ return 0;
++}
++
++#define lock_kernel() do {} while (0)
++#define unlock_kernel() do {} while (0)
++#define daemonize(l) do {} while (0)
++#define sigfillset(l) do {} while (0)
++#define recalc_sigpending(l) do {} while (0)
++#define kernel_thread(l,m,n) LBUG()
++
++#define USERMODEHELPER(path, argv, envp) (0)
++#define SIGNAL_MASK_ASSERT()
++#define KERN_INFO
++
++#include <sys/time.h>
++#if HZ != 1
++#error "liblustre's jiffies currently expects HZ to be 1"
++#endif
++#define jiffies \
++({ \
++ unsigned long _ret = 0; \
++ struct timeval tv; \
++ if (gettimeofday(&tv, NULL) == 0) \
++ _ret = tv.tv_sec; \
++ _ret; \
++})
++#define get_jiffies_64() (__u64)jiffies
++#define time_after(a, b) ((long)(b) - (long)(a) < 0)
++#define time_before(a, b) time_after(b,a)
++#define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0)
++
++struct timer_list {
++ struct list_head tl_list;
++ void (*function)(unsigned long unused);
++ unsigned long data;
++ long expires;
++};
++
++static inline int timer_pending(struct timer_list *l)
++{
++ if (time_after(l->expires, jiffies))
++ return 1;
++ else
++ return 0;
++}
++
++static inline int init_timer(struct timer_list *l)
++{
++ CFS_INIT_LIST_HEAD(&l->tl_list);
++ return 0;
++}
++
++static inline void mod_timer(struct timer_list *l, int thetime)
++{
++ l->expires = thetime;
++}
++
++static inline void del_timer(struct timer_list *l)
++{
++ free(l);
++}
++
++typedef struct { volatile int counter; } atomic_t;
++
++#define ATOMIC_INIT(i) { i }
++
++#define atomic_read(a) ((a)->counter)
++#define atomic_set(a,b) do {(a)->counter = b; } while (0)
++#define atomic_dec_and_test(a) ((--((a)->counter)) == 0)
++#define atomic_dec_and_lock(a,b) ((--((a)->counter)) == 0)
++#define atomic_inc(a) (((a)->counter)++)
++#define atomic_dec(a) do { (a)->counter--; } while (0)
++#define atomic_add(b,a) do {(a)->counter += b;} while (0)
++#define atomic_add_return(n,a) ((a)->counter += n)
++#define atomic_inc_return(a) atomic_add_return(1,a)
++#define atomic_sub(b,a) do {(a)->counter -= b;} while (0)
++#define atomic_sub_return(n,a) ((a)->counter -= n)
++#define atomic_dec_return(a) atomic_sub_return(1,a)
++
++#ifndef likely
++#define likely(exp) (exp)
++#endif
++#ifndef unlikely
++#define unlikely(exp) (exp)
++#endif
++
++/* FIXME sys/capability will finally included linux/fs.h thus
++ * cause numerous trouble on x86-64. as temporary solution for
++ * build broken at cary, we copy definition we need from capability.h
++ * FIXME
++ */
++struct _cap_struct;
++typedef struct _cap_struct *cap_t;
++typedef int cap_value_t;
++typedef enum {
++ CAP_EFFECTIVE=0,
++ CAP_PERMITTED=1,
++ CAP_INHERITABLE=2
++} cap_flag_t;
++typedef enum {
++ CAP_CLEAR=0,
++ CAP_SET=1
++} cap_flag_value_t;
++
++cap_t cap_get_proc(void);
++int cap_get_flag(cap_t, cap_value_t, cap_flag_t, cap_flag_value_t *);
++
++static inline void libcfs_run_lbug_upcall(char *file, const char *fn,
++ const int l){}
++
++/* completion */
++struct completion {
++ unsigned int done;
++ cfs_waitq_t wait;
++};
++
++#define COMPLETION_INITIALIZER(work) \
++ { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
++
++#define DECLARE_COMPLETION(work) \
++ struct completion work = COMPLETION_INITIALIZER(work)
++
++#define INIT_COMPLETION(x) ((x).done = 0)
++
++static inline void init_completion(struct completion *x)
++{
++ x->done = 0;
++ init_waitqueue_head(&x->wait);
++}
++
++struct liblustre_wait_callback {
++ struct list_head llwc_list;
++ const char *llwc_name;
++ int (*llwc_fn)(void *arg);
++ void *llwc_arg;
++};
++
++void *liblustre_register_wait_callback(const char *name,
++ int (*fn)(void *arg), void *arg);
++void liblustre_deregister_wait_callback(void *notifier);
++int liblustre_wait_event(int timeout);
++
++void *liblustre_register_idle_callback(const char *name,
++ int (*fn)(void *arg), void *arg);
++void liblustre_deregister_idle_callback(void *notifier);
++void liblustre_wait_idle(void);
++
++/* flock related */
++struct nfs_lock_info {
++ __u32 state;
++ __u32 flags;
++ void *host;
++};
++
++typedef struct file_lock {
++ struct file_lock *fl_next; /* singly linked list for this inode */
++ struct list_head fl_link; /* doubly linked list of all locks */
++ struct list_head fl_block; /* circular list of blocked processes */
++ void *fl_owner;
++ unsigned int fl_pid;
++ cfs_waitq_t fl_wait;
++ struct file *fl_file;
++ unsigned char fl_flags;
++ unsigned char fl_type;
++ loff_t fl_start;
++ loff_t fl_end;
++
++ void (*fl_notify)(struct file_lock *); /* unblock callback */
++ void (*fl_insert)(struct file_lock *); /* lock insertion callback */
++ void (*fl_remove)(struct file_lock *); /* lock removal callback */
++
++ void *fl_fasync; /* for lease break notifications */
++ unsigned long fl_break_time; /* for nonblocking lease breaks */
++
++ union {
++ struct nfs_lock_info nfs_fl;
++ } fl_u;
++} cfs_flock_t;
++
++#define cfs_flock_type(fl) ((fl)->fl_type)
++#define cfs_flock_set_type(fl, type) do { (fl)->fl_type = (type); } while(0)
++#define cfs_flock_pid(fl) ((fl)->fl_pid)
++#define cfs_flock_set_pid(fl, pid) do { (fl)->fl_pid = (pid); } while(0)
++#define cfs_flock_start(fl) ((fl)->fl_start)
++#define cfs_flock_set_start(fl, start) do { (fl)->fl_start = (start); } while(0)
++#define cfs_flock_end(fl) ((fl)->fl_end)
++#define cfs_flock_set_end(fl, end) do { (fl)->fl_end = (end); } while(0)
++
++#ifndef OFFSET_MAX
++#define INT_LIMIT(x) (~((x)1 << (sizeof(x)*8 - 1)))
++#define OFFSET_MAX INT_LIMIT(loff_t)
++#endif
++
++/* XXX: defined in kernel */
++#define FL_POSIX 1
++#define FL_SLEEP 128
++
++/* quota */
++#define QUOTA_OK 0
++#define NO_QUOTA 1
++
++/* ACL */
++struct posix_acl_entry {
++ short e_tag;
++ unsigned short e_perm;
++ unsigned int e_id;
++};
++
++struct posix_acl {
++ atomic_t a_refcount;
++ unsigned int a_count;
++ struct posix_acl_entry a_entries[0];
++};
++
++typedef struct {
++ __u16 e_tag;
++ __u16 e_perm;
++ __u32 e_id;
++} xattr_acl_entry;
++
++typedef struct {
++ __u32 a_version;
++ xattr_acl_entry a_entries[0];
++} xattr_acl_header;
++
++static inline size_t xattr_acl_size(int count)
++{
++ return sizeof(xattr_acl_header) + count * sizeof(xattr_acl_entry);
++}
++
++static inline
++struct posix_acl * posix_acl_from_xattr(const void *value, size_t size)
++{
++ return NULL;
++}
++
++static inline
++int posix_acl_valid(const struct posix_acl *acl)
++{
++ return 0;
++}
++
++static inline
++void posix_acl_release(struct posix_acl *acl)
++{
++}
++
++#ifdef LIBLUSTRE_POSIX_ACL
++ #ifndef posix_acl_xattr_entry
++ #define posix_acl_xattr_entry xattr_acl_entry
++ #endif
++ #ifndef posix_acl_xattr_header
++ #define posix_acl_xattr_header xattr_acl_header
++ #endif
++ #ifndef posix_acl_xattr_size
++ #define posix_acl_xattr_size(entry) xattr_acl_size(entry)
++ #endif
++ #ifndef CONFIG_FS_POSIX_ACL
++ #define CONFIG_FS_POSIX_ACL 1
++ #endif
++#endif
++
++#ifndef ENOTSUPP
++#define ENOTSUPP ENOTSUP
++#endif
++
++#include <obd_support.h>
++#include <lustre/lustre_idl.h>
++#include <lustre_lib.h>
++#include <lustre_import.h>
++#include <lustre_export.h>
++#include <lustre_net.h>
++
++#endif
diff -urNad lustre~/lustre/include/linux/lustre_compat25.h lustre/lustre/include/linux/lustre_compat25.h
---- lustre~/lustre/include/linux/lustre_compat25.h 2009-03-12 10:33:45.000000000 +0100
-+++ lustre/lustre/include/linux/lustre_compat25.h 2009-03-13 09:45:02.000000000 +0100
+--- lustre~/lustre/include/linux/lustre_compat25.h 2009-08-19 09:51:08.000000000 +0200
++++ lustre/lustre/include/linux/lustre_compat25.h 2009-08-19 10:46:25.000000000 +0200
+@@ -44,8 +44,8 @@
+ #endif
+
+ #include <libcfs/linux/portals_compat25.h>
+-
+ #include <linux/lustre_patchless_compat.h>
++#include <linux/fs_struct.h>
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
+ struct ll_iattr_struct {
@@ -57,6 +57,28 @@
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) */
@@ -2552,7 +3933,23 @@ diff -urNad lustre~/lustre/include/linux/lustre_compat25.h lustre/lustre/include
#else
#define ll_set_fs_pwd set_fs_pwd
#endif /* HAVE_SET_FS_PWD */
-@@ -151,7 +174,12 @@
+@@ -121,8 +144,13 @@
+ void groups_free(struct group_info *ginfo);
+ #else /* >= 2.6.4 */
+
+-#define current_ngroups current->group_info->ngroups
+-#define current_groups current->group_info->small_block
++# ifdef HAS_STRUCT_CRED
++# define current_ngroups current->real_cred->group_info->ngroups
++# define current_groups current->real_cred->group_info->small_block
++# else
++# define current_ngroups current->group_info->ngroups
++# define current_groups current->group_info->small_block
++# endif
+
+ #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) */
+
+@@ -151,7 +179,12 @@
#endif
/* XXX our code should be using the 2.6 calls, not the other way around */
@@ -2565,7 +3962,7 @@ diff -urNad lustre~/lustre/include/linux/lustre_compat25.h lustre/lustre/include
#define Page_Uptodate(page) PageUptodate(page)
#define ll_redirty_page(page) set_page_dirty(page)
-@@ -364,8 +392,17 @@
+@@ -364,8 +397,17 @@
#define LL_RENAME_DOES_D_MOVE FS_ODD_RENAME
#endif
@@ -2584,7 +3981,7 @@ diff -urNad lustre~/lustre/include/linux/lustre_compat25.h lustre/lustre/include
#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)
-@@ -377,7 +414,6 @@
+@@ -377,7 +419,6 @@
#define ll_vfs_rename(old,old_dir,mnt,new,new_dir,mnt1) \
vfs_rename(old,old_dir,mnt,new,new_dir,mnt1)
#else
@@ -2592,7 +3989,7 @@ diff -urNad lustre~/lustre/include/linux/lustre_compat25.h lustre/lustre/include
#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)
-@@ -388,6 +424,57 @@
+@@ -388,6 +429,57 @@
vfs_rename(old,old_dir,new,new_dir)
#endif
@@ -2651,8 +4048,8 @@ diff -urNad lustre~/lustre/include/linux/lustre_compat25.h lustre/lustre/include
static inline int abs(int x)
{
diff -urNad lustre~/lustre/include/linux/lustre_compat25.h.orig lustre/lustre/include/linux/lustre_compat25.h.orig
---- lustre~/lustre/include/linux/lustre_compat25.h.orig 1970-01-01 00:00:00.000000000 +0000
-+++ lustre/lustre/include/linux/lustre_compat25.h.orig 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/include/linux/lustre_compat25.h.orig 1970-01-01 01:00:00.000000000 +0100
++++ lustre/lustre/include/linux/lustre_compat25.h.orig 2009-08-19 10:40:29.000000000 +0200
@@ -0,0 +1,411 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -3066,8 +4463,8 @@ diff -urNad lustre~/lustre/include/linux/lustre_compat25.h.orig lustre/lustre/in
+#endif /* __KERNEL__ */
+#endif /* _COMPAT25_H */
diff -urNad lustre~/lustre/include/linux/lustre_lib.h lustre/lustre/include/linux/lustre_lib.h
---- lustre~/lustre/include/linux/lustre_lib.h 2008-08-07 11:52:06.000000000 +0200
-+++ lustre/lustre/include/linux/lustre_lib.h 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/include/linux/lustre_lib.h 2009-08-19 09:51:08.000000000 +0200
++++ lustre/lustre/include/linux/lustre_lib.h 2009-08-19 10:40:29.000000000 +0200
@@ -49,7 +49,6 @@
# include <string.h>
# include <sys/types.h>
@@ -3077,8 +4474,8 @@ diff -urNad lustre~/lustre/include/linux/lustre_lib.h lustre/lustre/include/linu
# include <linux/sched.h>
# include <linux/signal.h>
diff -urNad lustre~/lustre/include/linux/lustre_patchless_compat.h lustre/lustre/include/linux/lustre_patchless_compat.h
---- lustre~/lustre/include/linux/lustre_patchless_compat.h 2008-08-07 11:52:10.000000000 +0200
-+++ lustre/lustre/include/linux/lustre_patchless_compat.h 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/include/linux/lustre_patchless_compat.h 2009-08-19 09:51:08.000000000 +0200
++++ lustre/lustre/include/linux/lustre_patchless_compat.h 2009-08-19 10:40:29.000000000 +0200
@@ -52,7 +52,7 @@
BUG_ON(!PageLocked(page));
@@ -3098,8 +4495,8 @@ diff -urNad lustre~/lustre/include/linux/lustre_patchless_compat.h lustre/lustre
#else
spin_unlock_irq(&mapping->tree_lock);
diff -urNad lustre~/lustre/include/lprocfs_status.h lustre/lustre/include/lprocfs_status.h
---- lustre~/lustre/include/lprocfs_status.h 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/include/lprocfs_status.h 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/include/lprocfs_status.h 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/include/lprocfs_status.h 2009-08-19 10:40:29.000000000 +0200
@@ -521,6 +521,8 @@
#define LPROCFS_EXIT() do { \
up_read(&_lprocfs_lock); \
@@ -3133,8 +4530,8 @@ diff -urNad lustre~/lustre/include/lprocfs_status.h lustre/lustre/include/lprocf
* the import in a client obd_device for a lprocfs entry */
#define LPROCFS_CLIMP_CHECK(obd) do { \
diff -urNad lustre~/lustre/include/lprocfs_status.h.orig lustre/lustre/include/lprocfs_status.h.orig
---- lustre~/lustre/include/lprocfs_status.h.orig 1970-01-01 00:00:00.000000000 +0000
-+++ lustre/lustre/include/lprocfs_status.h.orig 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/include/lprocfs_status.h.orig 1970-01-01 01:00:00.000000000 +0100
++++ lustre/lustre/include/lprocfs_status.h.orig 2009-08-19 10:40:29.000000000 +0200
@@ -0,0 +1,817 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -3953,10 +5350,237 @@ diff -urNad lustre~/lustre/include/lprocfs_status.h.orig lustre/lustre/include/l
+#endif /* LPROCFS */
+
+#endif /* LPROCFS_SNMP_H */
+diff -urNad lustre~/lustre/include/lustre/ll_fiemap.h lustre/lustre/include/lustre/ll_fiemap.h
+--- lustre~/lustre/include/lustre/ll_fiemap.h 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/include/lustre/ll_fiemap.h 2009-08-19 10:46:25.000000000 +0200
+@@ -109,8 +109,45 @@
+
+ #else
+
++# ifndef FIEMAP_FLAG_DEVICE_ORDER
++/* dirty hack, but obviously lustre requires and serves FIEMAP_FLAG_DEVICE_ORDER */
++# define FIEMAP_FLAG_DEVICE_ORDER 0x40000000 /* return device ordered mapping */
++# undef FIEMAP_FLAGS_COMPAT
++# define FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC | FIEMAP_FLAG_XATTR | \
++ FIEMAP_FLAG_DEVICE_ORDER)
++# endif
++
++#define FIEMAP_EXTENT_NET 0x00000020 /* Data stored remotely.
++ * Sets EXTENT_NO_DIRECT. */
++
++struct ll_fiemap_extent {
++ __u64 fe_logical; /* logical offset in bytes for the start of
++ * the extent from the beginning of the file */
++ __u64 fe_physical; /* physical offset in bytes for the start
++ * of the extent from the beginning of the disk */
++ __u64 fe_length; /* length in bytes for the extent */
++ __u32 fe_flags; /* FIEMAP_EXTENT_* flags for the extent */
++ __u32 fe_device; /* device number for this extent */
++};
++
++struct ll_user_fiemap {
++ __u64 fm_start; /* logical offset (inclusive) at
++ * which to start mapping (in) */
++ __u64 fm_length; /* logical length of mapping which
++ * userspace wants (in) */
++ __u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */
++ __u32 fm_mapped_extents;/* number of extents that were mapped (out) */
++ __u32 fm_extent_count; /* size of fm_extents array (in) */
++ __u32 fm_reserved;
++ struct ll_fiemap_extent fm_extents[0]; /* array of mapped extents (out).
++ * Lustre uses first extent to
++ * send end_offset */
++};
++
++/*
+ #define ll_fiemap_extent fiemap_extent
+ #define ll_user_fiemap fiemap
++*/
+
+ #endif /* HAVE_LINUX_FIEMAP_H */
+
+diff -urNad lustre~/lustre/liblustre/lutil.c lustre/lustre/liblustre/lutil.c
+--- lustre~/lustre/liblustre/lutil.c 2009-08-11 12:37:07.000000000 +0200
++++ lustre/lustre/liblustre/lutil.c 2009-08-19 10:46:25.000000000 +0200
+@@ -184,7 +184,11 @@
+ {
+ int i;
+
++#ifdef HAS_STRUCT_CRED
++ if (gid == current->real_cred->fsgid)
++#else
+ if (gid == current->fsgid)
++#endif
+ return 1;
+
+ for (i = 0; i < current->ngroups; i++) {
+@@ -205,8 +209,13 @@
+
+ strncpy(current->comm, comm, sizeof(current->comm));
+ current->pid = getpid();
++#ifdef HAS_STRUCT_CRED
++ current->real_cred->fsuid = geteuid();
++ current->real_cred->fsgid = getegid();
++#else
+ current->fsuid = geteuid();
+ current->fsgid = getegid();
++#endif
+ memset(¤t->pending, 0, sizeof(current->pending));
+
+ current->max_groups = sysconf(_SC_NGROUPS_MAX);
+@@ -221,24 +230,40 @@
+ return -EINVAL;
+ }
+
++#ifdef HAS_STRUCT_CRED
++ init_capability(¤t->real_cred->cap_effective);
++#else
+ init_capability(¤t->cap_effective);
++#endif
+
+ return 0;
+ }
+
+ void cfs_cap_raise(cfs_cap_t cap)
+ {
++#ifdef HAS_STRUCT_CRED
++ current->real_cred->cap_effective |= (1 << cap);
++#else
+ current->cap_effective |= (1 << cap);
++#endif
+ }
+
+ void cfs_cap_lower(cfs_cap_t cap)
+ {
++#ifdef HAS_STRUCT_CRED
++ current->real_cred->cap_effective &= ~(1 << cap);
++#else
+ current->cap_effective &= ~(1 << cap);
++#endif
+ }
+
+ int cfs_cap_raised(cfs_cap_t cap)
+ {
++#ifdef HAS_STRUCT_CRED
++ return current->real_cred->cap_effective & (1 << cap);
++#else
+ return current->cap_effective & (1 << cap);
++#endif
+ }
+
+ void cfs_kernel_cap_pack(cfs_kernel_cap_t kcap, cfs_cap_t *cap)
+@@ -253,12 +278,20 @@
+
+ cfs_cap_t cfs_curproc_cap_pack(void) {
+ cfs_cap_t cap;
++#ifdef HAS_STRUCT_CRED
++ cfs_kernel_cap_pack(cfs_current()->real_cred->cap_effective, &cap);
++#else
+ cfs_kernel_cap_pack(cfs_current()->cap_effective, &cap);
++#endif
+ return cap;
+ }
+
+ void cfs_curproc_cap_unpack(cfs_cap_t cap) {
++#ifdef HAS_STRUCT_CRED
++ cfs_kernel_cap_unpack(&cfs_current()->real_cred->cap_effective, cap);
++#else
+ cfs_kernel_cap_unpack(&cfs_current()->cap_effective, cap);
++#endif
+ }
+
+ int cfs_capable(cfs_cap_t cap)
+diff -urNad lustre~/lustre/liblustre/super.c lustre/lustre/liblustre/super.c
+--- lustre~/lustre/liblustre/super.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/liblustre/super.c 2009-08-19 10:46:25.000000000 +0200
+@@ -82,7 +82,11 @@
+ struct intnl_stat *st = llu_i2stat(inode);
+ mode_t mode = st->st_mode;
+
++#ifdef HAS_STRUCT_CRED
++ if (current->real_cred->fsuid == st->st_uid)
++#else
+ if (current->fsuid == st->st_uid)
++#endif
+ mode >>= 6;
+ else if (in_group_p(st->st_gid))
+ mode >>= 3;
+@@ -731,12 +735,20 @@
+ if (ia_valid & (ATTR_MTIME | ATTR_ATIME)) {
+ /* from sys_utime() */
+ if (!(ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET))) {
++#ifdef HAS_STRUCT_CRED
++ if (current->real_cred->fsuid != st->st_uid &&
++#else
+ if (current->fsuid != st->st_uid &&
++#endif
+ (rc = ll_permission(inode, MAY_WRITE)) != 0)
+ RETURN(rc);
+ } else {
+ /* from inode_change_ok() */
++#ifdef HAS_STRUCT_CRED
++ if (current->real_cred->fsuid != st->st_uid &&
++#else
+ if (current->fsuid != st->st_uid &&
++#endif
+ !cfs_capable(CFS_CAP_FOWNER))
+ RETURN(-EPERM);
+ }
+@@ -889,7 +901,11 @@
+
+ llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
+ err = mdc_create(sbi->ll_mdc_exp, &op_data, tgt, strlen(tgt) + 1,
++#ifdef HAS_STRUCT_CRED
++ S_IFLNK | S_IRWXUGO, current->real_cred->fsuid, current->real_cred->fsgid,
++#else
+ S_IFLNK | S_IRWXUGO, current->fsuid, current->fsgid,
++#endif
+ cfs_curproc_cap_pack(), 0, &request);
+ ptlrpc_req_finished(request);
+ liblustre_wait_event(0);
+@@ -1018,7 +1034,11 @@
+ pno->p_base->pb_name.len,
+ 0);
+ err = mdc_create(sbi->ll_mdc_exp, &op_data, NULL, 0, mode,
++#ifdef HAS_STRUCT_CRED
++ current->real_cred->fsuid, current->real_cred->fsgid,
++#else
+ current->fsuid, current->fsgid,
++#endif
+ cfs_curproc_cap_pack(), dev, &request);
+ ptlrpc_req_finished(request);
+ break;
+@@ -1248,7 +1268,11 @@
+
+ llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
+ err = mdc_create(llu_i2sbi(dir)->ll_mdc_exp, &op_data, NULL, 0,
++#ifdef HAS_STRUCT_CRED
++ mode | S_IFDIR, current->real_cred->fsuid, current->real_cred->fsgid,
++#else
+ mode | S_IFDIR, current->fsuid, current->fsgid,
++#endif
+ cfs_curproc_cap_pack(), 0, &request);
+ ptlrpc_req_finished(request);
+ liblustre_wait_event(0);
+diff -urNad lustre~/lustre/llite/dir.c lustre/lustre/llite/dir.c
+--- lustre~/lustre/llite/dir.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/llite/dir.c 2009-08-19 10:46:25.000000000 +0200
+@@ -955,7 +955,11 @@
+ GOTO(out_quotactl, rc = -EPERM);
+ break;
+ case Q_GETQUOTA:
++#ifdef HAS_STRUCT_CRED
++ if (((type == USRQUOTA && current->real_cred->euid != id) ||
++#else
+ if (((type == USRQUOTA && current->euid != id) ||
++#endif
+ (type == GRPQUOTA && !in_egroup_p(id))) &&
+ !cfs_capable(CFS_CAP_SYS_ADMIN))
+ GOTO(out_quotactl, rc = -EPERM);
diff -urNad lustre~/lustre/llite/file.c lustre/lustre/llite/file.c
---- lustre~/lustre/llite/file.c 2009-03-13 09:45:02.000000000 +0100
-+++ lustre/lustre/llite/file.c 2009-03-13 09:45:03.000000000 +0100
-@@ -1801,11 +1801,12 @@
+--- lustre~/lustre/llite/file.c 2009-08-19 10:40:28.000000000 +0200
++++ lustre/lustre/llite/file.c 2009-08-19 10:40:29.000000000 +0200
+@@ -1817,11 +1817,12 @@
#endif
}
@@ -3971,7 +5595,7 @@ diff -urNad lustre~/lustre/llite/file.c lustre/lustre/llite/file.c
{
struct inode *inode = in_file->f_dentry->d_inode;
struct ll_inode_info *lli = ll_i2info(inode);
-@@ -1814,10 +1815,10 @@
+@@ -1830,10 +1831,10 @@
struct ll_lock_tree_node *node;
struct ost_lvb lvb;
struct ll_ra_read bead;
@@ -3984,7 +5608,7 @@ diff -urNad lustre~/lustre/llite/file.c lustre/lustre/llite/file.c
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),size="LPSZ",offset=%Ld\n",
inode->i_ino, inode->i_generation, inode, count, *ppos);
-@@ -1831,8 +1832,10 @@
+@@ -1847,8 +1848,10 @@
in_file->f_ra.ra_pages = 0;
/* File with no objects, nothing to lock */
@@ -3997,7 +5621,7 @@ diff -urNad lustre~/lustre/llite/file.c lustre/lustre/llite/file.c
node = ll_node_from_inode(inode, *ppos, *ppos + count - 1, LCK_PR);
if (IS_ERR(node))
-@@ -1872,8 +1875,8 @@
+@@ -1888,8 +1891,8 @@
/* A glimpse is necessary to determine whether we return a
* short read (B) or some zeroes at the end of the buffer (C) */
ll_inode_size_unlock(inode, 1);
@@ -4008,7 +5632,7 @@ diff -urNad lustre~/lustre/llite/file.c lustre/lustre/llite/file.c
goto out;
} else {
/* region is within kms and, hence, within real file size (A) */
-@@ -1889,13 +1892,115 @@
+@@ -1905,13 +1908,115 @@
ll_ra_read_in(in_file, &bead);
/* BUG: 5972 */
file_accessed(in_file);
@@ -4126,7 +5750,7 @@ diff -urNad lustre~/lustre/llite/file.c lustre/lustre/llite/file.c
static int ll_lov_recreate_obj(struct inode *inode, struct file *file,
unsigned long arg)
-@@ -3084,7 +3189,11 @@
+@@ -3100,7 +3205,11 @@
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
@@ -4138,7 +5762,7 @@ diff -urNad lustre~/lustre/llite/file.c lustre/lustre/llite/file.c
{
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), mask %o\n",
inode->i_ino, inode->i_generation, inode, mask);
-@@ -3093,7 +3202,7 @@
+@@ -3109,7 +3218,7 @@
return generic_permission(inode, mask, lustre_check_acl);
}
#else
@@ -4147,7 +5771,7 @@ diff -urNad lustre~/lustre/llite/file.c lustre/lustre/llite/file.c
int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
#else
int ll_inode_permission(struct inode *inode, int mask)
-@@ -3163,7 +3272,12 @@
+@@ -3179,7 +3288,12 @@
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
@@ -4160,7 +5784,7 @@ diff -urNad lustre~/lustre/llite/file.c lustre/lustre/llite/file.c
.fsync = ll_fsync,
};
-@@ -3185,7 +3299,12 @@
+@@ -3201,7 +3315,12 @@
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
@@ -4173,7 +5797,7 @@ diff -urNad lustre~/lustre/llite/file.c lustre/lustre/llite/file.c
.fsync = ll_fsync,
#ifdef HAVE_F_OP_FLOCK
.flock = ll_file_flock,
-@@ -3212,7 +3331,12 @@
+@@ -3228,7 +3347,12 @@
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
@@ -4187,8 +5811,8 @@ diff -urNad lustre~/lustre/llite/file.c lustre/lustre/llite/file.c
#ifdef HAVE_F_OP_FLOCK
.flock = ll_file_noflock,
diff -urNad lustre~/lustre/llite/file.c.orig lustre/lustre/llite/file.c.orig
---- lustre~/lustre/llite/file.c.orig 1970-01-01 00:00:00.000000000 +0000
-+++ lustre/lustre/llite/file.c.orig 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/llite/file.c.orig 1970-01-01 01:00:00.000000000 +0100
++++ lustre/lustre/llite/file.c.orig 2009-08-19 10:40:29.000000000 +0200
@@ -0,0 +1,3335 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -7526,9 +9150,23 @@ diff -urNad lustre~/lustre/llite/file.c.orig lustre/lustre/llite/file.c.orig
+ return ret;
+}
diff -urNad lustre~/lustre/llite/llite_internal.h lustre/lustre/llite/llite_internal.h
---- lustre~/lustre/llite/llite_internal.h 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/llite/llite_internal.h 2009-03-13 09:45:03.000000000 +0100
-@@ -647,7 +647,7 @@
+--- lustre~/lustre/llite/llite_internal.h 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/llite/llite_internal.h 2009-08-19 10:46:25.000000000 +0200
+@@ -596,8 +596,13 @@
+ void ll_lookup_finish_locks(struct lookup_intent *it, struct dentry *dentry);
+
+ /* llite/rw.c */
++#ifdef NO_PREPARE_WRITE
++int ll_write_begin(struct file *, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata);
++int ll_write_end(struct file *, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata);
++#else
+ int ll_prepare_write(struct file *, struct page *, unsigned from, unsigned to);
+ int ll_commit_write(struct file *, struct page *, unsigned from, unsigned to);
++#endif
+ int ll_writepage(struct page *page);
+ void ll_inode_fill_obdo(struct inode *inode, int cmd, struct obdo *oa);
+ int ll_ap_completion(void *data, int cmd, struct obdo *oa, int rc);
+@@ -647,7 +652,7 @@
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);
@@ -7537,7 +9175,7 @@ diff -urNad lustre~/lustre/llite/llite_internal.h lustre/lustre/llite/llite_inte
int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd);
#else
int ll_inode_permission(struct inode *inode, int mask);
-@@ -727,9 +727,6 @@
+@@ -727,9 +732,6 @@
/* llite/llite_nfs.c */
extern struct export_operations lustre_export_operations;
__u32 get_uuid2int(const char *name, int len);
@@ -7548,8 +9186,8 @@ diff -urNad lustre~/lustre/llite/llite_internal.h lustre/lustre/llite/llite_inte
/* llite/special.c */
extern struct inode_operations ll_special_inode_operations;
diff -urNad lustre~/lustre/llite/llite_internal.h.orig lustre/lustre/llite/llite_internal.h.orig
---- lustre~/lustre/llite/llite_internal.h.orig 1970-01-01 00:00:00.000000000 +0000
-+++ lustre/lustre/llite/llite_internal.h.orig 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/llite/llite_internal.h.orig 1970-01-01 01:00:00.000000000 +0100
++++ lustre/lustre/llite/llite_internal.h.orig 2009-08-19 10:40:29.000000000 +0200
@@ -0,0 +1,1027 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -8579,8 +10217,8 @@ diff -urNad lustre~/lustre/llite/llite_internal.h.orig lustre/lustre/llite/llite
+
+#endif /* LLITE_INTERNAL_H */
diff -urNad lustre~/lustre/llite/llite_lib.c lustre/lustre/llite/llite_lib.c
---- lustre~/lustre/llite/llite_lib.c 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/llite/llite_lib.c 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/llite/llite_lib.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/llite/llite_lib.c 2009-08-19 10:46:25.000000000 +0200
@@ -1346,7 +1346,7 @@
rc = vmtruncate(inode, new_size);
clear_bit(LLI_F_SRVLOCK, &lli->lli_flags);
@@ -8590,9 +10228,21 @@ diff -urNad lustre~/lustre/llite/llite_lib.c lustre/lustre/llite/llite_lib.c
ll_inode_size_unlock(inode, 0);
}
}
+@@ -1406,7 +1406,11 @@
+
+ /* POSIX: check before ATTR_*TIME_SET set (from inode_change_ok) */
+ if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) {
++#ifdef HAS_STRUCT_CRED
++ if (current->real_cred->fsuid != inode->i_uid &&
++#else
+ if (current->fsuid != inode->i_uid &&
++#endif
+ !cfs_capable(CFS_CAP_FOWNER))
+ RETURN(-EPERM);
+ }
diff -urNad lustre~/lustre/llite/llite_lib.c.orig lustre/lustre/llite/llite_lib.c.orig
---- lustre~/lustre/llite/llite_lib.c.orig 1970-01-01 00:00:00.000000000 +0000
-+++ lustre/lustre/llite/llite_lib.c.orig 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/llite/llite_lib.c.orig 1970-01-01 01:00:00.000000000 +0100
++++ lustre/lustre/llite/llite_lib.c.orig 2009-08-19 10:40:29.000000000 +0200
@@ -0,0 +1,2232 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -10827,8 +12477,8 @@ diff -urNad lustre~/lustre/llite/llite_lib.c.orig lustre/lustre/llite/llite_lib.
+ RETURN(0);
+}
diff -urNad lustre~/lustre/llite/llite_mmap.c lustre/lustre/llite/llite_mmap.c
---- lustre~/lustre/llite/llite_mmap.c 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/llite/llite_mmap.c 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/llite/llite_mmap.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/llite/llite_mmap.c 2009-08-19 10:40:29.000000000 +0200
@@ -81,8 +81,7 @@
int lt_get_mmap_locks(struct ll_lock_tree *tree,
unsigned long addr, size_t count);
@@ -11127,8 +12777,8 @@ diff -urNad lustre~/lustre/llite/llite_mmap.c lustre/lustre/llite/llite_mmap.c
filemap_populate = vma->vm_ops->populate;
#endif
diff -urNad lustre~/lustre/llite/llite_nfs.c lustre/lustre/llite/llite_nfs.c
---- lustre~/lustre/llite/llite_nfs.c 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/llite/llite_nfs.c 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/llite/llite_nfs.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/llite/llite_nfs.c 2009-08-19 10:46:25.000000000 +0200
@@ -68,36 +68,30 @@
}
@@ -11177,7 +12827,7 @@ diff -urNad lustre~/lustre/llite/llite_nfs.c lustre/lustre/llite/llite_nfs.c
RETURN(ERR_PTR(rc));
}
-@@ -111,27 +105,27 @@
+@@ -111,92 +105,143 @@
RETURN(inode);
}
@@ -11213,7 +12863,20 @@ diff -urNad lustre~/lustre/llite/llite_nfs.c lustre/lustre/llite/llite_nfs.c
iput(inode);
RETURN(ERR_PTR(-ESTALE));
}
-@@ -146,57 +140,102 @@
+
++#ifdef HAS_NO_D_ALLOC_ANON
++ result = d_obtain_alias(inode);
++ if (!IS_ERR(result))
++ ll_dops_init(result, 1);
++#else
+ result = d_alloc_anon(inode);
+ if (!result) {
+ iput(inode);
+ RETURN(ERR_PTR(-ENOMEM));
+ }
+ ll_dops_init(result, 1);
++#endif
+
RETURN(result);
}
@@ -11255,7 +12918,7 @@ diff -urNad lustre~/lustre/llite/llite_nfs.c lustre/lustre/llite/llite_nfs.c
+ struct lustre_nfs_fid *nfs_fid = (void *)fh;
+ ENTRY;
+
-+ CDEBUG(D_INFO, "encoding for (%lu) maxlen=%d minlen=%lu\n",
++ CDEBUG(D_INFO, "encoding for (%lu) maxlen=%d minlen=%u\n",
+ inode->i_ino, *plen,
+ sizeof(struct lustre_nfs_fid));
+
@@ -11300,7 +12963,7 @@ diff -urNad lustre~/lustre/llite/llite_nfs.c lustre/lustre/llite/llite_nfs.c
- *lenp = 3;
- return 1;
+ RETURN(ll_iget_for_nfs(sb, &nfs_fid->child));
-+}
+ }
+static struct dentry *ll_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
@@ -11309,9 +12972,8 @@ diff -urNad lustre~/lustre/llite/llite_nfs.c lustre/lustre/llite/llite_nfs.c
+ if (fh_type != LUSTRE_NFS_FID)
+ RETURN(ERR_PTR(-EINVAL));
+ RETURN(ll_iget_for_nfs(sb, &nfs_fid->parent));
- }
-
--#if THREAD_SIZE >= 8192
++}
++
+#else
+/*
+ * This length is counted as amount of __u32,
@@ -11338,7 +13000,8 @@ diff -urNad lustre~/lustre/llite/llite_nfs.c lustre/lustre/llite/llite_nfs.c
+ RETURN(entry);
+}
+
-+
+
+-#if THREAD_SIZE >= 8192
struct dentry *ll_get_dentry(struct super_block *sb, void *data)
{
- __u32 *inump = (__u32*)data;
@@ -11355,7 +13018,7 @@ diff -urNad lustre~/lustre/llite/llite_nfs.c lustre/lustre/llite/llite_nfs.c
struct dentry *ll_get_parent(struct dentry *dchild)
{
struct ptlrpc_request *req = NULL;
-@@ -208,11 +247,11 @@
+@@ -208,11 +253,11 @@
char dotdot[] = "..";
int rc = 0;
ENTRY;
@@ -11371,7 +13034,7 @@ diff -urNad lustre~/lustre/llite/llite_nfs.c lustre/lustre/llite/llite_nfs.c
fid.id = (__u64)dir->i_ino;
fid.generation = dir->i_generation;
fid.f_type = S_IFDIR;
-@@ -223,11 +262,12 @@
+@@ -223,11 +268,12 @@
CERROR("failure %d inode %lu get parent\n", rc, dir->i_ino);
return ERR_PTR(rc);
}
@@ -11388,7 +13051,7 @@ diff -urNad lustre~/lustre/llite/llite_nfs.c lustre/lustre/llite/llite_nfs.c
if (IS_ERR(result))
rc = PTR_ERR(result);
-@@ -236,10 +276,18 @@
+@@ -236,10 +282,18 @@
if (rc)
return ERR_PTR(rc);
RETURN(result);
@@ -11411,8 +13074,8 @@ diff -urNad lustre~/lustre/llite/llite_nfs.c lustre/lustre/llite/llite_nfs.c
};
#endif
diff -urNad lustre~/lustre/llite/lloop.c lustre/lustre/llite/lloop.c
---- lustre~/lustre/llite/lloop.c 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/llite/lloop.c 2009-03-13 09:45:45.000000000 +0100
+--- lustre~/lustre/llite/lloop.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/llite/lloop.c 2009-08-19 10:46:25.000000000 +0200
@@ -152,7 +152,7 @@
struct semaphore lo_bh_mutex;
atomic_t lo_pending;
@@ -11422,7 +13085,20 @@ diff -urNad lustre~/lustre/llite/lloop.c lustre/lustre/llite/lloop.c
/* data to handle bio for lustre. */
struct lo_request_data {
-@@ -283,7 +283,7 @@
+@@ -206,7 +206,12 @@
+ int ret, cmd, i;
+ struct bio_vec *bvec;
+
++#ifdef STRUCT_BIO_WO_HW_SEGMENTS
++ /* since 2.6.28 no bi_hw_segments */
++ BUG_ON(bio->bi_phys_segments > LLOOP_MAX_SEGMENTS);
++#else
+ BUG_ON(bio->bi_hw_segments > LLOOP_MAX_SEGMENTS);
++#endif
+
+ offset = (pgoff_t)(bio->bi_sector << 9) + lo->lo_offset;
+ bio_for_each_segment(bvec, bio, i) {
+@@ -283,7 +288,7 @@
return bio;
}
@@ -11431,7 +13107,7 @@ diff -urNad lustre~/lustre/llite/lloop.c lustre/lustre/llite/lloop.c
{
struct lloop_device *lo = q->queuedata;
int rw = bio_rw(old_bio);
-@@ -312,7 +312,7 @@
+@@ -312,7 +317,7 @@
if (atomic_dec_and_test(&lo->lo_pending))
up(&lo->lo_bh_mutex);
out:
@@ -11440,7 +13116,7 @@ diff -urNad lustre~/lustre/llite/lloop.c lustre/lustre/llite/lloop.c
return 0;
inactive:
spin_unlock_irq(&lo->lo_lock);
-@@ -322,7 +322,7 @@
+@@ -322,7 +327,7 @@
/*
* kick off io on the underlying address space
*/
@@ -11449,7 +13125,7 @@ diff -urNad lustre~/lustre/llite/lloop.c lustre/lustre/llite/lloop.c
{
struct lloop_device *lo = q->queuedata;
-@@ -334,7 +334,7 @@
+@@ -334,7 +339,7 @@
{
int ret;
ret = do_bio_filebacked(lo, bio);
@@ -11458,7 +13134,112 @@ diff -urNad lustre~/lustre/llite/lloop.c lustre/lustre/llite/lloop.c
}
/*
-@@ -736,7 +736,7 @@
+@@ -361,7 +366,8 @@
+ up(&lo->lo_sem);
+
+ for (;;) {
+- down_interruptible(&lo->lo_bh_mutex);
++ int i = down_interruptible(&lo->lo_bh_mutex);
++ if (i == 4711) break; /* that won't ever happen - just a tribute to -Werror */
+ /*
+ * could be upped because of tear-down, not because of
+ * pending work
+@@ -504,9 +510,17 @@
+ return 0;
+ }
+
++#ifdef BLOCKDEV_OPS_WITH_MODE
++static int lo_open(struct block_device *bdev, fmode_t unused_mode)
++#else
+ static int lo_open(struct inode *inode, struct file *file)
++#endif
+ {
++#ifdef BLOCKDEV_OPS_WITH_MODE
++ struct lloop_device *lo = bdev->bd_disk->private_data;
++#else
+ struct lloop_device *lo = inode->i_bdev->bd_disk->private_data;
++#endif
+
+ down(&lo->lo_ctl_mutex);
+ lo->lo_refcnt++;
+@@ -515,9 +529,17 @@
+ return 0;
+ }
+
++#ifdef BLOCKDEV_OPS_WITH_MODE
++static int lo_release(struct gendisk *bd_disk, fmode_t unused_mode)
++#else
+ static int lo_release(struct inode *inode, struct file *file)
++#endif
+ {
++#ifdef BLOCKDEV_OPS_WITH_MODE
++ struct lloop_device *lo = bd_disk->private_data;
++#else
+ struct lloop_device *lo = inode->i_bdev->bd_disk->private_data;
++#endif
+
+ down(&lo->lo_ctl_mutex);
+ --lo->lo_refcnt;
+@@ -527,11 +549,20 @@
+ }
+
+ /* lloop device node's ioctl function. */
++#ifdef BLOCKDEV_OPS_WITH_MODE
++static int lo_ioctl(struct block_device *bdev, fmode_t mode,
++ unsigned int cmd, unsigned long arg)
++#else
+ static int lo_ioctl(struct inode *inode, struct file *unused,
+ unsigned int cmd, unsigned long arg)
++#endif
+ {
++#ifdef BLOCKDEV_OPS_WITH_MODE
++ struct lloop_device *lo = bdev->bd_disk->private_data;
++#else
+ struct lloop_device *lo = inode->i_bdev->bd_disk->private_data;
+ struct block_device *bdev = inode->i_bdev;
++#endif
+ int err = 0;
+
+ down(&lloop_mutex);
+@@ -539,7 +570,11 @@
+ case LL_IOC_LLOOP_DETACH: {
+ err = loop_clr_fd(lo, bdev, 2);
+ if (err == 0)
++#ifdef BLOCKDEV_OPS_WITH_MODE
++ blkdev_put(bdev, mode); /* grabbed in LLOOP_ATTACH */
++#else
+ blkdev_put(bdev); /* grabbed in LLOOP_ATTACH */
++#endif
+ break;
+ }
+
+@@ -626,7 +661,12 @@
+ err = loop_set_fd(lo, NULL, bdev, file);
+ if (err) {
+ fput(file);
++#ifdef BLOCKDEV_OPS_WITH_MODE
++ /* i guess... --azi */
++ blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
++#else
+ blkdev_put(bdev);
++#endif
+ }
+
+ break;
+@@ -650,7 +690,12 @@
+ bdev = lo->lo_device;
+ err = loop_clr_fd(lo, bdev, 1);
+ if (err == 0)
++#ifdef BLOCKDEV_OPS_WITH_MODE
++ /* i guess... --azi */
++ blkdev_put(bdev, FMODE_READ|FMODE_WRITE); /* grabbed in LLOOP_ATTACH */
++#else
+ blkdev_put(bdev); /* grabbed in LLOOP_ATTACH */
++#endif
+
+ break;
+ }
+@@ -736,7 +781,7 @@
out_mem4:
while (i--)
@@ -11467,7 +13248,7 @@ diff -urNad lustre~/lustre/llite/lloop.c lustre/lustre/llite/lloop.c
i = max_loop;
out_mem3:
while (i--)
-@@ -758,7 +758,7 @@
+@@ -758,7 +803,7 @@
ll_iocontrol_unregister(ll_iocontrol_magic);
for (i = 0; i < max_loop; i++) {
del_gendisk(disks[i]);
@@ -11477,8 +13258,8 @@ diff -urNad lustre~/lustre/llite/lloop.c lustre/lustre/llite/lloop.c
}
if (ll_unregister_blkdev(lloop_major, "lloop"))
diff -urNad lustre~/lustre/llite/lloop.c.orig lustre/lustre/llite/lloop.c.orig
---- lustre~/lustre/llite/lloop.c.orig 1970-01-01 00:00:00.000000000 +0000
-+++ lustre/lustre/llite/lloop.c.orig 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/llite/lloop.c.orig 1970-01-01 01:00:00.000000000 +0100
++++ lustre/lustre/llite/lloop.c.orig 2009-08-19 10:40:29.000000000 +0200
@@ -0,0 +1,777 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -12257,9 +14038,39 @@ diff -urNad lustre~/lustre/llite/lloop.c.orig lustre/lustre/llite/lloop.c.orig
+MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
+MODULE_DESCRIPTION("Lustre virtual block device");
+MODULE_LICENSE("GPL");
+diff -urNad lustre~/lustre/llite/lproc_llite.c lustre/lustre/llite/lproc_llite.c
+--- lustre~/lustre/llite/lproc_llite.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/llite/lproc_llite.c 2009-08-19 10:46:25.000000000 +0200
+@@ -649,7 +649,11 @@
+ sbi->ll_stats_track_id == current->p_pptr->pid)
+ lprocfs_counter_add(sbi->ll_stats, op, count);
+ else if (sbi->ll_stats_track_type == STATS_TRACK_GID &&
++#ifdef HAS_STRUCT_CRED
++ sbi->ll_stats_track_id == current->real_cred->gid)
++#else
+ sbi->ll_stats_track_id == current->gid)
++#endif
+ lprocfs_counter_add(sbi->ll_stats, op, count);
+ }
+ EXPORT_SYMBOL(ll_stats_ops_tally);
+diff -urNad lustre~/lustre/llite/namei.c lustre/lustre/llite/namei.c
+--- lustre~/lustre/llite/namei.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/llite/namei.c 2009-08-19 10:46:25.000000000 +0200
+@@ -875,7 +875,11 @@
+ GOTO(err_exit, err);
+
+ err = mdc_create(sbi->ll_mdc_exp, &op_data, tgt, tgt_len,
++#ifdef HAS_STRUCT_CRED
++ mode, current->real_cred->fsuid, current->real_cred->fsgid,
++#else
+ mode, current->fsuid, current->fsgid,
++#endif
+ cfs_curproc_cap_pack(), rdev, &request);
+ if (err)
+ GOTO(err_exit, err);
diff -urNad lustre~/lustre/llite/rw.c lustre/lustre/llite/rw.c
---- lustre~/lustre/llite/rw.c 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/llite/rw.c 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/llite/rw.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/llite/rw.c 2009-08-19 10:46:25.000000000 +0200
@@ -61,6 +61,8 @@
#define DEBUG_SUBSYSTEM S_LLITE
@@ -12278,7 +14089,208 @@ diff -urNad lustre~/lustre/llite/rw.c lustre/lustre/llite/rw.c
if (!srvlock) {
struct ost_lvb lvb;
-@@ -2122,7 +2124,7 @@
+@@ -247,6 +249,94 @@
+ ll_inode_size_unlock(inode, 0);
+ } /* ll_truncate */
+
++#ifdef NO_PREPARE_WRITE
++int ll_write_begin(struct file *unused_file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **unused_fsdata)
++{
++ struct inode *inode = mapping->host;
++ struct page *page;
++ struct ll_inode_info *lli = ll_i2info(inode);
++ struct lov_stripe_md *lsm = lli->lli_smd;
++ obd_off index = pos >> CFS_PAGE_SHIFT;
++ obd_off offset = pos & (CFS_PAGE_SIZE - 1);
++ struct obd_info oinfo = { { { 0 } } };
++ struct brw_page pga;
++ struct obdo oa;
++ struct ost_lvb lvb;
++ int rc = 0;
++ ENTRY;
++
++ page = grab_cache_page_write_begin(mapping, index, flags);
++ if (!page) {
++ rc = -ENOMEM;
++ RETURN(rc);
++ }
++
++ LASSERT(PageLocked(page));
++ (void)llap_cast_private(page); /* assertion */
++
++ /* Check to see if we should return -EIO right away */
++ pga.pg = page;
++ pga.off = offset;
++ pga.count = CFS_PAGE_SIZE;
++ pga.flag = 0;
++
++ oa.o_mode = inode->i_mode;
++ oa.o_id = lsm->lsm_object_id;
++ oa.o_valid = OBD_MD_FLID | OBD_MD_FLMODE | OBD_MD_FLTYPE;
++ obdo_from_inode(&oa, inode, OBD_MD_FLFID | OBD_MD_FLGENER);
++
++ oinfo.oi_oa = &oa;
++ oinfo.oi_md = lsm;
++ rc = obd_brw(OBD_BRW_CHECK, ll_i2obdexp(inode), &oinfo, 1, &pga, NULL);
++ if (rc)
++ RETURN(rc);
++
++ if (PageUptodate(page)) {
++ LL_CDEBUG_PAGE(D_PAGE, page, "uptodate\n");
++ RETURN(0);
++ }
++
++ /* We're completely overwriting an existing page, so _don't_ set it up
++ * to date until commit_write */
++ if (pos == 0 && len == CFS_PAGE_SIZE) {
++ LL_CDEBUG_PAGE(D_PAGE, page, "full page write\n");
++ POISON_PAGE(page, 0x11);
++ RETURN(0);
++ }
++
++ /* If are writing to a new page, no need to read old data. The extent
++ * locking will have updated the KMS, and for our purposes here we can
++ * treat it like i_size. */
++ lov_stripe_lock(lsm);
++ inode_init_lvb(inode, &lvb);
++ obd_merge_lvb(ll_i2obdexp(inode), lsm, &lvb, 1);
++ lov_stripe_unlock(lsm);
++ if (lvb.lvb_size <= offset) {
++ char *kaddr = kmap_atomic(page, KM_USER0);
++ LL_CDEBUG_PAGE(D_PAGE, page, "kms "LPU64" <= offset "LPU64"\n",
++ lvb.lvb_size, offset);
++ memset(kaddr, 0, CFS_PAGE_SIZE);
++ kunmap_atomic(kaddr, KM_USER0);
++ GOTO(prepare_done, rc = 0);
++ }
++
++ /* XXX could be an async ocp read.. read-ahead? */
++ rc = ll_brw(OBD_BRW_READ, inode, &oa, page, 0);
++ if (rc == 0) {
++ /* bug 1598: don't clobber blksize */
++ oa.o_valid &= ~(OBD_MD_FLSIZE | OBD_MD_FLBLKSZ);
++ obdo_refresh_inode(inode, &oa, oa.o_valid);
++ }
++
++ EXIT;
++ prepare_done:
++ if (rc == 0)
++ SetPageUptodate(page);
++
++ *pagep = page;
++ return rc;
++}
++#else
+ int ll_prepare_write(struct file *file, struct page *page, unsigned from,
+ unsigned to)
+ {
+@@ -325,6 +415,7 @@
+
+ return rc;
+ }
++#endif
+
+ /**
+ * make page ready for ASYNC write
+@@ -806,6 +897,89 @@
+ RETURN(rc);
+ }
+
++#ifdef NO_PREPARE_WRITE
++int ll_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *unued_fsdata)
++{
++ struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
++ struct inode *inode = mapping->host;
++ struct ll_inode_info *lli = ll_i2info(inode);
++ struct lov_stripe_md *lsm = lli->lli_smd;
++ struct obd_export *exp;
++ struct ll_async_page *llap;
++ loff_t size;
++ struct lustre_handle *lockh = NULL;
++ int rc = 0;
++ ENTRY;
++
++ SIGNAL_MASK_ASSERT(); /* XXX BUG 1511 */
++ LASSERT(inode == file->f_dentry->d_inode);
++ LASSERT(PageLocked(page));
++
++ CDEBUG(D_INODE, "inode %p is writing page %p from %ld to %ld at %lu\n",
++ inode, page, (long int)pos, (long int)(pos + copied), page->index);
++
++/**** ???? ****/
++if (PageChecked(page)) {
++ if (copied == len)
++ SetPageUptodate(page);
++ ClearPageChecked(page);
++} else if (!PageUptodate(page) && copied == CFS_PAGE_SIZE)
++ SetPageUptodate(page);
++/************/
++
++
++
++ if (fd->fd_flags & LL_FILE_GROUP_LOCKED)
++ lockh = &fd->fd_cwlockh;
++
++ llap = llap_from_page_with_lockh(page, LLAP_ORIGIN_COMMIT_WRITE, lockh);
++ if (IS_ERR(llap))
++ RETURN(PTR_ERR(llap));
++
++ exp = ll_i2obdexp(inode);
++ if (exp == NULL)
++ RETURN(-EINVAL);
++
++ llap->llap_ignore_quota = cfs_capable(CFS_CAP_SYS_RESOURCE);
++
++ /* queue a write for some time in the future the first time we
++ * dirty the page */
++ if (!PageDirty(page)) {
++ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_DIRTY_MISSES, 1);
++
++ rc = queue_or_sync_write(exp, inode, llap, (pos + copied), 0);
++ if (rc)
++ GOTO(out, rc);
++ } else {
++ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_DIRTY_HITS, 1);
++ }
++
++ /* put the page in the page cache, from now on ll_removepage is
++ * responsible for cleaning up the llap.
++ * only set page dirty when it's queued to be write out */
++ if (llap->llap_write_queued)
++ set_page_dirty(page);
++
++out:
++ size = (((obd_off)page->index) << CFS_PAGE_SHIFT) + (pos + copied);
++ ll_inode_size_lock(inode, 0);
++ if (rc == 0) {
++ lov_stripe_lock(lsm);
++ obd_adjust_kms(exp, lsm, size, 0);
++ lov_stripe_unlock(lsm);
++ if (size > i_size_read(inode))
++ i_size_write(inode, size);
++ SetPageUptodate(page);
++ } else if (size > i_size_read(inode)) {
++ /* this page beyond the pales of i_size, so it can't be
++ * truncated in ll_p_r_e during lock revoking. we must
++ * teardown our book-keeping here. */
++ ll_removepage(page);
++ }
++ ll_inode_size_unlock(inode, 0);
++ RETURN(rc);
++}
++#else
+ /* update our write count to account for i_size increases that may have
+ * happened since we've queued the page for io. */
+
+@@ -882,6 +1056,7 @@
+ ll_inode_size_unlock(inode, 0);
+ RETURN(rc);
+ }
++#endif
+
+ static unsigned long ll_ra_count_get(struct ll_sb_info *sbi, unsigned long len)
+ {
+@@ -2122,7 +2297,7 @@
rc = generic_write_checks(file, ppos, &count, 0);
if (rc)
GOTO(out, rc);
@@ -12288,8 +14300,8 @@ diff -urNad lustre~/lustre/llite/rw.c lustre/lustre/llite/rw.c
GOTO(out, rc);
}
diff -urNad lustre~/lustre/llite/rw.c.orig lustre/lustre/llite/rw.c.orig
---- lustre~/lustre/llite/rw.c.orig 1970-01-01 00:00:00.000000000 +0000
-+++ lustre/lustre/llite/rw.c.orig 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/llite/rw.c.orig 1970-01-01 01:00:00.000000000 +0100
++++ lustre/lustre/llite/rw.c.orig 2009-08-19 10:40:29.000000000 +0200
@@ -0,0 +1,2215 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -14506,9 +16518,43 @@ diff -urNad lustre~/lustre/llite/rw.c.orig lustre/lustre/llite/rw.c.orig
+out:
+ RETURN(rc);
+}
+diff -urNad lustre~/lustre/llite/rw24.c lustre/lustre/llite/rw24.c
+--- lustre~/lustre/llite/rw24.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/llite/rw24.c 2009-08-19 10:46:25.000000000 +0200
+@@ -150,8 +150,13 @@
+ .readpage = ll_readpage,
+ .direct_IO = ll_direct_IO_24,
+ .writepage = ll_writepage,
++#ifdef NO_PREPARE_WRITE
++ .write_begin = ll_write_begin,
++ .write_end = ll_write_end,
++#else
+ .prepare_write = ll_prepare_write,
+ .commit_write = ll_commit_write,
++#endif
+ .removepage = ll_removepage,
+ .sync_page = NULL,
+ .bmap = NULL,
+diff -urNad lustre~/lustre/llite/rw26.c lustre/lustre/llite/rw26.c
+--- lustre~/lustre/llite/rw26.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/llite/rw26.c 2009-08-19 10:46:25.000000000 +0200
+@@ -339,8 +339,13 @@
+ .writepages = generic_writepages,
+ .set_page_dirty = __set_page_dirty_nobuffers,
+ .sync_page = NULL,
++#ifdef NO_PREPARE_WRITE
++ .write_begin = ll_write_begin,
++ .write_end = ll_write_end,
++#else
+ .prepare_write = ll_prepare_write,
+ .commit_write = ll_commit_write,
++#endif
+ .invalidatepage = ll_invalidatepage,
+ .releasepage = ll_releasepage,
+ .bmap = NULL
diff -urNad lustre~/lustre/llite/symlink.c lustre/lustre/llite/symlink.c
---- lustre~/lustre/llite/symlink.c 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/llite/symlink.c 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/llite/symlink.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/llite/symlink.c 2009-08-19 10:40:29.000000000 +0200
@@ -177,8 +177,12 @@
up(&lli->lli_size_sem);
}
@@ -14522,10 +16568,81 @@ diff -urNad lustre~/lustre/llite/symlink.c lustre/lustre/llite/symlink.c
GOTO(out, rc);
}
+diff -urNad lustre~/lustre/lvfs/lustre_quota_fmt.c lustre/lustre/lvfs/lustre_quota_fmt.c
+--- lustre~/lustre/lvfs/lustre_quota_fmt.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/lvfs/lustre_quota_fmt.c 2009-08-19 10:46:25.000000000 +0200
+@@ -50,7 +50,12 @@
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+-#include <linux/quotaio_v1.h>
++
++#ifdef HAVE_FS_QUOTA_QUOTAIO_V1_H
++# include <quota/quotaio_v1.h> /* MAX_DQ_TIME */
++#else
++# include <linux/quotaio_v1.h>
++#endif
+
+ #include <asm/byteorder.h>
+ #include <asm/uaccess.h>
+diff -urNad lustre~/lustre/lvfs/lustre_quota_fmt_convert.c lustre/lustre/lvfs/lustre_quota_fmt_convert.c
+--- lustre~/lustre/lvfs/lustre_quota_fmt_convert.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/lvfs/lustre_quota_fmt_convert.c 2009-08-19 10:46:25.000000000 +0200
+@@ -50,7 +50,11 @@
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+-#include <linux/quotaio_v1.h>
++#ifdef HAVE_FS_QUOTA_QUOTAIO_V1_H
++# include <quota/quotaio_v1.h> /* MAX_DQ_TIME */
++#else
++# include <linux/quotaio_v1.h>
++#endif
+
+ #include <asm/byteorder.h>
+ #include <asm/uaccess.h>
diff -urNad lustre~/lustre/lvfs/lvfs_linux.c lustre/lustre/lvfs/lvfs_linux.c
---- lustre~/lustre/lvfs/lvfs_linux.c 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/lvfs/lvfs_linux.c 2009-03-13 09:45:03.000000000 +0100
-@@ -148,10 +148,10 @@
+--- lustre~/lustre/lvfs/lvfs_linux.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/lvfs/lvfs_linux.c 2009-08-19 10:46:25.000000000 +0200
+@@ -86,10 +86,19 @@
+ current_ngroups = 0;
+ } else {
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
++# ifdef HAS_STRUCT_CRED
++ {
++ struct cred *new = prepare_creds();
++ save->group_info = get_group_info(new->group_info);
++ put_group_info(get_group_info(ginfo));
++ commit_creds(new);
++ }
++# else
+ task_lock(current);
+ save->group_info = current->group_info;
+ current->group_info = ginfo;
+ task_unlock(current);
++# endif
+ #else
+ LASSERT(ginfo->ngroups <= NGROUPS);
+ LASSERT(current->ngroups <= NGROUPS_SMALL);
+@@ -116,9 +125,17 @@
+ current_ngroups = save->ngroups;
+ } else {
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
++# ifdef HAS_STRUCT_CRED
++ {
++ struct cred *old = prepare_creds();
++ put_group_info(get_group_info(save->group_info));
++ commit_creds(old);
++ }
++# else
+ task_lock(current);
+ current->group_info = save->group_info;
+ task_unlock(current);
++# endif
+ #else
+ current->ngroups = save->group_info.ngroups;
+ if (current->ngroups)
+@@ -148,10 +165,10 @@
*/
save->fs = get_fs();
@@ -14539,7 +16656,34 @@ diff -urNad lustre~/lustre/lvfs/lvfs_linux.c lustre/lustre/lvfs/lvfs_linux.c
save->luc.luc_umask = current->fs->umask;
LASSERT(save->pwd);
-@@ -205,10 +205,10 @@
+@@ -160,6 +177,18 @@
+ LASSERT(new_ctx->pwdmnt);
+
+ if (uc) {
++#ifdef HAS_STRUCT_CRED
++ struct cred *new = prepare_creds();
++
++ save->luc.luc_fsuid = new->fsuid;
++ save->luc.luc_fsgid = new->fsgid;
++ save->luc.luc_cap = new->cap_effective;
++
++ new->fsuid = uc->luc_fsuid;
++ new->fsgid = uc->luc_fsgid;
++ new->cap_effective = uc->luc_cap;
++ commit_creds(new);
++#else
+ save->luc.luc_fsuid = current->fsuid;
+ save->luc.luc_fsgid = current->fsgid;
+ save->luc.luc_cap = current->cap_effective;
+@@ -167,6 +196,7 @@
+ current->fsuid = uc->luc_fsuid;
+ current->fsgid = uc->luc_fsgid;
+ current->cap_effective = uc->luc_cap;
++#endif
+ push_group_info(save, uc->luc_uce);
+ }
+ current->fs->umask = 0; /* umask already applied on client */
+@@ -205,10 +235,10 @@
atomic_read(¤t->fs->pwdmnt->mnt_count));
*/
@@ -14554,9 +16698,166 @@ diff -urNad lustre~/lustre/lvfs/lvfs_linux.c lustre/lustre/lvfs/lvfs_linux.c
set_fs(saved->fs);
ll_set_fs_pwd(current->fs, saved->pwdmnt, saved->pwd);
+@@ -217,9 +247,17 @@
+ mntput(saved->pwdmnt);
+ current->fs->umask = saved->luc.luc_umask;
+ if (uc) {
++#ifdef HAS_STRUCT_CRED
++ struct cred *old = prepare_creds();
++ old->fsuid = saved->luc.luc_fsuid;
++ old->fsgid = saved->luc.luc_fsgid;
++ old->cap_effective = saved->luc.luc_cap;
++ commit_creds(old);
++#else
+ current->fsuid = saved->luc.luc_fsuid;
+ current->fsgid = saved->luc.luc_fsgid;
+ current->cap_effective = saved->luc.luc_cap;
++#endif
+ pop_group_info(saved, uc->luc_uce);
+ }
+
+@@ -418,7 +456,11 @@
+ int flags)
+ {
+ mntget(ctxt->pwdmnt);
++#ifdef HAS_STRUCT_CRED
++ return dentry_open(de, ctxt->pwdmnt, flags, current->real_cred);
++#else
+ return dentry_open(de, ctxt->pwdmnt, flags);
++#endif
+ }
+ EXPORT_SYMBOL(l_dentry_open);
+
+diff -urNad lustre~/lustre/lvfs/upcall_cache.c lustre/lustre/lvfs/upcall_cache.c
+--- lustre~/lustre/lvfs/upcall_cache.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/lvfs/upcall_cache.c 2009-08-19 10:46:25.000000000 +0200
+@@ -216,7 +216,7 @@
+ entry->ue_primary = primary;
+
+ for (i = 0; i < ginfo->nblocks; i++) {
+- int cp_count = min(NGROUPS_PER_BLOCK, (int)ngroups);
++ int cp_count = min((int)NGROUPS_PER_BLOCK, (int)ngroups);
+ int off = i * NGROUPS_PER_BLOCK;
+
+ for (j = 0; j < cp_count; j++)
+diff -urNad lustre~/lustre/mdc/mdc_lib.c lustre/lustre/mdc/mdc_lib.c
+--- lustre~/lustre/mdc/mdc_lib.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/mdc/mdc_lib.c 2009-08-19 10:46:25.000000000 +0200
+@@ -56,8 +56,13 @@
+ struct mds_body *b;
+
+ b = lustre_msg_buf(req->rq_reqmsg, offset, sizeof(*b));
++#ifdef HAS_STRUCT_CRED
++ b->fsuid = current->real_cred->fsuid;
++ b->fsgid = current->real_cred->fsgid;
++#else
+ b->fsuid = current->fsuid;
+ b->fsgid = current->fsgid;
++#endif
+ b->capability = cfs_curproc_cap_pack();
+ b->fid1 = *fid;
+ b->size = pg_off; /* !! */
+@@ -69,8 +74,13 @@
+ {
+ LASSERT (b != NULL);
+
++#ifdef HAS_STRUCT_CRED
++ b->fsuid = current->real_cred->fsuid;
++ b->fsgid = current->real_cred->fsgid;
++#else
+ b->fsuid = current->fsuid;
+ b->fsgid = current->fsgid;
++#endif
+ b->capability = cfs_curproc_cap_pack();
+ }
+
+@@ -166,8 +176,13 @@
+
+ /* XXX do something about time, uid, gid */
+ rec->cr_opcode = REINT_OPEN;
++#ifdef HAS_STRUCT_CRED
++ rec->cr_fsuid = current->real_cred->fsuid;
++ rec->cr_fsgid = current->real_cred->fsgid;
++#else
+ rec->cr_fsuid = current->fsuid;
+ rec->cr_fsgid = current->fsgid;
++#endif
+ rec->cr_cap = cfs_curproc_cap_pack();
+ rec->cr_fid = op_data->fid1;
+ memset(&rec->cr_replayfid, 0, sizeof(rec->cr_replayfid));
+@@ -240,8 +255,13 @@
+ struct mds_rec_setattr *rec = lustre_msg_buf(req->rq_reqmsg, offset,
+ sizeof(*rec));
+ rec->sa_opcode = REINT_SETATTR;
++#ifdef HAS_STRUCT_CRED
++ rec->sa_fsuid = current->real_cred->fsuid;
++ rec->sa_fsgid = current->real_cred->fsgid;
++#else
+ rec->sa_fsuid = current->fsuid;
+ rec->sa_fsgid = current->fsgid;
++#endif
+ rec->sa_cap = cfs_curproc_cap_pack();
+ rec->sa_fid = data->fid1;
+ rec->sa_suppgid = -1;
+@@ -284,8 +304,13 @@
+ LASSERT (rec != NULL);
+
+ rec->ul_opcode = REINT_UNLINK;
++#ifdef HAS_STRUCT_CRED
++ rec->ul_fsuid = current->real_cred->fsuid;
++ rec->ul_fsgid = current->real_cred->fsgid;
++#else
+ rec->ul_fsuid = current->fsuid;
+ rec->ul_fsgid = current->fsgid;
++#endif
+ rec->ul_cap = cfs_curproc_cap_pack();
+ rec->ul_mode = data->create_mode;
+ rec->ul_suppgid = data->suppgids[0];
+@@ -307,8 +332,13 @@
+ rec = lustre_msg_buf(req->rq_reqmsg, offset, sizeof (*rec));
+
+ rec->lk_opcode = REINT_LINK;
++#ifdef HAS_STRUCT_CRED
++ rec->lk_fsuid = current->real_cred->fsuid;
++ rec->lk_fsgid = current->real_cred->fsgid;
++#else
+ rec->lk_fsuid = current->fsuid;
+ rec->lk_fsgid = current->fsgid;
++#endif
+ rec->lk_cap = cfs_curproc_cap_pack();
+ rec->lk_suppgid1 = data->suppgids[0];
+ rec->lk_suppgid2 = data->suppgids[1];
+@@ -331,8 +361,13 @@
+
+ /* XXX do something about time, uid, gid */
+ rec->rn_opcode = REINT_RENAME;
++#ifdef HAS_STRUCT_CRED
++ rec->rn_fsuid = current->real_cred->fsuid;
++ rec->rn_fsgid = current->real_cred->fsgid;
++#else
+ rec->rn_fsuid = current->fsuid;
+ rec->rn_fsgid = current->fsgid;
++#endif
+ rec->rn_cap = cfs_curproc_cap_pack();
+ rec->rn_suppgid1 = data->suppgids[0];
+ rec->rn_suppgid2 = data->suppgids[1];
+@@ -355,8 +390,13 @@
+ struct mds_body *b;
+ b = lustre_msg_buf(req->rq_reqmsg, offset, sizeof(*b));
+
++#ifdef HAS_STRUCT_CRED
++ b->fsuid = current->real_cred->fsuid;
++ b->fsgid = current->real_cred->fsgid;
++#else
+ b->fsuid = current->fsuid;
+ b->fsgid = current->fsgid;
++#endif
+ b->capability = cfs_curproc_cap_pack();
+ b->valid = valid;
+ b->flags = flags | MDS_BFLAG_EXT_FLAGS;
diff -urNad lustre~/lustre/mgc/mgc_request.c lustre/lustre/mgc/mgc_request.c
---- lustre~/lustre/mgc/mgc_request.c 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/mgc/mgc_request.c 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/mgc/mgc_request.c 2009-08-19 09:51:09.000000000 +0200
++++ lustre/lustre/mgc/mgc_request.c 2009-08-19 10:40:29.000000000 +0200
@@ -415,7 +415,7 @@
obd->obd_lvfs_ctxt.fs = get_ds();
@@ -14567,9 +16868,21 @@ diff -urNad lustre~/lustre/mgc/mgc_request.c lustre/lustre/mgc/mgc_request.c
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
if (IS_ERR(dentry)) {
diff -urNad lustre~/lustre/obdclass/linux/linux-module.c lustre/lustre/obdclass/linux/linux-module.c
---- lustre~/lustre/obdclass/linux/linux-module.c 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/obdclass/linux/linux-module.c 2009-03-13 09:45:03.000000000 +0100
-@@ -419,13 +419,14 @@
+--- lustre~/lustre/obdclass/linux/linux-module.c 2009-08-19 09:51:10.000000000 +0200
++++ lustre/lustre/obdclass/linux/linux-module.c 2009-08-19 10:46:25.000000000 +0200
+@@ -204,7 +204,11 @@
+ int err = 0;
+ ENTRY;
+
++#ifdef HAS_STRUCT_CRED
++ if (current->real_cred->fsuid != 0)
++#else
+ if (current->fsuid != 0)
++#endif
+ RETURN(err = -EACCES);
+ if ((cmd & 0xffffff00) == ((int)'T') << 8) /* ignore all tty ioctls */
+ RETURN(err = -ENOTTY);
+@@ -419,13 +423,14 @@
ENTRY;
obd_sysctl_init();
@@ -14587,8 +16900,8 @@ diff -urNad lustre~/lustre/obdclass/linux/linux-module.c lustre/lustre/obdclass/
if (entry == NULL) {
CERROR("error registering /proc/fs/lustre/devices\n");
diff -urNad lustre~/lustre/obdclass/linux/linux-sysctl.c lustre/lustre/obdclass/linux/linux-sysctl.c
---- lustre~/lustre/obdclass/linux/linux-sysctl.c 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/obdclass/linux/linux-sysctl.c 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/obdclass/linux/linux-sysctl.c 2009-08-19 09:51:10.000000000 +0200
++++ lustre/lustre/obdclass/linux/linux-sysctl.c 2009-08-19 10:40:29.000000000 +0200
@@ -56,7 +56,9 @@
cfs_sysctl_table_header_t *obd_table_header = NULL;
@@ -14862,8 +17175,8 @@ diff -urNad lustre~/lustre/obdclass/linux/linux-sysctl.c lustre/lustre/obdclass/
.data = NULL,
.maxlen = 0,
diff -urNad lustre~/lustre/obdclass/lprocfs_status.c lustre/lustre/obdclass/lprocfs_status.c
---- lustre~/lustre/obdclass/lprocfs_status.c 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/obdclass/lprocfs_status.c 2009-03-13 09:45:03.000000000 +0100
+--- lustre~/lustre/obdclass/lprocfs_status.c 2009-08-19 09:51:10.000000000 +0200
++++ lustre/lustre/obdclass/lprocfs_status.c 2009-08-19 10:40:29.000000000 +0200
@@ -151,7 +151,7 @@
LPROCFS_ENTRY();
@@ -14882,2076 +17195,46 @@ diff -urNad lustre~/lustre/obdclass/lprocfs_status.c lustre/lustre/obdclass/lpro
rc = dp->write_proc(f, buf, size, dp->data);
LPROCFS_EXIT();
return rc;
-diff -urNad lustre~/lustre/obdclass/lprocfs_status.c.orig lustre/lustre/obdclass/lprocfs_status.c.orig
---- lustre~/lustre/obdclass/lprocfs_status.c.orig 1970-01-01 00:00:00.000000000 +0000
-+++ lustre/lustre/obdclass/lprocfs_status.c.orig 2009-03-13 09:45:03.000000000 +0100
-@@ -0,0 +1,2062 @@
-+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
-+ * vim:expandtab:shiftwidth=8:tabstop=8:
-+ *
-+ * 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.sun.com/software/products/lustre/docs/GPLv2.pdf
-+ *
-+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-+ * CA 95054 USA or visit www.sun.com if you need additional information or
-+ * have any questions.
-+ *
-+ * GPL HEADER END
-+ */
-+/*
-+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved
-+ * Use is subject to license terms.
-+ */
-+/*
-+ * This file is part of Lustre, http://www.lustre.org/
-+ * Lustre is a trademark of Sun Microsystems, Inc.
-+ *
-+ * lustre/obdclass/lprocfs_status.c
-+ *
-+ * Author: Hariharan Thantry <thantry at users.sourceforge.net>
-+ */
-+
-+#ifndef EXPORT_SYMTAB
-+# define EXPORT_SYMTAB
-+#endif
-+#define DEBUG_SUBSYSTEM S_CLASS
-+
-+#ifndef __KERNEL__
-+# include <liblustre.h>
+diff -urNad lustre~/lustre/obdclass/lustre_handles.c lustre/lustre/obdclass/lustre_handles.c
+--- lustre~/lustre/obdclass/lustre_handles.c 2009-08-19 09:51:10.000000000 +0200
++++ lustre/lustre/obdclass/lustre_handles.c 2009-08-19 10:46:25.000000000 +0200
+@@ -56,6 +56,14 @@
+ # define rcu_read_unlock() spin_unlock(&bucket->lock)
+ #endif /* ifndef HAVE_RCU */
+
++#ifndef list_for_each_rcu
++/* stolen from 2.6.26, should work for 2.6.30 at least */
++# define list_for_each_rcu(pos, head) \
++ for (pos = rcu_dereference((head)->next); \
++ prefetch(pos->next), pos != (head); \
++ pos = rcu_dereference(pos->next))
+#endif
+
-+#include <obd_class.h>
-+#include <lprocfs_status.h>
-+#include <lustre_fsfilt.h>
-+
-+#if defined(LPROCFS)
-+
-+#define MAX_STRING_SIZE 128
-+
-+/* for bug 10866, global variable */
-+DECLARE_RWSEM(_lprocfs_lock);
-+EXPORT_SYMBOL(_lprocfs_lock);
-+
-+int lprocfs_seq_release(struct inode *inode, struct file *file)
-+{
-+ LPROCFS_EXIT();
-+ return seq_release(inode, file);
-+}
-+EXPORT_SYMBOL(lprocfs_seq_release);
-+
-+struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
-+ const char *name)
-+{
-+ struct proc_dir_entry *temp;
-+
-+ if (head == NULL)
-+ return NULL;
-+
-+ LPROCFS_ENTRY();
-+ temp = head->subdir;
-+ while (temp != NULL) {
-+ if (strcmp(temp->name, name) == 0) {
-+ LPROCFS_EXIT();
-+ return temp;
-+ }
-+
-+ temp = temp->next;
-+ }
-+ LPROCFS_EXIT();
-+ return NULL;
-+}
-+
-+/* lprocfs API calls */
-+
-+/* Function that emulates snprintf but also has the side effect of advancing
-+ the page pointer for the next write into the buffer, incrementing the total
-+ length written to the buffer, and decrementing the size left in the
-+ buffer. */
-+static int lprocfs_obd_snprintf(char **page, int end, int *len,
-+ const char *format, ...)
-+{
-+ va_list list;
-+ int n;
-+
-+ if (*len >= end)
-+ return 0;
-+
-+ va_start(list, format);
-+ n = vsnprintf(*page, end - *len, format, list);
-+ va_end(list);
-+
-+ *page += n; *len += n;
-+ return n;
-+}
-+
-+int lprocfs_add_simple(struct proc_dir_entry *root, char *name,
-+ read_proc_t *read_proc, write_proc_t *write_proc,
-+ void *data)
-+{
-+ struct proc_dir_entry *proc;
-+ mode_t mode = 0;
-+
-+ if (root == NULL || name == NULL)
-+ return -EINVAL;
-+ if (read_proc)
-+ mode = 0444;
-+ if (write_proc)
-+ mode |= 0200;
-+ proc = create_proc_entry(name, mode, root);
-+ if (!proc) {
-+ CERROR("LprocFS: No memory to create /proc entry %s", name);
-+ return -ENOMEM;
-+ }
-+ proc->read_proc = read_proc;
-+ proc->write_proc = write_proc;
-+ proc->data = data;
-+ return 0;
-+}
-+
-+static ssize_t lprocfs_fops_read(struct file *f, char __user *buf, size_t size,
-+ loff_t *ppos)
-+{
-+ struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
-+ char *page, *start = NULL;
-+ int rc = 0, eof = 1, count;
-+
-+ if (*ppos >= PAGE_SIZE)
-+ return 0;
-+
-+ page = (char *)__get_free_page(GFP_KERNEL);
-+ if (page == NULL)
-+ return -ENOMEM;
-+
-+ LPROCFS_ENTRY();
-+ OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
-+ if (!dp->deleted && dp->read_proc)
-+ rc = dp->read_proc(page, &start, *ppos, PAGE_SIZE,
-+ &eof, dp->data);
-+ LPROCFS_EXIT();
-+ if (rc <= 0)
-+ goto out;
-+
-+ /* for lustre proc read, the read count must be less than PAGE_SIZE */
-+ LASSERT(eof == 1);
-+
-+ if (start == NULL) {
-+ rc -= *ppos;
-+ if (rc < 0)
-+ rc = 0;
-+ if (rc == 0)
-+ goto out;
-+ start = page + *ppos;
-+ } else if (start < page) {
-+ start = page;
-+ }
-+
-+ count = (rc < size) ? rc : size;
-+ if (copy_to_user(buf, start, count)) {
-+ rc = -EFAULT;
-+ goto out;
-+ }
-+ *ppos += count;
-+
-+out:
-+ free_page((unsigned long)page);
-+ return rc;
-+}
-+
-+static ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
-+ size_t size, loff_t *ppos)
-+{
-+ struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
-+ int rc = -EIO;
-+
-+ LPROCFS_ENTRY();
-+ if (!dp->deleted && dp->write_proc)
-+ rc = dp->write_proc(f, buf, size, dp->data);
-+ LPROCFS_EXIT();
-+ return rc;
-+}
-+
-+static struct file_operations lprocfs_generic_fops = {
-+ .owner = THIS_MODULE,
-+ .read = lprocfs_fops_read,
-+ .write = lprocfs_fops_write,
-+};
-+
-+int lprocfs_evict_client_open(struct inode *inode, struct file *f)
-+{
-+ struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
-+ struct obd_device *obd = dp->data;
-+
-+ atomic_inc(&obd->obd_evict_inprogress);
-+
-+ return 0;
-+}
-+
-+int lprocfs_evict_client_release(struct inode *inode, struct file *f)
-+{
-+ struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
-+ struct obd_device *obd = dp->data;
-+
-+ atomic_dec(&obd->obd_evict_inprogress);
-+ wake_up(&obd->obd_evict_inprogress_waitq);
-+
-+ return 0;
-+}
-+
-+struct file_operations lprocfs_evict_client_fops = {
-+ .owner = THIS_MODULE,
-+ .read = lprocfs_fops_read,
-+ .write = lprocfs_fops_write,
-+ .open = lprocfs_evict_client_open,
-+ .release = lprocfs_evict_client_release,
-+};
-+EXPORT_SYMBOL(lprocfs_evict_client_fops);
-+
-+/**
-+ * Add /proc entrys.
-+ *
-+ * \param root [in] The parent proc entry on which new entry will be added.
-+ * \param list [in] Array of proc entries to be added.
-+ * \param data [in] The argument to be passed when entries read/write routines
-+ * are called through /proc file.
-+ *
-+ * \retval 0 on success
-+ * < 0 on error
-+ */
-+int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
-+ void *data)
-+{
-+ if (root == NULL || list == NULL)
-+ return -EINVAL;
-+
-+ while (list->name != NULL) {
-+ struct proc_dir_entry *cur_root, *proc;
-+ char *pathcopy, *cur, *next, pathbuf[64];
-+ int pathsize = strlen(list->name) + 1;
-+
-+ proc = NULL;
-+ cur_root = root;
-+
-+ /* need copy of path for strsep */
-+ if (strlen(list->name) > sizeof(pathbuf) - 1) {
-+ OBD_ALLOC(pathcopy, pathsize);
-+ if (pathcopy == NULL)
-+ return -ENOMEM;
-+ } else {
-+ pathcopy = pathbuf;
-+ }
-+
-+ next = pathcopy;
-+ strcpy(pathcopy, list->name);
-+
-+ while (cur_root != NULL && (cur = strsep(&next, "/"))) {
-+ if (*cur =='\0') /* skip double/trailing "/" */
-+ continue;
-+
-+ proc = lprocfs_srch(cur_root, cur);
-+ CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
-+ cur_root->name, cur, next,
-+ (proc ? "exists" : "new"));
-+ if (next != NULL) {
-+ cur_root = (proc ? proc :
-+ proc_mkdir(cur, cur_root));
-+ } else if (proc == NULL) {
-+ mode_t mode = 0;
-+ if (list->proc_mode != 0000) {
-+ mode = list->proc_mode;
-+ } else {
-+ if (list->read_fptr)
-+ mode = 0444;
-+ if (list->write_fptr)
-+ mode |= 0200;
-+ }
-+ proc = create_proc_entry(cur, mode, cur_root);
-+ }
-+ }
-+
-+ if (pathcopy != pathbuf)
-+ OBD_FREE(pathcopy, pathsize);
-+
-+ if (cur_root == NULL || proc == NULL) {
-+ CERROR("LprocFS: No memory to create /proc entry %s",
-+ list->name);
-+ return -ENOMEM;
-+ }
-+
-+ if (list->fops)
-+ proc->proc_fops = list->fops;
-+ else
-+ proc->proc_fops = &lprocfs_generic_fops;
-+ proc->read_proc = list->read_fptr;
-+ proc->write_proc = list->write_fptr;
-+ proc->data = (list->data ? list->data : data);
-+ list++;
-+ }
-+ return 0;
-+}
-+
-+void lprocfs_remove(struct proc_dir_entry **rooth)
-+{
-+ struct proc_dir_entry *root = *rooth;
-+ struct proc_dir_entry *temp = root;
-+ struct proc_dir_entry *rm_entry;
-+ struct proc_dir_entry *parent;
-+
-+ if (!root)
-+ return;
-+ *rooth = NULL;
-+
-+ parent = root->parent;
-+ LASSERT(parent != NULL);
-+ LPROCFS_WRITE_ENTRY(); /* search vs remove race */
-+
-+ while (1) {
-+ while (temp->subdir != NULL)
-+ temp = temp->subdir;
-+
-+ rm_entry = temp;
-+ temp = temp->parent;
-+
-+ /* Memory corruption once caused this to fail, and
-+ without this LASSERT we would loop here forever. */
-+ LASSERTF(strlen(rm_entry->name) == rm_entry->namelen,
-+ "0x%p %s/%s len %d\n", rm_entry, temp->name,
-+ rm_entry->name, (int)strlen(rm_entry->name));
-+
-+ /* Now, the rm_entry->deleted flags is protected
-+ * by _lprocfs_lock. */
-+ rm_entry->data = NULL;
-+ remove_proc_entry(rm_entry->name, temp);
-+ if (temp == parent)
-+ break;
-+ }
-+ LPROCFS_WRITE_EXIT();
-+}
-+
-+struct proc_dir_entry *lprocfs_register(const char *name,
-+ struct proc_dir_entry *parent,
-+ struct lprocfs_vars *list, void *data)
-+{
-+ struct proc_dir_entry *newchild;
-+
-+ newchild = lprocfs_srch(parent, name);
-+ if (newchild != NULL) {
-+ CERROR(" Lproc: Attempting to register %s more than once \n",
-+ name);
-+ return ERR_PTR(-EALREADY);
-+ }
-+
-+ newchild = proc_mkdir(name, parent);
-+ if (newchild != NULL && list != NULL) {
-+ int rc = lprocfs_add_vars(newchild, list, data);
-+ if (rc) {
-+ lprocfs_remove(&newchild);
-+ return ERR_PTR(rc);
-+ }
-+ }
-+ return newchild;
-+}
-+
-+/* Generic callbacks */
-+int lprocfs_rd_uint(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ unsigned int *temp = (unsigned int *)data;
-+ return snprintf(page, count, "%u\n", *temp);
-+}
-+
-+int lprocfs_wr_uint(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ unsigned *p = data;
-+ char dummy[MAX_STRING_SIZE + 1] = { '\0' }, *end;
-+ unsigned long tmp;
-+
-+ if (count >= sizeof(dummy) || count == 0)
-+ return -EINVAL;
-+
-+ if (copy_from_user(dummy, buffer, count))
-+ return -EFAULT;
-+
-+ tmp = simple_strtoul(dummy, &end, 0);
-+ if (dummy == end)
-+ return -EINVAL;
-+
-+ *p = (unsigned int)tmp;
-+ return count;
-+}
-+
-+int lprocfs_rd_u64(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ LASSERT(data != NULL);
-+ *eof = 1;
-+ return snprintf(page, count, LPU64"\n", *(__u64 *)data);
-+}
-+
-+int lprocfs_rd_atomic(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ atomic_t *atom = (atomic_t *)data;
-+ LASSERT(atom != NULL);
-+ *eof = 1;
-+ return snprintf(page, count, "%d\n", atomic_read(atom));
-+}
-+
-+int lprocfs_wr_atomic(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ atomic_t *atm = data;
-+ int val = 0;
-+ int rc;
-+
-+ rc = lprocfs_write_helper(buffer, count, &val);
-+ if (rc < 0)
-+ return rc;
-+
-+ if (val <= 0)
-+ return -ERANGE;
-+
-+ atomic_set(atm, val);
-+ return count;
-+}
-+
-+int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_device *obd = (struct obd_device*)data;
-+
-+ LASSERT(obd != NULL);
-+ *eof = 1;
-+ return snprintf(page, count, "%s\n", obd->obd_uuid.uuid);
-+}
-+
-+int lprocfs_rd_name(char *page, char **start, off_t off, int count,
-+ int *eof, void* data)
-+{
-+ struct obd_device *dev = (struct obd_device *)data;
-+
-+ LASSERT(dev != NULL);
-+ LASSERT(dev->obd_name != NULL);
-+ *eof = 1;
-+ return snprintf(page, count, "%s\n", dev->obd_name);
-+}
-+
-+int lprocfs_rd_fstype(char *page, char **start, off_t off, int count, int *eof,
-+ void *data)
-+{
-+ struct obd_device *obd = (struct obd_device *)data;
-+
-+ LASSERT(obd != NULL);
-+ LASSERT(obd->obd_fsops != NULL);
-+ LASSERT(obd->obd_fsops->fs_type != NULL);
-+ return snprintf(page, count, "%s\n", obd->obd_fsops->fs_type);
-+}
-+
-+int lprocfs_rd_blksize(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_statfs osfs;
-+ int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ,
-+ OBD_STATFS_NODELAY);
-+ if (!rc) {
-+ *eof = 1;
-+ rc = snprintf(page, count, "%u\n", osfs.os_bsize);
-+ }
-+ return rc;
-+}
-+
-+int lprocfs_rd_kbytestotal(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_statfs osfs;
-+ int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ,
-+ OBD_STATFS_NODELAY);
-+ if (!rc) {
-+ __u32 blk_size = osfs.os_bsize >> 10;
-+ __u64 result = osfs.os_blocks;
-+
-+ while (blk_size >>= 1)
-+ result <<= 1;
-+
-+ *eof = 1;
-+ rc = snprintf(page, count, LPU64"\n", result);
-+ }
-+ return rc;
-+}
-+
-+int lprocfs_rd_kbytesfree(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_statfs osfs;
-+ int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ,
-+ OBD_STATFS_NODELAY);
-+ if (!rc) {
-+ __u32 blk_size = osfs.os_bsize >> 10;
-+ __u64 result = osfs.os_bfree;
-+
-+ while (blk_size >>= 1)
-+ result <<= 1;
-+
-+ *eof = 1;
-+ rc = snprintf(page, count, LPU64"\n", result);
-+ }
-+ return rc;
-+}
-+
-+int lprocfs_rd_kbytesavail(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_statfs osfs;
-+ int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ,
-+ OBD_STATFS_NODELAY);
-+ if (!rc) {
-+ __u32 blk_size = osfs.os_bsize >> 10;
-+ __u64 result = osfs.os_bavail;
-+
-+ while (blk_size >>= 1)
-+ result <<= 1;
-+
-+ *eof = 1;
-+ rc = snprintf(page, count, LPU64"\n", result);
-+ }
-+ return rc;
-+}
-+
-+int lprocfs_rd_filestotal(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_statfs osfs;
-+ int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ,
-+ OBD_STATFS_NODELAY);
-+ if (!rc) {
-+ *eof = 1;
-+ rc = snprintf(page, count, LPU64"\n", osfs.os_files);
-+ }
-+
-+ return rc;
-+}
-+
-+int lprocfs_rd_filesfree(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_statfs osfs;
-+ int rc = obd_statfs(data, &osfs, cfs_time_current_64() - HZ,
-+ OBD_STATFS_NODELAY);
-+ if (!rc) {
-+ *eof = 1;
-+ rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
-+ }
-+ return rc;
-+}
-+
-+int lprocfs_rd_server_uuid(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_device *obd = (struct obd_device *)data;
-+ struct obd_import *imp;
-+ char *imp_state_name = NULL;
-+ int rc = 0;
-+
-+ LASSERT(obd != NULL);
-+ LPROCFS_CLIMP_CHECK(obd);
-+ imp = obd->u.cli.cl_import;
-+ imp_state_name = ptlrpc_import_state_name(imp->imp_state);
-+ *eof = 1;
-+ rc = snprintf(page, count, "%s\t%s%s\n",
-+ obd2cli_tgt(obd), imp_state_name,
-+ imp->imp_deactive ? "\tDEACTIVATED" : "");
-+
-+ LPROCFS_CLIMP_EXIT(obd);
-+ return rc;
-+}
-+
-+int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_device *obd = (struct obd_device*)data;
-+ struct ptlrpc_connection *conn;
-+ int rc = 0;
-+
-+ LASSERT(obd != NULL);
-+ LPROCFS_CLIMP_CHECK(obd);
-+ conn = obd->u.cli.cl_import->imp_connection;
-+ LASSERT(conn != NULL);
-+ *eof = 1;
-+ rc = snprintf(page, count, "%s\n", conn->c_remote_uuid.uuid);
-+
-+ LPROCFS_CLIMP_EXIT(obd);
-+ return rc;
-+}
-+
-+#define flag2str(flag) \
-+ if (imp->imp_##flag && max - len > 0) \
-+ len += snprintf(str + len, max - len, " " #flag);
-+
-+/**
-+ * Append a space separated list of current set flags to str.
-+ */
-+static int obd_import_flags2str(struct obd_import *imp, char *str,
-+ int max)
-+{
-+ int len = 0;
-+
-+ if (imp->imp_obd->obd_no_recov)
-+ len += snprintf(str, max - len, " no_recov");
-+
-+ flag2str(invalid);
-+ flag2str(deactive);
-+ flag2str(replayable);
-+ flag2str(pingable);
-+ flag2str(recon_bk);
-+ flag2str(last_recon);
-+ return len;
-+}
-+#undef flags2str
-+
-+int lprocfs_rd_import(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_device *obd = (struct obd_device *)data;
-+ struct obd_import *imp;
-+ char *imp_state_name = NULL;
-+ int rc = 0;
-+
-+ LASSERT(obd != NULL);
-+ LPROCFS_CLIMP_CHECK(obd);
-+ imp = obd->u.cli.cl_import;
-+ imp_state_name = ptlrpc_import_state_name(imp->imp_state);
-+ *eof = 1;
-+
-+ rc = snprintf(page, count,
-+ "import: %s\n"
-+ " target: %s@%s\n"
-+ " state: %s\n"
-+ " inflight: %u\n"
-+ " unregistering: %u\n"
-+ " conn_cnt: %u\n"
-+ " generation: %u\n"
-+ " inval_cnt: %u\n"
-+ " last_replay_transno: "LPU64"\n"
-+ " peer_committed_transno: "LPU64"\n"
-+ " last_trasno_checked: "LPU64"\n"
-+ " flags:",
-+ obd->obd_name,
-+ obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid,
-+ imp_state_name,
-+ atomic_read(&imp->imp_inflight),
-+ atomic_read(&imp->imp_unregistering),
-+ imp->imp_conn_cnt,
-+ imp->imp_generation,
-+ atomic_read(&imp->imp_inval_count),
-+ imp->imp_last_replay_transno,
-+ imp->imp_peer_committed_transno,
-+ imp->imp_last_transno_checked);
-+ rc += obd_import_flags2str(imp, page + rc, count - rc);
-+ rc += snprintf(page+rc, count - rc, "\n");
-+ LPROCFS_CLIMP_EXIT(obd);
-+ return rc;
-+}
-+
-+int lprocfs_at_hist_helper(char *page, int count, int rc,
-+ struct adaptive_timeout *at)
-+{
-+ int i;
-+ for (i = 0; i < AT_BINS; i++)
-+ rc += snprintf(page + rc, count - rc, "%3u ", at->at_hist[i]);
-+ rc += snprintf(page + rc, count - rc, "\n");
-+ return rc;
-+}
-+
-+/* See also ptlrpc_lprocfs_rd_timeouts */
-+int lprocfs_rd_timeouts(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_device *obd = (struct obd_device *)data;
-+ struct obd_import *imp;
-+ unsigned int cur, worst;
-+ time_t now, worstt;
-+ struct dhms ts;
-+ int i, rc = 0;
-+
-+ LASSERT(obd != NULL);
-+ LPROCFS_CLIMP_CHECK(obd);
-+ imp = obd->u.cli.cl_import;
-+ *eof = 1;
-+
-+ now = cfs_time_current_sec();
-+
-+ /* Some network health info for kicks */
-+ s2dhms(&ts, now - imp->imp_last_reply_time);
-+ rc += snprintf(page + rc, count - rc,
-+ "%-10s : %ld, "DHMS_FMT" ago\n",
-+ "last reply", imp->imp_last_reply_time, DHMS_VARS(&ts));
-+
-+ cur = at_get(&imp->imp_at.iat_net_latency);
-+ worst = imp->imp_at.iat_net_latency.at_worst_ever;
-+ worstt = imp->imp_at.iat_net_latency.at_worst_time;
-+ s2dhms(&ts, now - worstt);
-+ rc += snprintf(page + rc, count - rc,
-+ "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
-+ "network", cur, worst, worstt, DHMS_VARS(&ts));
-+ rc = lprocfs_at_hist_helper(page, count, rc,
-+ &imp->imp_at.iat_net_latency);
-+
-+ for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
-+ if (imp->imp_at.iat_portal[i] == 0)
-+ break;
-+ cur = at_get(&imp->imp_at.iat_service_estimate[i]);
-+ worst = imp->imp_at.iat_service_estimate[i].at_worst_ever;
-+ worstt = imp->imp_at.iat_service_estimate[i].at_worst_time;
-+ s2dhms(&ts, now - worstt);
-+ rc += snprintf(page + rc, count - rc,
-+ "portal %-2d : cur %3u worst %3u (at %ld, "
-+ DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
-+ cur, worst, worstt, DHMS_VARS(&ts));
-+ rc = lprocfs_at_hist_helper(page, count, rc,
-+ &imp->imp_at.iat_service_estimate[i]);
-+ }
-+
-+ LPROCFS_CLIMP_EXIT(obd);
-+ return rc;
-+}
-+
-+static const char *obd_connect_names[] = {
-+ "read_only",
-+ "lov_index",
-+ "unused",
-+ "write_grant",
-+ "server_lock",
-+ "version",
-+ "request_portal",
-+ "acl",
-+ "xattr",
-+ "create_on_write",
-+ "truncate_lock",
-+ "initial_transno",
-+ "inode_bit_locks",
-+ "join_file",
-+ "getattr_by_fid",
-+ "no_oh_for_devices",
-+ "local_1.8_client",
-+ "remote_1.8_client",
-+ "max_byte_per_rpc",
-+ "64bit_qdata",
-+ "fid_capability",
-+ "oss_capability",
-+ "early_lock_cancel",
-+ "size_on_mds",
-+ "adaptive_timeout",
-+ "lru_resize",
-+ "mds_mds_connection",
-+ "real_conn",
-+ "change_qunit_size",
-+ "alt_checksum_algorithm",
-+ "fid_is_enabled",
-+ "version_recovery",
-+ "pools",
-+ NULL
-+};
-+
-+int lprocfs_rd_connect_flags(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ struct obd_device *obd = data;
-+ __u64 mask = 1, flags;
-+ int i, ret = 0;
-+
-+ LPROCFS_CLIMP_CHECK(obd);
-+ flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
-+ ret = snprintf(page, count, "flags="LPX64"\n", flags);
-+ for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) {
-+ if (flags & mask)
-+ ret += snprintf(page + ret, count - ret, "%s\n",
-+ obd_connect_names[i]);
-+ }
-+ if (flags & ~(mask - 1))
-+ ret += snprintf(page + ret, count - ret,
-+ "unknown flags "LPX64"\n", flags & ~(mask - 1));
-+
-+ LPROCFS_CLIMP_EXIT(obd);
-+ return ret;
-+}
-+EXPORT_SYMBOL(lprocfs_rd_connect_flags);
-+
-+int lprocfs_rd_num_exports(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_device *obd = (struct obd_device*)data;
-+
-+ LASSERT(obd != NULL);
-+ *eof = 1;
-+ return snprintf(page, count, "%u\n", obd->obd_num_exports);
-+}
-+
-+int lprocfs_rd_numrefs(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_type *class = (struct obd_type*) data;
-+
-+ LASSERT(class != NULL);
-+ *eof = 1;
-+ return snprintf(page, count, "%d\n", class->typ_refcnt);
-+}
-+
-+int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list)
-+{
-+ int rc = 0;
-+
-+ LASSERT(obd != NULL);
-+ LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
-+ LASSERT(obd->obd_type->typ_procroot != NULL);
-+
-+ obd->obd_proc_entry = lprocfs_register(obd->obd_name,
-+ obd->obd_type->typ_procroot,
-+ list, obd);
-+ if (IS_ERR(obd->obd_proc_entry)) {
-+ rc = PTR_ERR(obd->obd_proc_entry);
-+ CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
-+ obd->obd_proc_entry = NULL;
-+ }
-+ return rc;
-+}
-+
-+int lprocfs_obd_cleanup(struct obd_device *obd)
-+{
-+ if (!obd)
-+ return -EINVAL;
-+ if (obd->obd_proc_exports_entry) {
-+ /* Should be no exports left */
-+ LASSERT(obd->obd_proc_exports_entry->subdir == NULL);
-+ lprocfs_remove(&obd->obd_proc_exports_entry);
-+ }
-+ lprocfs_remove(&obd->obd_proc_entry);
-+ return 0;
-+}
-+
-+static void lprocfs_free_client_stats(struct nid_stat *client_stat)
-+{
-+ CDEBUG(D_CONFIG, "stat %p - data %p/%p/%p\n", client_stat,
-+ client_stat->nid_proc, client_stat->nid_stats,
-+ client_stat->nid_brw_stats);
-+
-+ LASSERTF(client_stat->nid_exp_ref_count == 0, "count %d\n",
-+ client_stat->nid_exp_ref_count);
-+
-+ hlist_del_init(&client_stat->nid_hash);
-+
-+ if (client_stat->nid_proc)
-+ lprocfs_remove(&client_stat->nid_proc);
-+
-+ if (client_stat->nid_stats)
-+ lprocfs_free_stats(&client_stat->nid_stats);
-+
-+ if (client_stat->nid_brw_stats)
-+ OBD_FREE_PTR(client_stat->nid_brw_stats);
-+
-+ if (client_stat->nid_ldlm_stats)
-+ lprocfs_free_stats(&client_stat->nid_ldlm_stats);
-+
-+ OBD_FREE_PTR(client_stat);
-+ return;
-+
-+}
-+
-+void lprocfs_free_per_client_stats(struct obd_device *obd)
-+{
-+ struct nid_stat *stat;
-+ ENTRY;
-+
-+ /* we need extra list - because hash_exit called to early */
-+ /* not need locking because all clients is died */
-+ while(!list_empty(&obd->obd_nid_stats)) {
-+ stat = list_entry(obd->obd_nid_stats.next,
-+ struct nid_stat, nid_list);
-+ list_del_init(&stat->nid_list);
-+ lprocfs_free_client_stats(stat);
-+ }
-+
-+ EXIT;
-+}
-+
-+struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
-+ enum lprocfs_stats_flags flags)
-+{
-+ struct lprocfs_stats *stats;
-+ unsigned int percpusize;
-+ unsigned int i, j;
-+ unsigned int num_cpu;
-+
-+ if (num == 0)
-+ return NULL;
-+
-+ if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
-+ num_cpu = 1;
-+ else
-+ num_cpu = num_possible_cpus();
-+
-+ OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
-+ if (stats == NULL)
-+ return NULL;
-+
-+ if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
-+ stats->ls_flags = flags;
-+ spin_lock_init(&stats->ls_lock);
-+ /* Use this lock only if there are no percpu areas */
-+ } else {
-+ stats->ls_flags = 0;
-+ }
-+
-+ percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
-+ if (num_cpu > 1)
-+ percpusize = L1_CACHE_ALIGN(percpusize);
-+
-+ for (i = 0; i < num_cpu; i++) {
-+ OBD_ALLOC(stats->ls_percpu[i], percpusize);
-+ if (stats->ls_percpu[i] == NULL) {
-+ for (j = 0; j < i; j++) {
-+ OBD_FREE(stats->ls_percpu[j], percpusize);
-+ stats->ls_percpu[j] = NULL;
-+ }
-+ break;
-+ }
-+ }
-+ if (stats->ls_percpu[0] == NULL) {
-+ OBD_FREE(stats, offsetof(typeof(*stats),
-+ ls_percpu[num_cpu]));
-+ return NULL;
-+ }
-+
-+ stats->ls_num = num;
-+ return stats;
-+}
-+
-+void lprocfs_free_stats(struct lprocfs_stats **statsh)
-+{
-+ struct lprocfs_stats *stats = *statsh;
-+ unsigned int num_cpu;
-+ unsigned int percpusize;
-+ unsigned int i;
-+
-+ if (!stats || (stats->ls_num == 0))
-+ return;
-+ *statsh = NULL;
-+ if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
-+ num_cpu = 1;
-+ else
-+ num_cpu = num_possible_cpus();
-+
-+ percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
-+ if (num_cpu > 1)
-+ percpusize = L1_CACHE_ALIGN(percpusize);
-+ for (i = 0; i < num_cpu; i++)
-+ OBD_FREE(stats->ls_percpu[i], percpusize);
-+ OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
-+}
-+
-+void lprocfs_clear_stats(struct lprocfs_stats *stats)
-+{
-+ struct lprocfs_counter *percpu_cntr;
-+ int i, j;
-+ unsigned int num_cpu;
-+
-+ num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
-+
-+ for (i = 0; i < num_cpu; i++) {
-+ for (j = 0; j < stats->ls_num; j++) {
-+ percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
-+ atomic_inc(&percpu_cntr->lc_cntl.la_entry);
-+ percpu_cntr->lc_count = 0;
-+ percpu_cntr->lc_sum = 0;
-+ percpu_cntr->lc_min = LC_MIN_INIT;
-+ percpu_cntr->lc_max = 0;
-+ percpu_cntr->lc_sumsquare = 0;
-+ atomic_inc(&percpu_cntr->lc_cntl.la_exit);
-+ }
-+ }
-+
-+ lprocfs_stats_unlock(stats);
-+}
-+
-+static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
-+ size_t len, loff_t *off)
-+{
-+ struct seq_file *seq = file->private_data;
-+ struct lprocfs_stats *stats = seq->private;
-+
-+ lprocfs_clear_stats(stats);
-+
-+ return len;
-+}
-+
-+static void *lprocfs_stats_seq_start(struct seq_file *p, loff_t *pos)
-+{
-+ struct lprocfs_stats *stats = p->private;
-+ /* return 1st cpu location */
-+ return (*pos >= stats->ls_num) ? NULL :
-+ &(stats->ls_percpu[0]->lp_cntr[*pos]);
-+}
-+
-+static void lprocfs_stats_seq_stop(struct seq_file *p, void *v)
-+{
-+}
-+
-+static void *lprocfs_stats_seq_next(struct seq_file *p, void *v, loff_t *pos)
-+{
-+ struct lprocfs_stats *stats = p->private;
-+ ++*pos;
-+ return (*pos >= stats->ls_num) ? NULL :
-+ &(stats->ls_percpu[0]->lp_cntr[*pos]);
-+}
-+
-+/* seq file export of one lprocfs counter */
-+static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
-+{
-+ struct lprocfs_stats *stats = p->private;
-+ struct lprocfs_counter *cntr = v;
-+ struct lprocfs_counter t, ret = { .lc_min = LC_MIN_INIT };
-+ int i, idx, rc = 0;
-+ unsigned int num_cpu;
-+
-+ if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
-+ struct timeval now;
-+ do_gettimeofday(&now);
-+ rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
-+ "snapshot_time", now.tv_sec, now.tv_usec);
-+ if (rc < 0)
-+ return rc;
-+ }
-+ idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
-+
-+ if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
-+ num_cpu = 1;
-+ else
-+ num_cpu = num_possible_cpus();
-+
-+ for (i = 0; i < num_cpu; i++) {
-+ struct lprocfs_counter *percpu_cntr =
-+ &(stats->ls_percpu[i])->lp_cntr[idx];
-+ int centry;
-+
-+ do {
-+ centry = atomic_read(&percpu_cntr->lc_cntl.la_entry);
-+ t.lc_count = percpu_cntr->lc_count;
-+ t.lc_sum = percpu_cntr->lc_sum;
-+ t.lc_min = percpu_cntr->lc_min;
-+ t.lc_max = percpu_cntr->lc_max;
-+ t.lc_sumsquare = percpu_cntr->lc_sumsquare;
-+ } while (centry != atomic_read(&percpu_cntr->lc_cntl.la_entry) &&
-+ centry != atomic_read(&percpu_cntr->lc_cntl.la_exit));
-+ ret.lc_count += t.lc_count;
-+ ret.lc_sum += t.lc_sum;
-+ if (t.lc_min < ret.lc_min)
-+ ret.lc_min = t.lc_min;
-+ if (t.lc_max > ret.lc_max)
-+ ret.lc_max = t.lc_max;
-+ ret.lc_sumsquare += t.lc_sumsquare;
-+ }
-+
-+ if (ret.lc_count == 0)
-+ goto out;
-+
-+ rc = seq_printf(p, "%-25s "LPD64" samples [%s]", cntr->lc_name,
-+ ret.lc_count, cntr->lc_units);
-+ if (rc < 0)
-+ goto out;
-+
-+ if ((cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ret.lc_count > 0)) {
-+ rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
-+ ret.lc_min, ret.lc_max, ret.lc_sum);
-+ if (rc < 0)
-+ goto out;
-+ if (cntr->lc_config & LPROCFS_CNTR_STDDEV)
-+ rc = seq_printf(p, " "LPD64, ret.lc_sumsquare);
-+ if (rc < 0)
-+ goto out;
-+ }
-+ rc = seq_printf(p, "\n");
-+ out:
-+ return (rc < 0) ? rc : 0;
-+}
-+
-+struct seq_operations lprocfs_stats_seq_sops = {
-+ start: lprocfs_stats_seq_start,
-+ stop: lprocfs_stats_seq_stop,
-+ next: lprocfs_stats_seq_next,
-+ show: lprocfs_stats_seq_show,
-+};
-+
-+static int lprocfs_stats_seq_open(struct inode *inode, struct file *file)
-+{
-+ struct proc_dir_entry *dp = PDE(inode);
-+ struct seq_file *seq;
-+ int rc;
-+
-+ LPROCFS_ENTRY_AND_CHECK(dp);
-+ rc = seq_open(file, &lprocfs_stats_seq_sops);
-+ if (rc) {
-+ LPROCFS_EXIT();
-+ return rc;
-+ }
-+
-+ seq = file->private_data;
-+ seq->private = dp->data;
-+ return 0;
-+}
-+
-+struct file_operations lprocfs_stats_seq_fops = {
-+ .owner = THIS_MODULE,
-+ .open = lprocfs_stats_seq_open,
-+ .read = seq_read,
-+ .write = lprocfs_stats_seq_write,
-+ .llseek = seq_lseek,
-+ .release = lprocfs_seq_release,
-+};
-+
-+int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
-+ struct lprocfs_stats *stats)
-+{
-+ struct proc_dir_entry *entry;
-+ LASSERT(root != NULL);
-+
-+ entry = create_proc_entry(name, 0644, root);
-+ if (entry == NULL)
-+ return -ENOMEM;
-+ entry->proc_fops = &lprocfs_stats_seq_fops;
-+ entry->data = (void *)stats;
-+ return 0;
-+}
-+
-+void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
-+ unsigned conf, const char *name, const char *units)
-+{
-+ struct lprocfs_counter *c;
-+ int i;
-+ unsigned int num_cpu;
-+
-+ LASSERT(stats != NULL);
-+
-+ num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
-+
-+ for (i = 0; i < num_cpu; i++) {
-+ c = &(stats->ls_percpu[i]->lp_cntr[index]);
-+ c->lc_config = conf;
-+ c->lc_count = 0;
-+ c->lc_sum = 0;
-+ c->lc_min = LC_MIN_INIT;
-+ c->lc_max = 0;
-+ c->lc_name = name;
-+ c->lc_units = units;
-+ }
-+
-+ lprocfs_stats_unlock(stats);
-+}
-+EXPORT_SYMBOL(lprocfs_counter_init);
-+
-+#define LPROCFS_OBD_OP_INIT(base, stats, op) \
-+do { \
-+ unsigned int coffset = base + OBD_COUNTER_OFFSET(op); \
-+ LASSERT(coffset < stats->ls_num); \
-+ lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
-+} while (0)
-+
-+void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
-+{
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, iocontrol);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_info);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_info_async);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, attach);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, detach);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, setup);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, precleanup);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, cleanup);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, process_config);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, postrecov);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, add_conn);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, del_conn);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, connect);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, reconnect);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, disconnect);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, statfs_async);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, packmd);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, checkmd);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr_async);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, getattr_async);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, brw_async);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, prep_async_page);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, reget_short_lock);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, release_short_lock);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, queue_async_io);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, queue_group_io);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, trigger_group_io);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, set_async_flags);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, teardown_async_page);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, merge_lvb);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, adjust_kms);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, punch);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, sync);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, migrate);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, copy);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, iterate);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, preprw);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, match);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, join_lru);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy_export);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, extent_calc);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_init);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, llog_finish);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, pin);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpin);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, import_event);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, notify);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, health_check);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, register_page_removal_cb);
-+ LPROCFS_OBD_OP_INIT(num_private_stats,stats,unregister_page_removal_cb);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, register_lock_cancel_cb);
-+ LPROCFS_OBD_OP_INIT(num_private_stats, stats,unregister_lock_cancel_cb);
-+}
-+
-+void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
-+{
-+ lprocfs_counter_init(ldlm_stats,
-+ LDLM_ENQUEUE - LDLM_FIRST_OPC,
-+ 0, "ldlm_enqueue", "reqs");
-+ lprocfs_counter_init(ldlm_stats,
-+ LDLM_CONVERT - LDLM_FIRST_OPC,
-+ 0, "ldlm_convert", "reqs");
-+ lprocfs_counter_init(ldlm_stats,
-+ LDLM_CANCEL - LDLM_FIRST_OPC,
-+ 0, "ldlm_cancel", "reqs");
-+ lprocfs_counter_init(ldlm_stats,
-+ LDLM_BL_CALLBACK - LDLM_FIRST_OPC,
-+ 0, "ldlm_bl_callback", "reqs");
-+ lprocfs_counter_init(ldlm_stats,
-+ LDLM_CP_CALLBACK - LDLM_FIRST_OPC,
-+ 0, "ldlm_cp_callback", "reqs");
-+ lprocfs_counter_init(ldlm_stats,
-+ LDLM_GL_CALLBACK - LDLM_FIRST_OPC,
-+ 0, "ldlm_gl_callback", "reqs");
-+}
-+
-+int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
-+{
-+ struct lprocfs_stats *stats;
-+ unsigned int num_stats;
-+ int rc, i;
-+
-+ LASSERT(obd->obd_stats == NULL);
-+ LASSERT(obd->obd_proc_entry != NULL);
-+ LASSERT(obd->obd_cntr_base == 0);
-+
-+ num_stats = ((int)sizeof(*obd->obd_type->typ_ops) / sizeof(void *)) +
-+ num_private_stats - 1 /* o_owner */;
-+ stats = lprocfs_alloc_stats(num_stats, 0);
-+ if (stats == NULL)
-+ return -ENOMEM;
-+
-+ lprocfs_init_ops_stats(num_private_stats, stats);
-+
-+ for (i = num_private_stats; i < num_stats; i++) {
-+ /* If this LBUGs, it is likely that an obd
-+ * operation was added to struct obd_ops in
-+ * <obd.h>, and that the corresponding line item
-+ * LPROCFS_OBD_OP_INIT(.., .., opname)
-+ * is missing from the list above. */
-+ LASSERTF(stats->ls_percpu[0]->lp_cntr[i].lc_name != NULL,
-+ "Missing obd_stat initializer obd_op "
-+ "operation at offset %d.\n", i - num_private_stats);
-+ }
-+ rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats);
-+ if (rc < 0) {
-+ lprocfs_free_stats(&stats);
-+ } else {
-+ obd->obd_stats = stats;
-+ obd->obd_cntr_base = num_private_stats;
-+ }
-+ return rc;
-+}
-+
-+void lprocfs_free_obd_stats(struct obd_device *obd)
-+{
-+ if (obd->obd_stats)
-+ lprocfs_free_stats(&obd->obd_stats);
-+}
-+
-+int lprocfs_exp_rd_nid(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct obd_export *exp = (struct obd_export*)data;
-+ LASSERT(exp != NULL);
-+ *eof = 1;
-+ return snprintf(page, count, "%s\n", obd_export_nid2str(exp));
-+}
-+
-+struct exp_uuid_cb_data {
-+ char *page;
-+ int count;
-+ int *eof;
-+ int *len;
-+};
-+
-+static void
-+lprocfs_exp_rd_cb_data_init(struct exp_uuid_cb_data *cb_data, char *page,
-+ int count, int *eof, int *len)
-+{
-+ cb_data->page = page;
-+ cb_data->count = count;
-+ cb_data->eof = eof;
-+ cb_data->len = len;
-+}
-+
-+void lprocfs_exp_print_uuid(void *obj, void *cb_data)
-+{
-+ struct obd_export *exp = (struct obd_export *)obj;
-+ struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
-+
-+ if (exp->exp_nid_stats)
-+ *data->len += snprintf((data->page + *data->len),
-+ data->count, "%s\n",
-+ obd_uuid2str(&exp->exp_client_uuid));
-+}
-+
-+int lprocfs_exp_rd_uuid(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct nid_stat *stats = (struct nid_stat *)data;
-+ struct exp_uuid_cb_data cb_data;
-+ struct obd_device *obd = stats->nid_obd;
-+ int len = 0;
-+
-+ *eof = 1;
-+ page[0] = '\0';
-+ lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
-+ lustre_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
-+ lprocfs_exp_print_uuid, &cb_data);
-+ return (*cb_data.len);
-+}
-+
-+void lprocfs_exp_print_hash(void *obj, void *cb_data)
-+{
-+ struct obd_export *exp = (struct obd_export *)obj;
-+ struct exp_uuid_cb_data *data = (struct exp_uuid_cb_data *)cb_data;
-+ lustre_hash_t *lh;
-+
-+ lh = exp->exp_lock_hash;
-+ if (lh) {
-+ if (!*data->len)
-+ *data->len += lustre_hash_debug_header(data->page,
-+ data->count);
-+
-+ *data->len += lustre_hash_debug_str(lh, data->page +
-+ *data->len,
-+ data->count);
-+ }
-+}
-+
-+int lprocfs_exp_rd_hash(char *page, char **start, off_t off, int count,
-+ int *eof, void *data)
-+{
-+ struct nid_stat *stats = (struct nid_stat *)data;
-+ struct exp_uuid_cb_data cb_data;
-+ struct obd_device *obd = stats->nid_obd;
-+ int len = 0;
-+
-+ *eof = 1;
-+ page[0] = '\0';
-+ lprocfs_exp_rd_cb_data_init(&cb_data, page, count, eof, &len);
-+ lustre_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
-+ lprocfs_exp_print_hash, &cb_data);
-+ return (*cb_data.len);
-+}
-+
-+int lprocfs_nid_stats_clear_read(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ *eof = 1;
-+ return snprintf(page, count, "%s\n",
-+ "Write into this file to clear all nid stats and "
-+ "stale nid entries");
-+}
-+EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
-+
-+void lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
-+{
-+ struct nid_stat *stat = obj;
-+ int i;
-+
-+ /* object has only hash + iterate_all references.
-+ * add/delete blocked by hash bucket lock */
-+ CDEBUG(D_INFO,"refcnt %d\n", stat->nid_exp_ref_count);
-+ if (stat->nid_exp_ref_count == 2) {
-+ hlist_del_init(&stat->nid_hash);
-+ stat->nid_exp_ref_count--;
-+ spin_lock(&stat->nid_obd->obd_nid_lock);
-+ list_del_init(&stat->nid_list);
-+ spin_unlock(&stat->nid_obd->obd_nid_lock);
-+ list_add(&stat->nid_list, data);
-+ EXIT;
-+ return;
-+ }
-+ /* we has reference to object - only clear data*/
-+ if (stat->nid_stats)
-+ lprocfs_clear_stats(stat->nid_stats);
-+
-+ if (stat->nid_brw_stats) {
-+ for (i = 0; i < BRW_LAST; i++)
-+ lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
-+ }
-+ EXIT;
-+ return;
-+}
-+
-+int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ struct obd_device *obd = (struct obd_device *)data;
-+ struct nid_stat *client_stat;
-+ CFS_LIST_HEAD(free_list);
-+
-+ lustre_hash_for_each(obd->obd_nid_stats_hash,
-+ lprocfs_nid_stats_clear_write_cb, &free_list);
-+
-+ while (!list_empty(&free_list)) {
-+ client_stat = list_entry(free_list.next, struct nid_stat,
-+ nid_list);
-+ list_del_init(&client_stat->nid_list);
-+ lprocfs_free_client_stats(client_stat);
-+ }
-+
-+ return count;
-+}
-+EXPORT_SYMBOL(lprocfs_nid_stats_clear_write);
-+
-+int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid)
-+{
-+ struct nid_stat *new_stat, *old_stat;
-+ struct nid_stat_uuid *new_ns_uuid;
-+ struct obd_device *obd;
-+ int rc = 0;
-+ ENTRY;
-+
-+ *newnid = 0;
-+
-+ if (!exp || !exp->exp_obd || !exp->exp_obd->obd_proc_exports_entry ||
-+ !exp->exp_obd->obd_nid_stats_hash)
-+ RETURN(-EINVAL);
-+
-+ /* not test against zero because eric say:
-+ * You may only test nid against another nid, or LNET_NID_ANY.
-+ * Anything else is nonsense.*/
-+ if (!nid || *nid == LNET_NID_ANY)
-+ RETURN(0);
-+
-+ obd = exp->exp_obd;
-+
-+ CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
-+
-+ OBD_ALLOC_PTR(new_stat);
-+ if (new_stat == NULL)
-+ RETURN(-ENOMEM);
-+
-+ OBD_ALLOC_PTR(new_ns_uuid);
-+ if (new_ns_uuid == NULL) {
-+ OBD_FREE_PTR(new_stat);
-+ RETURN(-ENOMEM);
-+ }
-+ CFS_INIT_LIST_HEAD(&new_ns_uuid->ns_uuid_list);
-+ strncpy(new_ns_uuid->ns_uuid.uuid, exp->exp_client_uuid.uuid,
-+ sizeof(struct obd_uuid));
-+
-+ CFS_INIT_LIST_HEAD(&new_stat->nid_uuid_list);
-+ new_stat->nid = *nid;
-+ new_stat->nid_obd = exp->exp_obd;
-+ /* need live in hash after destroy export */
-+ new_stat->nid_exp_ref_count = 1;
-+
-+ old_stat = lustre_hash_findadd_unique(obd->obd_nid_stats_hash,
-+ nid, &new_stat->nid_hash);
-+ CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n",
-+ old_stat, libcfs_nid2str(*nid), new_stat->nid_exp_ref_count);
-+
-+ /* Return -EALREADY here so that we know that the /proc
-+ * entry already has been created */
-+ if (old_stat != new_stat) {
-+ struct nid_stat_uuid *tmp_uuid;
-+ int found = 0;
-+
-+ exp->exp_nid_stats = old_stat;
-+
-+ /* We need to decrement the refcount if the uuid was
-+ * already in our list */
-+ spin_lock(&obd->obd_nid_lock);
-+ list_for_each_entry(tmp_uuid, &old_stat->nid_uuid_list,
-+ ns_uuid_list) {
-+ if (tmp_uuid && obd_uuid_equals(&tmp_uuid->ns_uuid,
-+ &exp->exp_client_uuid)){
-+ found = 1;
-+ --old_stat->nid_exp_ref_count;
-+ break;
-+ }
-+ }
-+
-+ if (!found)
-+ list_add(&new_ns_uuid->ns_uuid_list,
-+ &old_stat->nid_uuid_list);
-+ else
-+ OBD_FREE_PTR(new_ns_uuid);
-+ spin_unlock(&obd->obd_nid_lock);
-+
-+ GOTO(destroy_new, rc = -EALREADY);
-+ }
-+ /* not found - create */
-+ new_stat->nid_proc = proc_mkdir(libcfs_nid2str(*nid),
-+ obd->obd_proc_exports_entry);
-+ if (!new_stat->nid_proc) {
-+ CERROR("Error making export directory for"
-+ " nid %s\n", libcfs_nid2str(*nid));
-+ GOTO(destroy_new_ns, rc = -ENOMEM);
-+ }
-+
-+ /* Add in uuid to our nid_stats list */
-+ spin_lock(&obd->obd_nid_lock);
-+ list_add(&new_ns_uuid->ns_uuid_list, &new_stat->nid_uuid_list);
-+ spin_unlock(&obd->obd_nid_lock);
-+
-+ rc = lprocfs_add_simple(new_stat->nid_proc, "uuid",
-+ lprocfs_exp_rd_uuid, NULL, new_stat);
-+ if (rc) {
-+ CWARN("Error adding the uuid file\n");
-+ GOTO(destroy_new_ns, rc);
-+ }
-+
-+ rc = lprocfs_add_simple(new_stat->nid_proc, "hash",
-+ lprocfs_exp_rd_hash, NULL, new_stat);
-+ if (rc) {
-+ CWARN("Error adding the hash file\n");
-+ lprocfs_remove(&new_stat->nid_proc);
-+ GOTO(destroy_new_ns, rc);
-+ }
-+
-+ exp->exp_nid_stats = new_stat;
-+ *newnid = 1;
-+ /* protect competitive add to list, not need locking on destroy */
-+ spin_lock(&obd->obd_nid_lock);
-+ list_add(&new_stat->nid_list, &obd->obd_nid_stats);
-+ spin_unlock(&obd->obd_nid_lock);
-+
-+ RETURN(rc);
-+
-+destroy_new_ns:
-+ lustre_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash);
-+ OBD_FREE_PTR(new_ns_uuid);
-+
-+destroy_new:
-+ OBD_FREE_PTR(new_stat);
-+ RETURN(rc);
-+}
-+
-+int lprocfs_exp_cleanup(struct obd_export *exp)
-+{
-+ struct nid_stat *stat = exp->exp_nid_stats;
-+ struct nid_stat_uuid *cursor, *tmp;
-+ int found = 0;
-+
-+ if(!stat || !exp->exp_obd)
-+ RETURN(0);
-+
-+ spin_lock(&exp->exp_obd->obd_nid_lock);
-+ list_for_each_entry_safe(cursor, tmp,
-+ &stat->nid_uuid_list,
-+ ns_uuid_list) {
-+ if (cursor && obd_uuid_equals(&cursor->ns_uuid,
-+ &exp->exp_client_uuid)) {
-+ found = 1;
-+ list_del(&cursor->ns_uuid_list);
-+ OBD_FREE_PTR(cursor);
-+ --stat->nid_exp_ref_count;
-+ CDEBUG(D_INFO, "Put stat %p - %d\n", stat,
-+ stat->nid_exp_ref_count);
-+ break;
-+ }
-+ }
-+ spin_unlock(&exp->exp_obd->obd_nid_lock);
-+ if (!found)
-+ CERROR("obd_export's client uuid %s are not found in its "
-+ "nid_stats list\n", exp->exp_client_uuid.uuid);
-+
-+ exp->exp_nid_stats = NULL;
-+ lprocfs_free_stats(&exp->exp_ops_stats);
-+
-+ return 0;
-+}
-+
-+int lprocfs_write_helper(const char *buffer, unsigned long count,
-+ int *val)
-+{
-+ return lprocfs_write_frac_helper(buffer, count, val, 1);
-+}
-+
-+int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
-+ int *val, int mult)
-+{
-+ char kernbuf[20], *end, *pbuf;
-+
-+ if (count > (sizeof(kernbuf) - 1))
-+ return -EINVAL;
-+
-+ if (copy_from_user(kernbuf, buffer, count))
-+ return -EFAULT;
-+
-+ kernbuf[count] = '\0';
-+ pbuf = kernbuf;
-+ if (*pbuf == '-') {
-+ mult = -mult;
-+ pbuf++;
-+ }
-+
-+ *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
-+ if (pbuf == end)
-+ return -EINVAL;
-+
-+ if (end != NULL && *end == '.') {
-+ int temp_val, pow = 1;
-+ int i;
-+
-+ pbuf = end + 1;
-+ if (strlen(pbuf) > 5)
-+ pbuf[5] = '\0'; /*only allow 5bits fractional*/
-+
-+ temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
-+
-+ if (pbuf < end) {
-+ for (i = 0; i < (end - pbuf); i++)
-+ pow *= 10;
-+
-+ *val += temp_val / pow;
-+ }
-+ }
-+ return 0;
-+}
-+
-+int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
-+ int mult)
-+{
-+ long decimal_val, frac_val;
-+ int prtn;
-+
-+ if (count < 10)
-+ return -EINVAL;
-+
-+ decimal_val = val / mult;
-+ prtn = snprintf(buffer, count, "%ld", decimal_val);
-+ frac_val = val % mult;
-+
-+ if (prtn < (count - 4) && frac_val > 0) {
-+ long temp_frac;
-+ int i, temp_mult = 1, frac_bits = 0;
-+
-+ temp_frac = frac_val * 10;
-+ buffer[prtn++] = '.';
-+ while (frac_bits < 2 && (temp_frac / mult) < 1 ) {
-+ /*only reserved 2bits fraction*/
-+ buffer[prtn++] ='0';
-+ temp_frac *= 10;
-+ frac_bits++;
-+ }
-+ /*
-+ Need to think these cases :
-+ 1. #echo x.00 > /proc/xxx output result : x
-+ 2. #echo x.0x > /proc/xxx output result : x.0x
-+ 3. #echo x.x0 > /proc/xxx output result : x.x
-+ 4. #echo x.xx > /proc/xxx output result : x.xx
-+ Only reserved 2bits fraction.
-+ */
-+ for (i = 0; i < (5 - prtn); i++)
-+ temp_mult *= 10;
-+
-+ frac_bits = min((int)count - prtn, 3 - frac_bits);
-+ prtn += snprintf(buffer + prtn, frac_bits, "%ld",
-+ frac_val * temp_mult / mult);
-+
-+ prtn--;
-+ while(buffer[prtn] < '1' || buffer[prtn] > '9') {
-+ prtn--;
-+ if (buffer[prtn] == '.') {
-+ prtn--;
-+ break;
-+ }
-+ }
-+ prtn++;
-+ }
-+ buffer[prtn++] ='\n';
-+ return prtn;
-+}
-+
-+int lprocfs_write_u64_helper(const char *buffer, unsigned long count,__u64 *val)
-+{
-+ return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
-+}
-+
-+int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
-+ __u64 *val, int mult)
-+{
-+ char kernbuf[22], *end, *pbuf;
-+ __u64 whole, frac = 0, units;
-+ unsigned frac_d = 1;
-+
-+ if (count > (sizeof(kernbuf) - 1))
-+ return -EINVAL;
-+
-+ if (copy_from_user(kernbuf, buffer, count))
-+ return -EFAULT;
-+
-+ kernbuf[count] = '\0';
-+ pbuf = kernbuf;
-+ if (*pbuf == '-') {
-+ mult = -mult;
-+ pbuf++;
-+ }
-+
-+ whole = simple_strtoull(pbuf, &end, 10);
-+ if (pbuf == end)
-+ return -EINVAL;
-+
-+ if (end != NULL && *end == '.') {
-+ int i;
-+ pbuf = end + 1;
-+
-+ /* need to limit frac_d to a __u32 */
-+ if (strlen(pbuf) > 10)
-+ pbuf[10] = '\0';
-+
-+ frac = simple_strtoull(pbuf, &end, 10);
-+ /* count decimal places */
-+ for (i = 0; i < (end - pbuf); i++)
-+ frac_d *= 10;
-+ }
-+
-+ units = 1;
-+ switch(*end) {
-+ case 'p': case 'P':
-+ units <<= 10;
-+ case 't': case 'T':
-+ units <<= 10;
-+ case 'g': case 'G':
-+ units <<= 10;
-+ case 'm': case 'M':
-+ units <<= 10;
-+ case 'k': case 'K':
-+ units <<= 10;
-+ }
-+ /* Specified units override the multiplier */
-+ if (units)
-+ mult = mult < 0 ? -units : units;
-+
-+ frac *= mult;
-+ do_div(frac, frac_d);
-+ *val = whole * mult + frac;
-+ return 0;
-+}
-+
-+int lprocfs_seq_create(cfs_proc_dir_entry_t *parent,
-+ char *name, mode_t mode,
-+ struct file_operations *seq_fops, void *data)
-+{
-+ struct proc_dir_entry *entry;
-+ ENTRY;
-+
-+ entry = create_proc_entry(name, mode, parent);
-+ if (entry == NULL)
-+ RETURN(-ENOMEM);
-+ entry->proc_fops = seq_fops;
-+ entry->data = data;
-+
-+ RETURN(0);
-+}
-+EXPORT_SYMBOL(lprocfs_seq_create);
-+
-+__inline__ int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
-+ mode_t mode,
-+ struct file_operations *seq_fops,
-+ void *data)
-+{
-+ return (lprocfs_seq_create(dev->obd_proc_entry, name,
-+ mode, seq_fops, data));
-+}
-+EXPORT_SYMBOL(lprocfs_obd_seq_create);
-+
-+void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
-+{
-+ if (value >= OBD_HIST_MAX)
-+ value = OBD_HIST_MAX - 1;
-+
-+ spin_lock(&oh->oh_lock);
-+ oh->oh_buckets[value]++;
-+ spin_unlock(&oh->oh_lock);
-+}
-+EXPORT_SYMBOL(lprocfs_oh_tally);
-+
-+void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
-+{
-+ unsigned int val;
-+
-+ for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
-+ ;
-+
-+ lprocfs_oh_tally(oh, val);
-+}
-+EXPORT_SYMBOL(lprocfs_oh_tally_log2);
-+
-+unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
-+{
-+ unsigned long ret = 0;
-+ int i;
-+
-+ for (i = 0; i < OBD_HIST_MAX; i++)
-+ ret += oh->oh_buckets[i];
-+ return ret;
-+}
-+EXPORT_SYMBOL(lprocfs_oh_sum);
-+
-+void lprocfs_oh_clear(struct obd_histogram *oh)
-+{
-+ spin_lock(&oh->oh_lock);
-+ memset(oh->oh_buckets, 0, sizeof(oh->oh_buckets));
-+ spin_unlock(&oh->oh_lock);
-+}
-+EXPORT_SYMBOL(lprocfs_oh_clear);
-+
-+int lprocfs_obd_rd_recovery_status(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ struct obd_device *obd = data;
-+ int len = 0, size;
-+
-+ LASSERT(obd != NULL);
-+ LASSERT(count >= 0);
-+
-+ /* Set start of user data returned to
-+ page + off since the user may have
-+ requested to read much smaller than
-+ what we need to read */
-+ *start = page + off;
-+
-+ /* We know we are allocated a page here.
-+ Also we know that this function will
-+ not need to write more than a page
-+ so we can truncate at CFS_PAGE_SIZE. */
-+ size = min(count + (int)off + 1, (int)CFS_PAGE_SIZE);
-+
-+ /* Initialize the page */
-+ memset(page, 0, size);
-+
-+ if (lprocfs_obd_snprintf(&page, size, &len, "status: ") <= 0)
-+ goto out;
-+ if (obd->obd_max_recoverable_clients == 0) {
-+ if (lprocfs_obd_snprintf(&page, size, &len, "INACTIVE\n") <= 0)
-+ goto out;
-+
-+ goto fclose;
-+ }
-+
-+ /* sampled unlocked, but really... */
-+ if (obd->obd_recovering == 0) {
-+ if (lprocfs_obd_snprintf(&page, size, &len, "COMPLETE\n") <= 0)
-+ goto out;
-+ if (lprocfs_obd_snprintf(&page, size, &len,
-+ "recovery_start: %lu\n",
-+ obd->obd_recovery_start) <= 0)
-+ goto out;
-+ if (lprocfs_obd_snprintf(&page, size, &len,
-+ "recovery_duration: %lu\n",
-+ obd->obd_recovery_end -
-+ obd->obd_recovery_start) <= 0)
-+ goto out;
-+ /* Number of clients that have completed recovery */
-+ if (lprocfs_obd_snprintf(&page, size, &len,
-+ "completed_clients: %d/%d\n",
-+ obd->obd_max_recoverable_clients -
-+ obd->obd_recoverable_clients,
-+ obd->obd_max_recoverable_clients) <= 0)
-+ goto out;
-+ if (lprocfs_obd_snprintf(&page, size, &len,
-+ "replayed_requests: %d\n",
-+ obd->obd_replayed_requests) <= 0)
-+ goto out;
-+ if (lprocfs_obd_snprintf(&page, size, &len,
-+ "last_transno: "LPD64"\n",
-+ obd->obd_next_recovery_transno - 1)<=0)
-+ goto out;
-+ goto fclose;
-+ }
-+
-+ if (lprocfs_obd_snprintf(&page, size, &len, "RECOVERING\n") <= 0)
-+ goto out;
-+ if (lprocfs_obd_snprintf(&page, size, &len, "recovery_start: %lu\n",
-+ obd->obd_recovery_start) <= 0)
-+ goto out;
-+ if (lprocfs_obd_snprintf(&page, size, &len, "time_remaining: %lu\n",
-+ cfs_time_current_sec() >= obd->obd_recovery_end ? 0 :
-+ obd->obd_recovery_end - cfs_time_current_sec()) <= 0)
-+ goto out;
-+ if (lprocfs_obd_snprintf(&page, size, &len,"connected_clients: %d/%d\n",
-+ obd->obd_connected_clients,
-+ obd->obd_max_recoverable_clients) <= 0)
-+ goto out;
-+ /* Number of clients that have completed recovery */
-+ if (lprocfs_obd_snprintf(&page, size, &len,"completed_clients: %d/%d\n",
-+ obd->obd_max_recoverable_clients -
-+ obd->obd_recoverable_clients,
-+ obd->obd_max_recoverable_clients) <= 0)
-+ goto out;
-+ if (lprocfs_obd_snprintf(&page, size, &len,"replayed_requests: %d/??\n",
-+ obd->obd_replayed_requests) <= 0)
-+ goto out;
-+ if (lprocfs_obd_snprintf(&page, size, &len, "queued_requests: %d\n",
-+ obd->obd_requests_queued_for_recovery) <= 0)
-+ goto out;
-+ if (lprocfs_obd_snprintf(&page, size, &len, "next_transno: "LPD64"\n",
-+ obd->obd_next_recovery_transno) <= 0)
-+ goto out;
-+
-+fclose:
-+ *eof = 1;
-+out:
-+ return min(count, len - (int)off);
-+}
-+EXPORT_SYMBOL(lprocfs_obd_rd_recovery_status);
-+
-+int lprocfs_obd_rd_hash(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ struct obd_device *obd = data;
-+ int c = 0;
-+
-+ if (obd == NULL)
-+ return 0;
-+
-+ c += lustre_hash_debug_header(page, count);
-+ c += lustre_hash_debug_str(obd->obd_uuid_hash, page + c, count - c);
-+ c += lustre_hash_debug_str(obd->obd_nid_hash, page + c, count - c);
-+ c += lustre_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c);
-+
-+ return c;
-+}
-+EXPORT_SYMBOL(lprocfs_obd_rd_hash);
-+
-+#ifdef CRAY_XT3
-+int lprocfs_obd_rd_recovery_maxtime(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ struct obd_device *obd = (struct obd_device *)data;
-+ LASSERT(obd != NULL);
-+
-+ return snprintf(page, count, "%lu\n",
-+ obd->obd_recovery_max_time);
-+}
-+EXPORT_SYMBOL(lprocfs_obd_rd_recovery_maxtime);
-+
-+int lprocfs_obd_wr_recovery_maxtime(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ struct obd_device *obd = (struct obd_device *)data;
-+ int val, rc;
-+ LASSERT(obd != NULL);
-+
-+ rc = lprocfs_write_helper(buffer, count, &val);
-+ if (rc)
-+ return rc;
-+
-+ obd->obd_recovery_max_time = val;
-+ return count;
-+}
-+EXPORT_SYMBOL(lprocfs_obd_wr_recovery_maxtime);
-+#endif /* CRAY_XT3 */
-+
-+EXPORT_SYMBOL(lprocfs_register);
-+EXPORT_SYMBOL(lprocfs_srch);
-+EXPORT_SYMBOL(lprocfs_remove);
-+EXPORT_SYMBOL(lprocfs_add_vars);
-+EXPORT_SYMBOL(lprocfs_obd_setup);
-+EXPORT_SYMBOL(lprocfs_obd_cleanup);
-+EXPORT_SYMBOL(lprocfs_add_simple);
-+EXPORT_SYMBOL(lprocfs_free_per_client_stats);
-+EXPORT_SYMBOL(lprocfs_alloc_stats);
-+EXPORT_SYMBOL(lprocfs_free_stats);
-+EXPORT_SYMBOL(lprocfs_clear_stats);
-+EXPORT_SYMBOL(lprocfs_register_stats);
-+EXPORT_SYMBOL(lprocfs_init_ops_stats);
-+EXPORT_SYMBOL(lprocfs_init_ldlm_stats);
-+EXPORT_SYMBOL(lprocfs_alloc_obd_stats);
-+EXPORT_SYMBOL(lprocfs_free_obd_stats);
-+EXPORT_SYMBOL(lprocfs_exp_setup);
-+EXPORT_SYMBOL(lprocfs_exp_cleanup);
-+
-+EXPORT_SYMBOL(lprocfs_rd_u64);
-+EXPORT_SYMBOL(lprocfs_rd_atomic);
-+EXPORT_SYMBOL(lprocfs_wr_atomic);
-+EXPORT_SYMBOL(lprocfs_rd_uint);
-+EXPORT_SYMBOL(lprocfs_wr_uint);
-+EXPORT_SYMBOL(lprocfs_rd_uuid);
-+EXPORT_SYMBOL(lprocfs_rd_name);
-+EXPORT_SYMBOL(lprocfs_rd_fstype);
-+EXPORT_SYMBOL(lprocfs_rd_server_uuid);
-+EXPORT_SYMBOL(lprocfs_rd_conn_uuid);
-+EXPORT_SYMBOL(lprocfs_rd_num_exports);
-+EXPORT_SYMBOL(lprocfs_rd_numrefs);
-+EXPORT_SYMBOL(lprocfs_at_hist_helper);
-+EXPORT_SYMBOL(lprocfs_rd_import);
-+EXPORT_SYMBOL(lprocfs_rd_timeouts);
-+EXPORT_SYMBOL(lprocfs_rd_blksize);
-+EXPORT_SYMBOL(lprocfs_rd_kbytestotal);
-+EXPORT_SYMBOL(lprocfs_rd_kbytesfree);
-+EXPORT_SYMBOL(lprocfs_rd_kbytesavail);
-+EXPORT_SYMBOL(lprocfs_rd_filestotal);
-+EXPORT_SYMBOL(lprocfs_rd_filesfree);
-+
-+EXPORT_SYMBOL(lprocfs_write_helper);
-+EXPORT_SYMBOL(lprocfs_write_frac_helper);
-+EXPORT_SYMBOL(lprocfs_read_frac_helper);
-+EXPORT_SYMBOL(lprocfs_write_u64_helper);
-+EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
-+#endif /* LPROCFS*/
+ static __u64 handle_base;
+ #define HANDLE_INCR 7
+ static spinlock_t handle_base_lock;
+@@ -233,6 +241,7 @@
+
+ for (i = 0; i < HANDLE_HASH_SIZE; i++) {
+ struct list_head *tmp, *pos;
++ pos = tmp = NULL; /* avoid Werror */
+ spin_lock(&handle_hash[i].lock);
+ list_for_each_safe_rcu(tmp, pos, &(handle_hash[i].head)) {
+ struct portals_handle *h;
diff -urNad lustre~/lustre/ptlrpc/service.c lustre/lustre/ptlrpc/service.c
---- lustre~/lustre/ptlrpc/service.c 2009-03-12 10:32:27.000000000 +0100
-+++ lustre/lustre/ptlrpc/service.c 2009-03-13 09:45:03.000000000 +0100
-@@ -1501,7 +1501,7 @@
+--- lustre~/lustre/ptlrpc/service.c 2009-08-19 09:51:10.000000000 +0200
++++ lustre/lustre/ptlrpc/service.c 2009-08-19 10:46:25.000000000 +0200
+@@ -1497,11 +1497,17 @@
+ {
+ struct fs_struct *fs = current->fs;
+
++#ifdef NO_FS_STRUCT_COUNT
++ write_lock(&fs->lock);
++ fs->users++;
++ write_unlock(&fs->lock);
++#else
+ atomic_inc(&fs->count);
++#endif
cfs_daemonize(name);
exit_fs(cfs_current());
current->fs = fs;
@@ -16960,3 +17243,122 @@ diff -urNad lustre~/lustre/ptlrpc/service.c lustre/lustre/ptlrpc/service.c
}
static void
+diff -urNad lustre~/lustre/quota/quota_context.c lustre/lustre/quota/quota_context.c
+--- lustre~/lustre/quota/quota_context.c 2009-08-19 09:51:10.000000000 +0200
++++ lustre/lustre/quota/quota_context.c 2009-08-19 10:46:25.000000000 +0200
+@@ -240,7 +240,11 @@
+ int ret = 0;
+ ENTRY;
+
++#ifdef HAS_SB_ANY_QUOTA_LOADED
++ if (!sb_any_quota_loaded(sb))
++#else
+ if (!sb_any_quota_enabled(sb))
++#endif
+ RETURN(0);
+
+ spin_lock(&qctxt->lqc_lock);
+@@ -366,7 +370,11 @@
+ int ret = QUOTA_RET_OK;
+ ENTRY;
+
++#ifdef HAS_SB_ANY_QUOTA_LOADED
++ if (!sb_any_quota_loaded(sb))
++#else
+ if (!sb_any_quota_enabled(sb))
++#endif
+ RETURN(QUOTA_RET_NOQUOTA);
+
+ /* ignore root user */
+@@ -1022,7 +1030,11 @@
+ ENTRY;
+
+ CLASSERT(MAXQUOTAS < 4);
++#ifdef HAS_SB_ANY_QUOTA_LOADED
++ if (!sb_any_quota_loaded(qctxt->lqc_sb))
++#else
+ if (!sb_any_quota_enabled(qctxt->lqc_sb))
++#endif
+ RETURN(0);
+
+ for (i = 0; i < MAXQUOTAS; i++) {
+@@ -1248,7 +1260,11 @@
+ int ret;
+
+ LOCK_DQONOFF_MUTEX(dqopt);
++#ifdef HAS_SB_HAS_QUOTA_ACTIVE
++ if (!sb_has_quota_active(qctxt->lqc_sb, type)) {
++#else
+ if (!sb_has_quota_enabled(qctxt->lqc_sb, type)) {
++#endif
+ UNLOCK_DQONOFF_MUTEX(dqopt);
+ break;
+ }
+@@ -1310,7 +1326,11 @@
+ int rc;
+ ENTRY;
+
++#ifdef HAS_SB_ANY_QUOTA_LOADED
++ if (!sb_any_quota_loaded(qctxt->lqc_sb))
++#else
+ if (!sb_any_quota_enabled(qctxt->lqc_sb))
++#endif
+ goto exit;
+
+ data.obd = obd;
+diff -urNad lustre~/lustre/quota/quota_interface.c lustre/lustre/quota/quota_interface.c
+--- lustre~/lustre/quota/quota_interface.c 2009-08-19 09:51:10.000000000 +0200
++++ lustre/lustre/quota/quota_interface.c 2009-08-19 10:46:25.000000000 +0200
+@@ -149,7 +149,11 @@
+ {
+ ENTRY;
+
++#ifdef HAS_SB_ANY_QUOTA_LOADED
++ if (!sb_any_quota_loaded(obd->u.obt.obt_sb))
++#else
+ if (!sb_any_quota_enabled(obd->u.obt.obt_sb))
++#endif
+ RETURN(0);
+
+ if (ignore) {
+@@ -170,7 +174,11 @@
+ struct obd_quotactl *oqctl;
+ ENTRY;
+
++#ifdef HAS_SB_ANY_QUOTA_LOADED
++ if (!sb_any_quota_loaded(obt->obt_sb))
++#else
+ if (!sb_any_quota_enabled(obt->obt_sb))
++#endif
+ RETURN(0);
+
+ OBD_ALLOC_PTR(oqctl);
+@@ -259,7 +267,11 @@
+ ENTRY;
+
+ CLASSERT(MAXQUOTAS < 4);
++#ifdef HAS_SB_ANY_QUOTA_LOADED
++ if (!sb_any_quota_loaded(qctxt->lqc_sb))
++#else
+ if (!sb_any_quota_enabled(qctxt->lqc_sb))
++#endif
+ RETURN(rc);
+
+ spin_lock(&qctxt->lqc_lock);
+diff -urNad lustre~/lustre/quota/quota_internal.h lustre/lustre/quota/quota_internal.h
+--- lustre~/lustre/quota/quota_internal.h 2009-08-19 09:51:10.000000000 +0200
++++ lustre/lustre/quota/quota_internal.h 2009-08-19 10:46:25.000000000 +0200
+@@ -41,6 +41,13 @@
+
+ #ifdef HAVE_QUOTA_SUPPORT
+
++#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,30)
++/* since 2.6.29 defined in fs/quota/quota_v?.c */
++# define QUOTABLOCK_BITS 10
++# define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
++#endif
++
++
+ /* QUSG covnert bytes to blocks when counting block quota */
+ #define QUSG(count, isblk) (isblk ? toqb(count) : count)
+
--
Lustre Debian Packaging
More information about the Pkg-lustre-svn-commit
mailing list