[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 *)&current->real_cred->cap_effective, cap);
++#else
+         cfs_kernel_cap_unpack(&current->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(&current->pending, 0, sizeof(current->pending));
+ 
+         current->max_groups = sysconf(_SC_NGROUPS_MAX);
+@@ -221,24 +230,40 @@
+                 return -EINVAL;
+         }
+ 
++#ifdef HAS_STRUCT_CRED
++        init_capability(&current->real_cred->cap_effective);
++#else
+         init_capability(&current->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(&current->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