[Pkg-lustre-svn-commit] updated: [725ae43] Removed modified-debian-specific-stuff.patch
Marco Nelles
marco.nelles at credativ.de
Tue Jun 5 08:54:39 UTC 2012
The following commit has been merged in the master branch:
commit 725ae43a4e8e21d6148952f178a932f920a86a18
Author: Marco Nelles <marco.nelles at credativ.de>
Date: Tue Jun 5 10:54:13 2012 +0200
Removed modified-debian-specific-stuff.patch
diff --git a/debian/patches/modified-debian-specific-stuff.patch b/debian/patches/modified-debian-specific-stuff.patch
deleted file mode 100644
index 38c77d5..0000000
--- a/debian/patches/modified-debian-specific-stuff.patch
+++ /dev/null
@@ -1,4373 +0,0 @@
-Description: everything which was incorporated into the .diff.gz over time
- This patch contains every modification which was done directly in .diff.gz
- over the time. Cleanup is required here in near future.
- .
- lustre (1.8.5+dfsg-3) unstable; urgency=low
- .
- * [9194f2d] Build ldiskfs kernel module also on plain
- debian kernel (2.6.32)
-Author: Patrick Winnertz <winnie at debian.org>
-
----
-The information above should follow the Patch Tagging Guidelines, please
-checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
-are templates for supplementary fields that you might want to add:
-
-Origin: <vendor|upstream|other>, <url of original patch>
-Bug: <url in upstream bugtracker>
-Bug-Debian: http://bugs.debian.org/<bugnumber>
-Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
-Forwarded: <no|not-needed|url proving that it has been forwarded>
-Reviewed-By: <name and email of someone who approved the patch>
-Last-Update: <YYYY-MM-DD>
-
---- /dev/null
-+++ lustre-1.8.5+dfsg/ldiskfs/kernel_patches/series/ldiskfs-2.6.18-debian.series
-@@ -0,0 +1,20 @@
-+ext3-wantedi-2.6-rhel4.patch
-+iopen-2.6-fc5.patch
-+ext3-map_inode_page-2.6.18.patch
-+export-ext3-2.6-rhel4.patch
-+ext3-include-fixes-2.6-rhel4.patch
-+ext3-extents-2.6.18-vanilla.patch
-+ext3-mballoc3-core.patch
-+ext3-mballoc3-2.6.18.patch
-+ext3-nlinks-2.6.9.patch
-+ext3-ialloc-2.6.patch
-+ext3-remove-cond_resched-calls-2.6.12.patch
-+ext3-filterdata-sles10.patch
-+ext3-16tb-overflow-fixes.patch
-+ext3-uninit-2.6.18.patch
-+ext3-nanosecond-2.6.18-vanilla.patch
-+ext3-inode-version-2.6.18-vanilla.patch
-+ext3-ea-expand-lose-block.patch
-+ext3-mmp-2.6.18-vanilla.patch
-+ext3-fiemap-2.6.18-vanilla.patch
-+ext3-lookup-dotdot-2.6.9.patch
---- /dev/null
-+++ lustre-1.8.5+dfsg/lustre/kernel_patches/series/2.6.27-vanilla.series
-@@ -0,0 +1,15 @@
-+lustre_version.patch
-+vfs_races-2.6.22-vanilla.patch
-+iopen-misc-2.6.22-vanilla.patch
-+export-truncate-2.6.18-vanilla.patch
-+export_symbols-2.6.22-vanilla.patch
-+dev_read_only-2.6.27-vanilla.patch
-+export-2.6.27-vanilla.patch
-+export-show_task-2.6.27-vanilla.patch
-+sd_iostats-2.6.27-vanilla.patch
-+md-mmp-unplug-dev-2.6.27-vanilla.patch
-+quota-Split-off-quota-tree-handling-into-a-separate.patch
-+quota-Increase-size-of-variables-for-limits-and-ino.patch
-+quota-support-64-bit-quota-format-2.6.27-vanilla.patch
-+jbd2-jcberr-2.6-sles11.patch
-+jbd2-commit-timer-no-jiffies-rounding.diff
---- /dev/null
-+++ lustre-1.8.5+dfsg/lustre/kernel_patches/series/2.6.26-vanilla.series
-@@ -0,0 +1,2 @@
-+lustre_version.patch
-+debian-2.6.26.diff
---- /dev/null
-+++ lustre-1.8.5+dfsg/lustre/kernel_patches/patches/quota-Increase-size-of-variables-for-limits-and-ino.patch
-@@ -0,0 +1,359 @@
-+From: Jan Kara <jack at suse.cz>
-+References: fate#302681
-+Subject: [PATCH 02/28] quota: Increase size of variables for limits and inode usage
-+Patch-mainline: 2.6.29?
-+
-+So far quota was fine with quota block limits and inode limits/numbers in
-+a 32-bit type. Now with rapid increase in storage sizes there are coming
-+requests to be able to handle quota limits above 4TB / more that 2^32 inodes.
-+So bump up sizes of types in mem_dqblk structure to 64-bits to be able to
-+handle this. Also update inode allocation / checking functions to use qsize_t
-+and make global structure keep quota limits in bytes so that things are
-+consistent.
-+
-+Signed-off-by: Jan Kara <jack at suse.cz>
-+---
-+ fs/dquot.c | 50 ++++++++++++++++++++++++++-------------------
-+ fs/quota_v1.c | 25 +++++++++++++++++-----
-+ fs/quota_v2.c | 21 +++++++++++++++---
-+ include/linux/quota.h | 28 +++++++++++--------------
-+ include/linux/quotaops.h | 4 +-
-+ 5 files changed, 79 insertions(+), 49 deletions(-)
-+
-+diff --git a/fs/dquot.c b/fs/dquot.c
-+index e1dac3e..758bf4a 100644
-+--- a/fs/dquot.c
-++++ b/fs/dquot.c
-+@@ -833,7 +833,7 @@ static void drop_dquot_ref(struct super_block *sb, int type)
-+ }
-+ }
-+
-+-static inline void dquot_incr_inodes(struct dquot *dquot, unsigned long number)
-++static inline void dquot_incr_inodes(struct dquot *dquot, qsize_t number)
-+ {
-+ dquot->dq_dqb.dqb_curinodes += number;
-+ }
-+@@ -843,7 +843,7 @@ static inline void dquot_incr_space(struct dquot *dquot, qsize_t number)
-+ dquot->dq_dqb.dqb_curspace += number;
-+ }
-+
-+-static inline void dquot_decr_inodes(struct dquot *dquot, unsigned long number)
-++static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
-+ {
-+ if (dquot->dq_dqb.dqb_curinodes > number)
-+ dquot->dq_dqb.dqb_curinodes -= number;
-+@@ -860,7 +860,7 @@ static inline void dquot_decr_space(struct dquot *dquot, qsize_t number)
-+ dquot->dq_dqb.dqb_curspace -= number;
-+ else
-+ dquot->dq_dqb.dqb_curspace = 0;
-+- if (toqb(dquot->dq_dqb.dqb_curspace) <= dquot->dq_dqb.dqb_bsoftlimit)
-++ if (dquot->dq_dqb.dqb_curspace <= dquot->dq_dqb.dqb_bsoftlimit)
-+ dquot->dq_dqb.dqb_btime = (time_t) 0;
-+ clear_bit(DQ_BLKS_B, &dquot->dq_flags);
-+ }
-+@@ -1038,7 +1038,7 @@ static inline char ignore_hardlimit(struct dquot *dquot)
-+ }
-+
-+ /* needs dq_data_lock */
-+-static int check_idq(struct dquot *dquot, ulong inodes, char *warntype)
-++static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
-+ {
-+ *warntype = QUOTA_NL_NOWARN;
-+ if (inodes <= 0 || test_bit(DQ_FAKE_B, &dquot->dq_flags))
-+@@ -1077,7 +1077,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
-+ return QUOTA_OK;
-+
-+ if (dquot->dq_dqb.dqb_bhardlimit &&
-+- toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bhardlimit &&
-++ dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bhardlimit &&
-+ !ignore_hardlimit(dquot)) {
-+ if (!prealloc)
-+ *warntype = QUOTA_NL_BHARDWARN;
-+@@ -1085,7 +1085,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
-+ }
-+
-+ if (dquot->dq_dqb.dqb_bsoftlimit &&
-+- toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit &&
-++ dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit &&
-+ dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime &&
-+ !ignore_hardlimit(dquot)) {
-+ if (!prealloc)
-+@@ -1094,7 +1094,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
-+ }
-+
-+ if (dquot->dq_dqb.dqb_bsoftlimit &&
-+- toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit &&
-++ dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit &&
-+ dquot->dq_dqb.dqb_btime == 0) {
-+ if (!prealloc) {
-+ *warntype = QUOTA_NL_BSOFTWARN;
-+@@ -1111,7 +1111,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
-+ return QUOTA_OK;
-+ }
-+
-+-static int info_idq_free(struct dquot *dquot, ulong inodes)
-++static int info_idq_free(struct dquot *dquot, qsize_t inodes)
-+ {
-+ if (test_bit(DQ_FAKE_B, &dquot->dq_flags) ||
-+ dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit)
-+@@ -1128,15 +1128,13 @@ static int info_idq_free(struct dquot *dquot, ulong inodes)
-+ static int info_bdq_free(struct dquot *dquot, qsize_t space)
-+ {
-+ if (test_bit(DQ_FAKE_B, &dquot->dq_flags) ||
-+- toqb(dquot->dq_dqb.dqb_curspace) <= dquot->dq_dqb.dqb_bsoftlimit)
-++ dquot->dq_dqb.dqb_curspace <= dquot->dq_dqb.dqb_bsoftlimit)
-+ return QUOTA_NL_NOWARN;
-+
-+- if (toqb(dquot->dq_dqb.dqb_curspace - space) <=
-+- dquot->dq_dqb.dqb_bsoftlimit)
-++ if (dquot->dq_dqb.dqb_curspace - space <= dquot->dq_dqb.dqb_bsoftlimit)
-+ return QUOTA_NL_BSOFTBELOW;
-+- if (toqb(dquot->dq_dqb.dqb_curspace) >= dquot->dq_dqb.dqb_bhardlimit &&
-+- toqb(dquot->dq_dqb.dqb_curspace - space) <
-+- dquot->dq_dqb.dqb_bhardlimit)
-++ if (dquot->dq_dqb.dqb_curspace >= dquot->dq_dqb.dqb_bhardlimit &&
-++ dquot->dq_dqb.dqb_curspace - space < dquot->dq_dqb.dqb_bhardlimit)
-+ return QUOTA_NL_BHARDBELOW;
-+ return QUOTA_NL_NOWARN;
-+ }
-+@@ -1279,7 +1277,7 @@ warn_put_all:
-+ /*
-+ * This operation can block, but only after everything is updated
-+ */
-+-int dquot_alloc_inode(const struct inode *inode, unsigned long number)
-++int dquot_alloc_inode(const struct inode *inode, qsize_t number)
-+ {
-+ int cnt, ret = NO_QUOTA;
-+ char warntype[MAXQUOTAS];
-+@@ -1364,7 +1362,7 @@ out_sub:
-+ /*
-+ * This operation can block, but only after everything is updated
-+ */
-+-int dquot_free_inode(const struct inode *inode, unsigned long number)
-++int dquot_free_inode(const struct inode *inode, qsize_t number)
-+ {
-+ unsigned int cnt;
-+ char warntype[MAXQUOTAS];
-+@@ -1881,14 +1879,24 @@ int vfs_dq_quota_on_remount(struct super_block *sb)
-+ return ret;
-+ }
-+
-++static inline qsize_t qbtos(qsize_t blocks)
-++{
-++ return blocks << QIF_DQBLKSIZE_BITS;
-++}
-++
-++static inline qsize_t stoqb(qsize_t space)
-++{
-++ return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS;
-++}
-++
-+ /* Generic routine for getting common part of quota structure */
-+ static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di)
-+ {
-+ struct mem_dqblk *dm = &dquot->dq_dqb;
-+
-+ spin_lock(&dq_data_lock);
-+- di->dqb_bhardlimit = dm->dqb_bhardlimit;
-+- di->dqb_bsoftlimit = dm->dqb_bsoftlimit;
-++ di->dqb_bhardlimit = stoqb(dm->dqb_bhardlimit);
-++ di->dqb_bsoftlimit = stoqb(dm->dqb_bsoftlimit);
-+ di->dqb_curspace = dm->dqb_curspace;
-+ di->dqb_ihardlimit = dm->dqb_ihardlimit;
-+ di->dqb_isoftlimit = dm->dqb_isoftlimit;
-+@@ -1935,8 +1943,8 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
-+ check_blim = 1;
-+ }
-+ if (di->dqb_valid & QIF_BLIMITS) {
-+- dm->dqb_bsoftlimit = di->dqb_bsoftlimit;
-+- dm->dqb_bhardlimit = di->dqb_bhardlimit;
-++ dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit);
-++ dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit);
-+ check_blim = 1;
-+ }
-+ if (di->dqb_valid & QIF_INODES) {
-+@@ -1954,7 +1962,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
-+ dm->dqb_itime = di->dqb_itime;
-+
-+ if (check_blim) {
-+- if (!dm->dqb_bsoftlimit || toqb(dm->dqb_curspace) < dm->dqb_bsoftlimit) {
-++ if (!dm->dqb_bsoftlimit || dm->dqb_curspace < dm->dqb_bsoftlimit) {
-+ dm->dqb_btime = 0;
-+ clear_bit(DQ_BLKS_B, &dquot->dq_flags);
-+ }
-+diff --git a/fs/quota_v1.c b/fs/quota_v1.c
-+index 5ae15b1..3e078ee 100644
-+--- a/fs/quota_v1.c
-++++ b/fs/quota_v1.c
-+@@ -14,14 +14,27 @@ MODULE_AUTHOR("Jan Kara");
-+ MODULE_DESCRIPTION("Old quota format support");
-+ MODULE_LICENSE("GPL");
-+
-++#define QUOTABLOCK_BITS 10
-++#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
-++
-++static inline qsize_t v1_stoqb(qsize_t space)
-++{
-++ return (space + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS;
-++}
-++
-++static inline qsize_t v1_qbtos(qsize_t blocks)
-++{
-++ return blocks << QUOTABLOCK_BITS;
-++}
-++
-+ static void v1_disk2mem_dqblk(struct mem_dqblk *m, struct v1_disk_dqblk *d)
-+ {
-+ m->dqb_ihardlimit = d->dqb_ihardlimit;
-+ m->dqb_isoftlimit = d->dqb_isoftlimit;
-+ m->dqb_curinodes = d->dqb_curinodes;
-+- m->dqb_bhardlimit = d->dqb_bhardlimit;
-+- m->dqb_bsoftlimit = d->dqb_bsoftlimit;
-+- m->dqb_curspace = ((qsize_t)d->dqb_curblocks) << QUOTABLOCK_BITS;
-++ m->dqb_bhardlimit = v1_qbtos(d->dqb_bhardlimit);
-++ m->dqb_bsoftlimit = v1_qbtos(d->dqb_bsoftlimit);
-++ m->dqb_curspace = v1_qbtos(d->dqb_curblocks);
-+ m->dqb_itime = d->dqb_itime;
-+ m->dqb_btime = d->dqb_btime;
-+ }
-+@@ -31,9 +44,9 @@ static void v1_mem2disk_dqblk(struct v1_disk_dqblk *d, struct mem_dqblk *m)
-+ d->dqb_ihardlimit = m->dqb_ihardlimit;
-+ d->dqb_isoftlimit = m->dqb_isoftlimit;
-+ d->dqb_curinodes = m->dqb_curinodes;
-+- d->dqb_bhardlimit = m->dqb_bhardlimit;
-+- d->dqb_bsoftlimit = m->dqb_bsoftlimit;
-+- d->dqb_curblocks = toqb(m->dqb_curspace);
-++ d->dqb_bhardlimit = v1_stoqb(m->dqb_bhardlimit);
-++ d->dqb_bsoftlimit = v1_stoqb(m->dqb_bsoftlimit);
-++ d->dqb_curblocks = v1_stoqb(m->dqb_curspace);
-+ d->dqb_itime = m->dqb_itime;
-+ d->dqb_btime = m->dqb_btime;
-+ }
-+diff --git a/fs/quota_v2.c b/fs/quota_v2.c
-+index b53827d..51c4717 100644
-+--- a/fs/quota_v2.c
-++++ b/fs/quota_v2.c
-+@@ -26,6 +26,19 @@ typedef char *dqbuf_t;
-+ #define GETIDINDEX(id, depth) (((id) >> ((V2_DQTREEDEPTH-(depth)-1)*8)) & 0xff)
-+ #define GETENTRIES(buf) ((struct v2_disk_dqblk *)(((char *)buf)+sizeof(struct v2_disk_dqdbheader)))
-+
-++#define QUOTABLOCK_BITS 10
-++#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
-++
-++static inline qsize_t v2_stoqb(qsize_t space)
-++{
-++ return (space + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS;
-++}
-++
-++static inline qsize_t v2_qbtos(qsize_t blocks)
-++{
-++ return blocks << QUOTABLOCK_BITS;
-++}
-++
-+ /* Check whether given file is really vfsv0 quotafile */
-+ static int v2_check_quota_file(struct super_block *sb, int type)
-+ {
-+@@ -104,8 +117,8 @@ static void disk2memdqb(struct mem_dqblk *m, struct v2_disk_dqblk *d)
-+ m->dqb_isoftlimit = le32_to_cpu(d->dqb_isoftlimit);
-+ m->dqb_curinodes = le32_to_cpu(d->dqb_curinodes);
-+ m->dqb_itime = le64_to_cpu(d->dqb_itime);
-+- m->dqb_bhardlimit = le32_to_cpu(d->dqb_bhardlimit);
-+- m->dqb_bsoftlimit = le32_to_cpu(d->dqb_bsoftlimit);
-++ m->dqb_bhardlimit = v2_qbtos(le32_to_cpu(d->dqb_bhardlimit));
-++ m->dqb_bsoftlimit = v2_qbtos(le32_to_cpu(d->dqb_bsoftlimit));
-+ m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
-+ m->dqb_btime = le64_to_cpu(d->dqb_btime);
-+ }
-+@@ -116,8 +129,8 @@ static void mem2diskdqb(struct v2_disk_dqblk *d, struct mem_dqblk *m, qid_t id)
-+ d->dqb_isoftlimit = cpu_to_le32(m->dqb_isoftlimit);
-+ d->dqb_curinodes = cpu_to_le32(m->dqb_curinodes);
-+ d->dqb_itime = cpu_to_le64(m->dqb_itime);
-+- d->dqb_bhardlimit = cpu_to_le32(m->dqb_bhardlimit);
-+- d->dqb_bsoftlimit = cpu_to_le32(m->dqb_bsoftlimit);
-++ d->dqb_bhardlimit = cpu_to_le32(v2_qbtos(m->dqb_bhardlimit));
-++ d->dqb_bsoftlimit = cpu_to_le32(v2_qbtos(m->dqb_bsoftlimit));
-+ d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
-+ d->dqb_btime = cpu_to_le64(m->dqb_btime);
-+ d->dqb_id = cpu_to_le32(id);
-+diff --git a/include/linux/quota.h b/include/linux/quota.h
-+index eeae7a9..5167786 100644
-+--- a/include/linux/quota.h
-++++ b/include/linux/quota.h
-+@@ -41,15 +41,6 @@
-+ #define __DQUOT_VERSION__ "dquot_6.5.1"
-+ #define __DQUOT_NUM_VERSION__ 6*10000+5*100+1
-+
-+-/* Size of blocks in which are counted size limits */
-+-#define QUOTABLOCK_BITS 10
-+-#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
-+-
-+-/* Conversion routines from and to quota blocks */
-+-#define qb2kb(x) ((x) << (QUOTABLOCK_BITS-10))
-+-#define kb2qb(x) ((x) >> (QUOTABLOCK_BITS-10))
-+-#define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
-+-
-+ #define MAXQUOTAS 2
-+ #define USRQUOTA 0 /* element used for user quotas */
-+ #define GRPQUOTA 1 /* element used for group quotas */
-+@@ -82,6 +73,11 @@
-+ #define Q_GETQUOTA 0x800007 /* get user quota structure */
-+ #define Q_SETQUOTA 0x800008 /* set user quota structure */
-+
-++/* Size of block in which space limits are passed through the quota
-++ * interface */
-++#define QIF_DQBLKSIZE_BITS 10
-++#define QIF_DQBLKSIZE (1 << QIF_DQBLKSIZE_BITS)
-++
-+ /*
-+ * Quota structure used for communication with userspace via quotactl
-+ * Following flags are used to specify which fields are valid
-+@@ -189,12 +185,12 @@ extern spinlock_t dq_data_lock;
-+ * Data for one user/group kept in memory
-+ */
-+ struct mem_dqblk {
-+- __u32 dqb_bhardlimit; /* absolute limit on disk blks alloc */
-+- __u32 dqb_bsoftlimit; /* preferred limit on disk blks */
-++ qsize_t dqb_bhardlimit; /* absolute limit on disk blks alloc */
-++ qsize_t dqb_bsoftlimit; /* preferred limit on disk blks */
-+ qsize_t dqb_curspace; /* current used space */
-+- __u32 dqb_ihardlimit; /* absolute limit on allocated inodes */
-+- __u32 dqb_isoftlimit; /* preferred inode limit */
-+- __u32 dqb_curinodes; /* current # allocated inodes */
-++ qsize_t dqb_ihardlimit; /* absolute limit on allocated inodes */
-++ qsize_t dqb_isoftlimit; /* preferred inode limit */
-++ qsize_t dqb_curinodes; /* current # allocated inodes */
-+ time_t dqb_btime; /* time limit for excessive disk use */
-+ time_t dqb_itime; /* time limit for excessive inode use */
-+ };
-+@@ -289,9 +285,9 @@ struct dquot_operations {
-+ int (*initialize) (struct inode *, int);
-+ int (*drop) (struct inode *);
-+ int (*alloc_space) (struct inode *, qsize_t, int);
-+- int (*alloc_inode) (const struct inode *, unsigned long);
-++ int (*alloc_inode) (const struct inode *, qsize_t);
-+ int (*free_space) (struct inode *, qsize_t);
-+- int (*free_inode) (const struct inode *, unsigned long);
-++ int (*free_inode) (const struct inode *, qsize_t);
-+ int (*transfer) (struct inode *, struct iattr *);
-+ int (*write_dquot) (struct dquot *); /* Ordinary dquot write */
-+ struct dquot *(*alloc_dquot)(struct super_block *, int); /* Allocate memory for new dquot (can be NULL if no special entries dquot are needed) */
-+diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
-+index ca6b9b5..9e7bc4b 100644
-+--- a/include/linux/quotaops.h
-++++ b/include/linux/quotaops.h
-+@@ -29,10 +29,10 @@ int dquot_initialize(struct inode *inode, int type);
-+ int dquot_drop(struct inode *inode);
-+
-+ int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc);
-+-int dquot_alloc_inode(const struct inode *inode, unsigned long number);
-++int dquot_alloc_inode(const struct inode *inode, qsize_t number);
-+
-+ int dquot_free_space(struct inode *inode, qsize_t number);
-+-int dquot_free_inode(const struct inode *inode, unsigned long number);
-++int dquot_free_inode(const struct inode *inode, qsize_t number);
-+
-+ int dquot_transfer(struct inode *inode, struct iattr *iattr);
-+ int dquot_commit(struct dquot *dquot);
-+--
-+1.5.2.4
-+
---- /dev/null
-+++ lustre-1.8.5+dfsg/lustre/kernel_patches/patches/export-2.6.26-vanilla.patch
-@@ -0,0 +1,24 @@
-+Index: linux-source-2.6.26/fs/jbd2/journal.c
-+===================================================================
-+--- linux-source-2.6.26.orig/fs/jbd2/journal.c 2009-10-09 13:49:43.000000000 +0200
-++++ linux-source-2.6.26/fs/jbd2/journal.c 2009-10-09 13:49:50.000000000 +0200
-+@@ -460,6 +460,7 @@
-+ spin_unlock(&journal->j_state_lock);
-+ return ret;
-+ }
-++EXPORT_SYMBOL(jbd2_log_start_commit);
-+
-+ /*
-+ * Force and wait upon a commit if the calling process is not within
-+Index: linux-source-2.6.26/security/security.c
-+===================================================================
-+--- linux-source-2.6.26.orig/security/security.c 2009-10-09 13:49:43.000000000 +0200
-++++ linux-source-2.6.26/security/security.c 2009-10-09 13:49:50.000000000 +0200
-+@@ -68,6 +68,7 @@
-+
-+ return 0;
-+ }
-++EXPORT_SYMBOL(security_inode_unlink);
-+
-+ /* Save user chosen LSM */
-+ static int __init choose_lsm(char *str)
---- /dev/null
-+++ lustre-1.8.5+dfsg/lustre/kernel_patches/patches/quota-support-64-bit-quota-format-2.6.27-vanilla.patch
-@@ -0,0 +1,282 @@
-+From: Jan Kara <jack at suse.cz>
-+
-+Implement conversion functions for new version (version 1) of quota format
-+which supports 64-bit block and inode limits and 64-bit inode usage. The
-+original implementation has been written by Andrew Perepechko.
-+
-+Signed-off-by: Andrew Perepechko <andrew.perepechko at sun.com>
-+Signed-off-by: Jan Kara <jack at suse.cz>
-+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
-+---
-+
-+ fs/quota_v2.c | 140 ++++++++++++++++++++++++++++++++++++----------
-+ fs/quotaio_v2.h | 26 ++++++--
-+ 2 files changed, 132 insertions(+), 34 deletions(-)
-+
-+Index: linux-2.6.27.36/fs/quota_v2.c
-+===================================================================
-+--- linux-2.6.27.36.orig/fs/quota_v2.c 2009-10-09 17:00:48.000000000 +0200
-++++ linux-2.6.27.36/fs/quota_v2.c 2009-10-09 17:03:35.000000000 +0200
-+@@ -23,14 +23,24 @@
-+
-+ #define __QUOTA_V2_PARANOIA
-+
-+-static void v2_mem2diskdqb(void *dp, struct dquot *dquot);
-+-static void v2_disk2memdqb(struct dquot *dquot, void *dp);
-+-static int v2_is_id(void *dp, struct dquot *dquot);
-+-
-+-static struct qtree_fmt_operations v2_qtree_ops = {
-+- .mem2disk_dqblk = v2_mem2diskdqb,
-+- .disk2mem_dqblk = v2_disk2memdqb,
-+- .is_id = v2_is_id,
-++static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot);
-++static void v2r0_disk2memdqb(struct dquot *dquot, void *dp);
-++static int v2r0_is_id(void *dp, struct dquot *dquot);
-++
-++static struct qtree_fmt_operations v2r0_qtree_ops = {
-++ .mem2disk_dqblk = v2r0_mem2diskdqb,
-++ .disk2mem_dqblk = v2r0_disk2memdqb,
-++ .is_id = v2r0_is_id,
-++};
-++
-++static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot);
-++static void v2r1_disk2memdqb(struct dquot *dquot, void *dp);
-++static int v2r1_is_id(void *dp, struct dquot *dquot);
-++
-++static struct qtree_fmt_operations v2r1_qtree_ops = {
-++ .mem2disk_dqblk = v2r1_mem2diskdqb,
-++ .disk2mem_dqblk = v2r1_disk2memdqb,
-++ .is_id = v2r1_is_id,
-+ };
-+
-+ #define QUOTABLOCK_BITS 10
-+@@ -46,8 +56,7 @@
-+ return blocks << QUOTABLOCK_BITS;
-+ }
-+
-+-/* Check whether given file is really vfsv0 quotafile */
-+-static int v2_check_quota_file(struct super_block *sb, int type)
-++static int v2_check_quota_file_header(struct super_block *sb, int type)
-+ {
-+ struct v2_disk_dqheader dqhead;
-+ ssize_t size;
-+@@ -58,12 +67,20 @@
-+ if (size != sizeof(struct v2_disk_dqheader)) {
-+ printk("quota_v2: failed read expected=%zd got=%zd\n",
-+ sizeof(struct v2_disk_dqheader), size);
-+- return 0;
-++ return -EIO;
-+ }
-+- if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] ||
-+- le32_to_cpu(dqhead.dqh_version) != quota_versions[type])
-+- return 0;
-+- return 1;
-++ if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type])
-++ return -ENOENT;
-++ if (le32_to_cpu(dqhead.dqh_version) > quota_versions[type])
-++ return -EOPNOTSUPP;
-++ return le32_to_cpu(dqhead.dqh_version);
-++}
-++
-++
-++/* Check whether given file is really vfsv0 quotafile */
-++static int v2_check_quota_file(struct super_block *sb, int type)
-++{
-++ return v2_check_quota_file_header(sb, type) >= 0;
-+ }
-+
-+ /* Read information header from quota file */
-+@@ -72,7 +89,13 @@
-+ struct v2_disk_dqinfo dinfo;
-+ struct mem_dqinfo *info = sb_dqinfo(sb, type);
-+ ssize_t size;
-++ int version = v2_check_quota_file_header(sb, type);
-+
-++ if (version < 0) {
-++ printk(KERN_WARNING "Cannot identify quota file version on "
-++ "device %s: %d\n", sb->s_id, version);
-++ return -1;
-++ }
-+ size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
-+ sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
-+ if (size != sizeof(struct v2_disk_dqinfo)) {
-+@@ -81,8 +104,14 @@
-+ return -1;
-+ }
-+ /* limits are stored as unsigned 32-bit data */
-+- info->dqi_maxblimit = 0xffffffff;
-+- info->dqi_maxilimit = 0xffffffff;
-++ if (version == 0) {
-++ /* limits are stored as unsigned 32-bit data */
-++ info->dqi_maxblimit = 0xffffffff;
-++ info->dqi_maxilimit = 0xffffffff;
-++ } else {
-++ info->dqi_maxblimit = 0x7fffffffffffffffULL;
-++ info->dqi_maxilimit = 0x7fffffffffffffffULL;
-++ }
-+ info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
-+ info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
-+ info->dqi_flags = le32_to_cpu(dinfo.dqi_flags);
-+@@ -94,8 +123,13 @@
-+ info->u.v2_i.i.dqi_blocksize_bits = V2_DQBLKSIZE_BITS;
-+ info->u.v2_i.i.dqi_usable_bs = 1 << V2_DQBLKSIZE_BITS;
-+ info->u.v2_i.i.dqi_qtree_depth = qtree_depth(&info->u.v2_i.i);
-+- info->u.v2_i.i.dqi_entry_size = sizeof(struct v2_disk_dqblk);
-+- info->u.v2_i.i.dqi_ops = &v2_qtree_ops;
-++ if (version == 0) {
-++ qinfo->dqi_entry_size = sizeof(struct v2r0_disk_dqblk);
-++ qinfo->dqi_ops = &v2r0_qtree_ops;
-++ } else {
-++ qinfo->dqi_entry_size = sizeof(struct v2r1_disk_dqblk);
-++ qinfo->dqi_ops = &v2r1_qtree_ops;
-++ }
-+ return 0;
-+ }
-+
-+@@ -125,9 +159,9 @@
-+ return 0;
-+ }
-+
-+-static void v2_disk2memdqb(struct dquot *dquot, void *dp)
-++static void v2r0_disk2memdqb(struct dquot *dquot, void *dp)
-+ {
-+- struct v2_disk_dqblk *d = dp, empty;
-++ struct v2r0_disk_dqblk *d = dp, empty;
-+ struct mem_dqblk *m = &dquot->dq_dqb;
-+
-+ m->dqb_ihardlimit = le32_to_cpu(d->dqb_ihardlimit);
-+@@ -139,15 +173,15 @@
-+ m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
-+ m->dqb_btime = le64_to_cpu(d->dqb_btime);
-+ /* We need to escape back all-zero structure */
-+- memset(&empty, 0, sizeof(struct v2_disk_dqblk));
-++ memset(&empty, 0, sizeof(struct v2r0_disk_dqblk));
-+ empty.dqb_itime = cpu_to_le64(1);
-+- if (!memcmp(&empty, dp, sizeof(struct v2_disk_dqblk)))
-++ if (!memcmp(&empty, dp, sizeof(struct v2r0_disk_dqblk)))
-+ m->dqb_itime = 0;
-+ }
-+
-+-static void v2_mem2diskdqb(void *dp, struct dquot *dquot)
-++static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot)
-+ {
-+- struct v2_disk_dqblk *d = dp;
-++ struct v2r0_disk_dqblk *d = dp;
-+ struct mem_dqblk *m = &dquot->dq_dqb;
-+ struct qtree_mem_dqinfo *info =
-+ &sb_dqinfo(dquot->dq_sb, dquot->dq_type)->u.v2_i.i;
-+@@ -165,9 +199,60 @@
-+ d->dqb_itime = cpu_to_le64(1);
-+ }
-+
-+-static int v2_is_id(void *dp, struct dquot *dquot)
-++static int v2r0_is_id(void *dp, struct dquot *dquot)
-++{
-++ struct v2r0_disk_dqblk *d = dp;
-++ struct qtree_mem_dqinfo *info =
-++ sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
-++
-++ if (qtree_entry_unused(info, dp))
-++ return 0;
-++ return le32_to_cpu(d->dqb_id) == dquot->dq_id;
-++}
-++
-++static void v2r1_disk2memdqb(struct dquot *dquot, void *dp)
-++{
-++ struct v2r1_disk_dqblk *d = dp, empty;
-++ struct mem_dqblk *m = &dquot->dq_dqb;
-++
-++ m->dqb_ihardlimit = le64_to_cpu(d->dqb_ihardlimit);
-++ m->dqb_isoftlimit = le64_to_cpu(d->dqb_isoftlimit);
-++ m->dqb_curinodes = le64_to_cpu(d->dqb_curinodes);
-++ m->dqb_itime = le64_to_cpu(d->dqb_itime);
-++ m->dqb_bhardlimit = v2_qbtos(le64_to_cpu(d->dqb_bhardlimit));
-++ m->dqb_bsoftlimit = v2_qbtos(le64_to_cpu(d->dqb_bsoftlimit));
-++ m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
-++ m->dqb_btime = le64_to_cpu(d->dqb_btime);
-++ /* We need to escape back all-zero structure */
-++ memset(&empty, 0, sizeof(struct v2r1_disk_dqblk));
-++ empty.dqb_itime = cpu_to_le64(1);
-++ if (!memcmp(&empty, dp, sizeof(struct v2r1_disk_dqblk)))
-++ m->dqb_itime = 0;
-++}
-++
-++static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot)
-++{
-++ struct v2r1_disk_dqblk *d = dp;
-++ struct mem_dqblk *m = &dquot->dq_dqb;
-++ struct qtree_mem_dqinfo *info =
-++ sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
-++
-++ d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit);
-++ d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit);
-++ d->dqb_curinodes = cpu_to_le64(m->dqb_curinodes);
-++ d->dqb_itime = cpu_to_le64(m->dqb_itime);
-++ d->dqb_bhardlimit = cpu_to_le64(v2_stoqb(m->dqb_bhardlimit));
-++ d->dqb_bsoftlimit = cpu_to_le64(v2_stoqb(m->dqb_bsoftlimit));
-++ d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
-++ d->dqb_btime = cpu_to_le64(m->dqb_btime);
-++ d->dqb_id = cpu_to_le32(dquot->dq_id);
-++ if (qtree_entry_unused(info, dp))
-++ d->dqb_itime = cpu_to_le64(1);
-++}
-++
-++static int v2r1_is_id(void *dp, struct dquot *dquot)
-+ {
-+- struct v2_disk_dqblk *d = dp;
-++ struct v2r1_disk_dqblk *d = dp;
-+ struct qtree_mem_dqinfo *info =
-+ &sb_dqinfo(dquot->dq_sb, dquot->dq_type)->u.v2_i.i;
-+
-+Index: linux-2.6.27.36/include/linux/quotaio_v2.h
-+===================================================================
-+--- linux-2.6.27.36.orig/include/linux/quotaio_v2.h 2009-10-09 17:00:48.000000000 +0200
-++++ linux-2.6.27.36/include/linux/quotaio_v2.h 2009-10-09 17:00:56.000000000 +0200
-+@@ -17,8 +17,8 @@
-+ }
-+
-+ #define V2_INITQVERSIONS {\
-+- 0, /* USRQUOTA */\
-+- 0 /* GRPQUOTA */\
-++ 1, /* USRQUOTA */\
-++ 1 /* GRPQUOTA */\
-+ }
-+
-+ /* First generic header */
-+@@ -28,11 +28,11 @@
-+ };
-+
-+ /*
-+- * The following structure defines the format of the disk quota file
-+- * (as it appears on disk) - the file is a radix tree whose leaves point
-+- * to blocks of these structures.
-++ * The following structure defines the format of the disk quota file in version
-++ * 0 - the file is a radix tree whose leaves point to blocks of these
-++ * structures.
-+ */
-+-struct v2_disk_dqblk {
-++struct v2r0_disk_dqblk {
-+ __le32 dqb_id; /* id this quota applies to */
-+ __le32 dqb_ihardlimit; /* absolute limit on allocated inodes */
-+ __le32 dqb_isoftlimit; /* preferred inode limit */
-+@@ -44,6 +44,20 @@
-+ __le64 dqb_itime; /* time limit for excessive inode use */
-+ };
-+
-++/* The same structure in quota file version 1 */
-++struct v2r1_disk_dqblk {
-++ __le32 dqb_id; /* id this quota applies to */
-++ __le32 dqb_padding; /* padding field */
-++ __le64 dqb_ihardlimit; /* absolute limit on allocated inodes */
-++ __le64 dqb_isoftlimit; /* preferred inode limit */
-++ __le64 dqb_curinodes; /* current # allocated inodes */
-++ __le64 dqb_bhardlimit; /* absolute limit on disk space */
-++ __le64 dqb_bsoftlimit; /* preferred limit on disk space */
-++ __le64 dqb_curspace; /* current space occupied (in bytes) */
-++ __le64 dqb_btime; /* time limit for excessive disk use */
-++ __le64 dqb_itime; /* time limit for excessive inode use */
-++};
-++
-+ /* Header with type and version specific information */
-+ struct v2_disk_dqinfo {
-+ __le32 dqi_bgrace; /* Time before block soft limit becomes hard limit */
---- /dev/null
-+++ lustre-1.8.5+dfsg/lustre/kernel_patches/patches/sd_iostats-2.6.26-vanilla.patch
-@@ -0,0 +1,579 @@
-+Index: linux-source-2.6.26/drivers/scsi/Kconfig
-+===================================================================
-+--- linux-source-2.6.26.orig/drivers/scsi/Kconfig 2009-10-09 13:33:25.000000000 +0200
-++++ linux-source-2.6.26/drivers/scsi/Kconfig 2009-10-09 13:39:06.000000000 +0200
-+@@ -81,6 +81,14 @@
-+ In this case, do not compile the driver for your SCSI host adapter
-+ (below) as a module either.
-+
-++config SD_IOSTATS
-++ bool "Enable SCSI disk I/O stats"
-++ depends on BLK_DEV_SD
-++ default y
-++ ---help---
-++ This enables SCSI disk I/O stats collection. You must also enable
-++ /proc file system support if you want this feature.
-++
-+ config CHR_DEV_ST
-+ tristate "SCSI tape support"
-+ depends on SCSI
-+Index: linux-source-2.6.26/drivers/scsi/scsi_proc.c
-+===================================================================
-+--- linux-source-2.6.26.orig/drivers/scsi/scsi_proc.c 2009-10-09 13:33:25.000000000 +0200
-++++ linux-source-2.6.26/drivers/scsi/scsi_proc.c 2009-10-09 13:39:06.000000000 +0200
-+@@ -40,7 +40,8 @@
-+ /* 4K page size, but our output routines, use some slack for overruns */
-+ #define PROC_BLOCK_SIZE (3*1024)
-+
-+-static struct proc_dir_entry *proc_scsi;
-++struct proc_dir_entry *proc_scsi;
-++EXPORT_SYMBOL(proc_scsi);
-+
-+ /* Protect sht->present and sht->proc_dir */
-+ static DEFINE_MUTEX(global_host_template_mutex);
-+Index: linux-source-2.6.26/drivers/scsi/sd.c
-+===================================================================
-+--- linux-source-2.6.26.orig/drivers/scsi/sd.c 2009-10-09 13:33:25.000000000 +0200
-++++ linux-source-2.6.26/drivers/scsi/sd.c 2009-10-09 13:39:50.000000000 +0200
-+@@ -107,6 +107,24 @@
-+ * object after last put) */
-+ static DEFINE_MUTEX(sd_ref_mutex);
-+
-++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-++# include <linux/proc_fs.h>
-++# include <linux/seq_file.h>
-++struct proc_dir_entry *sd_iostats_procdir = NULL;
-++char sd_iostats_procdir_name[] = "sd_iostats";
-++static struct file_operations sd_iostats_proc_fops;
-++
-++extern void sd_iostats_init(void);
-++extern void sd_iostats_fini(void);
-++void sd_iostats_start_req(struct scsi_cmnd *SCpnt);
-++void sd_iostats_finish_req(struct scsi_cmnd *SCpnt);
-++#else
-++static inline void sd_iostats_init(void) {}
-++static inline void sd_iostats_fini(void) {}
-++static inline void sd_iostats_start_req(struct scsi_cmnd *SCpnt) {}
-++static inline void sd_iostats_finish_req(struct scsi_cmnd *SCpnt) {}
-++#endif
-++
-+ static const char *sd_cache_types[] = {
-+ "write through", "none", "write back",
-+ "write back, no read (daft)"
-+@@ -578,6 +596,8 @@
-+
-+ sdev = sdkp->device;
-+
-++ sd_iostats_start_req(SCpnt);
-++
-+ /*
-+ * If the device is in error recovery, wait until it is done.
-+ * If the device is offline, then disallow any access to it.
-+@@ -1023,6 +1043,7 @@
-+ break;
-+ }
-+ out:
-++ sd_iostats_finish_req(SCpnt);
-+ return good_bytes;
-+ }
-+
-+@@ -1712,6 +1733,36 @@
-+ if (sdp->removable)
-+ gd->flags |= GENHD_FL_REMOVABLE;
-+
-++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-++ sdkp->stats = kzalloc(sizeof(iostat_stats_t), GFP_KERNEL);
-++ if (!sdkp->stats) {
-++ printk(KERN_WARNING "cannot allocate iostat structure for"
-++ "%s\n", gd->disk_name);
-++ } else {
-++ do_gettimeofday(&sdkp->stats->iostat_timeval);
-++ sdkp->stats->iostat_queue_stamp = jiffies;
-++ spin_lock_init(&sdkp->stats->iostat_lock);
-++ if (sd_iostats_procdir) {
-++ struct proc_dir_entry *pde;
-++ pde = create_proc_entry(gd->disk_name, S_IRUGO | S_IWUSR,
-++ sd_iostats_procdir);
-++ if (!pde) {
-++ printk(KERN_WARNING "Can't create /proc/scsi/"
-++ "%s/%s\n",
-++ sd_iostats_procdir_name,
-++ gd->disk_name);
-++ kfree(sdkp->stats);
-++ sdkp->stats = NULL;
-++ } else {
-++ pde->proc_fops = &sd_iostats_proc_fops;
-++ pde->data = gd;
-++ }
-++ } else {
-++ kfree(sdkp->stats);
-++ sdkp->stats = NULL;
-++ }
-++ }
-++#endif
-+ dev_set_drvdata(dev, sdkp);
-+ add_disk(gd);
-+
-+@@ -1755,6 +1806,366 @@
-+ return 0;
-+ }
-+
-++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-++static int
-++sd_iostats_seq_show(struct seq_file *seq, void *v)
-++{
-++ struct timeval now;
-++ struct gendisk *disk = seq->private;
-++ iostat_stats_t *stats;
-++ unsigned long long read_len;
-++ unsigned long long read_len_tot;
-++ unsigned long read_num;
-++ unsigned long read_num_tot;
-++ unsigned long long write_len;
-++ unsigned long long write_len_tot;
-++ unsigned long write_num;
-++ unsigned long write_num_tot;
-++ int i;
-++ int maxi;
-++
-++ stats = scsi_disk(disk)->stats;
-++ if (stats == NULL) {
-++ printk(KERN_ERR "sd_iostats_seq_show: NULL stats entry\n");
-++ BUG();
-++ }
-++
-++ do_gettimeofday(&now);
-++ now.tv_sec -= stats->iostat_timeval.tv_sec;
-++ now.tv_usec -= stats->iostat_timeval.tv_usec;
-++ if (now.tv_usec < 0) {
-++ now.tv_usec += 1000000;
-++ now.tv_sec--;
-++ }
-++
-++ /* this sampling races with updates */
-++ seq_printf(seq, "index: %lu snapshot_time: %lu.%06lu\n",
-++ (unsigned long) scsi_disk(disk)->index,
-++ now.tv_sec, now.tv_usec);
-++
-++ for (i = IOSTAT_NCOUNTERS - 1; i > 0; i--)
-++ if (stats->iostat_read_histogram[i].iostat_count != 0 ||
-++ stats->iostat_write_histogram[i].iostat_count != 0)
-++ break;
-++ maxi = i;
-++
-++ seq_printf(seq, "%8s %8s %12s %8s %12s\n", "size",
-++ "reads", "total", "writes", "total");
-++
-++ read_len_tot = write_len_tot = 0;
-++ read_num_tot = write_num_tot = 0;
-++ for (i = 0; i <= maxi; i++) {
-++ read_len = stats->iostat_read_histogram[i].iostat_size;
-++ read_len_tot += read_len;
-++ read_num = stats->iostat_read_histogram[i].iostat_count;
-++ read_num_tot += read_num;
-++
-++ write_len = stats->iostat_write_histogram[i].iostat_size;
-++ write_len_tot += write_len;
-++ write_num = stats->iostat_write_histogram[i].iostat_count;
-++ write_num_tot += write_num;
-++
-++ seq_printf (seq, "%8d %8lu %12llu %8lu %12llu\n",
-++ 512<<i, read_num, read_len, write_num, write_len);
-++ }
-++
-++ seq_printf(seq, "%8s %8lu %12llu %8lu %12llu\n\n", "total",
-++ read_num_tot, read_len_tot,
-++ write_num_tot, write_len_tot);
-++
-++ seq_printf(seq, "%8s %8s %8s\n", "qdepth", "ticks", "%");
-++ for (i = 0; i < IOSTAT_NCOUNTERS; i++) {
-++ unsigned long long ticks, percent;
-++ ticks = stats->iostat_queue_ticks[i];
-++ if (ticks == 0)
-++ continue;
-++ percent = stats->iostat_queue_ticks[i] * 100;
-++ do_div(percent, stats->iostat_queue_ticks_sum);
-++ seq_printf(seq, "%8d %8llu %8llu\n", i, ticks, percent);
-++ }
-++
-++ if (stats->iostat_reqs != 0) {
-++ unsigned long long aveseek = 0, percent = 0;
-++
-++ if (stats->iostat_seeks) {
-++ aveseek = stats->iostat_seek_sectors;
-++ do_div(aveseek, stats->iostat_seeks);
-++ percent = stats->iostat_seeks * 100;
-++ do_div(percent, stats->iostat_reqs);
-++ }
-++
-++ seq_printf(seq, "\n%llu sectors in %llu reqs: %llu seek(s) over "
-++ "%llu sectors in ave, %llu%% of all reqs\n",
-++ stats->iostat_sectors, stats->iostat_reqs,
-++ stats->iostat_seeks, aveseek, percent);
-++ }
-++
-++ seq_printf(seq, "\n%16s %8s %8s %8s %8s\n", "process time", "reads",
-++ "%%", "writes", "%%");
-++ for (i = 0; i < IOSTAT_NCOUNTERS; i++) {
-++ unsigned long read_percent = 0, write_percent = 0;
-++ if (stats->iostat_wtime[i] == 0 &&
-++ stats->iostat_rtime[i] == 0)
-++ continue;
-++ if (stats->iostat_read_reqs)
-++ read_percent = stats->iostat_rtime[i] * 100 /
-++ stats->iostat_read_reqs;
-++ if (stats->iostat_write_reqs)
-++ write_percent = stats->iostat_wtime[i] * 100 /
-++ stats->iostat_write_reqs;
-++ seq_printf(seq, "%16u %8lu %8lu %8lu %8lu\n",
-++ jiffies_to_msecs(((1UL << i) >> 1) << 1),
-++ stats->iostat_rtime[i], read_percent,
-++ stats->iostat_wtime[i], write_percent);
-++ }
-++
-++ seq_printf(seq, "\n%16s %8s %8s %8s %8s\n", "time in queue", "reads",
-++ "%%", "writes", "%%");
-++ for (i = 0; i < IOSTAT_NCOUNTERS; i++) {
-++ unsigned long read_percent = 0, write_percent = 0;
-++ if (stats->iostat_wtime_in_queue[i] == 0 &&
-++ stats->iostat_rtime_in_queue[i] == 0)
-++ continue;
-++ if (stats->iostat_read_reqs)
-++ read_percent = stats->iostat_rtime_in_queue[i] * 100 /
-++ stats->iostat_read_reqs;
-++ if (stats->iostat_write_reqs)
-++ write_percent = stats->iostat_wtime_in_queue[i] * 100 /
-++ stats->iostat_write_reqs;
-++ seq_printf(seq, "%16u %8lu %8lu %8lu %8lu\n",
-++ jiffies_to_msecs(((1UL << i) >> 1) << 1),
-++ stats->iostat_rtime_in_queue[i],
-++ read_percent,
-++ stats->iostat_wtime_in_queue[i],
-++ write_percent);
-++ }
-++
-++ return 0;
-++}
-++
-++static void *
-++sd_iostats_seq_start(struct seq_file *p, loff_t *pos)
-++{
-++ return (*pos == 0) ? (void *)1 : NULL;
-++}
-++
-++static void *
-++sd_iostats_seq_next(struct seq_file *p, void *v, loff_t *pos)
-++{
-++ ++*pos;
-++ return NULL;
-++}
-++
-++static void
-++sd_iostats_seq_stop(struct seq_file *p, void *v)
-++{
-++}
-++
-++static struct seq_operations sd_iostats_seqops = {
-++ .start = sd_iostats_seq_start,
-++ .stop = sd_iostats_seq_stop,
-++ .next = sd_iostats_seq_next,
-++ .show = sd_iostats_seq_show,
-++};
-++
-++static int
-++sd_iostats_seq_open (struct inode *inode, struct file *file)
-++{
-++ int rc;
-++
-++ rc = seq_open(file, &sd_iostats_seqops);
-++ if (rc != 0)
-++ return rc;
-++
-++ ((struct seq_file *)file->private_data)->private = PDE(inode)->data;
-++ return 0;
-++}
-++
-++static ssize_t
-++sd_iostats_seq_write(struct file *file, const char *buffer,
-++ size_t len, loff_t *off)
-++{
-++ struct seq_file *seq = file->private_data;
-++ struct gendisk *disk = seq->private;
-++ iostat_stats_t *stats = scsi_disk(disk)->stats;
-++ unsigned long flags;
-++ unsigned long qdepth;
-++
-++
-++ spin_lock_irqsave (&stats->iostat_lock, flags);
-++ qdepth = stats->iostat_queue_depth;
-++ memset (stats, 0, offsetof(iostat_stats_t, iostat_lock));
-++ do_gettimeofday(&stats->iostat_timeval);
-++ stats->iostat_queue_stamp = jiffies;
-++ stats->iostat_queue_depth = qdepth;
-++ spin_unlock_irqrestore (&stats->iostat_lock, flags);
-++
-++ return len;
-++}
-++
-++static struct file_operations sd_iostats_proc_fops = {
-++ .owner = THIS_MODULE,
-++ .open = sd_iostats_seq_open,
-++ .read = seq_read,
-++ .write = sd_iostats_seq_write,
-++ .llseek = seq_lseek,
-++ .release = seq_release,
-++};
-++
-++extern struct proc_dir_entry *proc_scsi;
-++
-++void
-++sd_iostats_init(void)
-++{
-++ if (proc_scsi == NULL) {
-++ printk(KERN_WARNING "No access to sd iostats: "
-++ "proc_scsi is NULL\n");
-++ return;
-++ }
-++
-++ sd_iostats_procdir = create_proc_entry(sd_iostats_procdir_name,
-++ S_IFDIR | S_IRUGO | S_IXUGO,
-++ proc_scsi);
-++ if (sd_iostats_procdir == NULL) {
-++ printk(KERN_WARNING "No access to sd iostats: "
-++ "can't create /proc/scsi/%s\n", sd_iostats_procdir_name);
-++ return;
-++ }
-++}
-++
-++void sd_iostats_fini(void)
-++{
-++ if (proc_scsi != NULL && sd_iostats_procdir != NULL)
-++ remove_proc_entry(sd_iostats_procdir_name, proc_scsi);
-++
-++ sd_iostats_procdir = NULL;
-++}
-++
-++void sd_iostats_finish_req(struct scsi_cmnd *SCpnt)
-++{
-++ struct request *rq = SCpnt->request;
-++ iostat_stats_t *stats;
-++ unsigned long *tcounter;
-++ int tbucket;
-++ int tmp;
-++ unsigned long irqflags;
-++ unsigned long i;
-++
-++ stats = scsi_disk(rq->rq_disk)->stats;
-++ if (stats == NULL)
-++ return;
-++
-++ tmp = jiffies - rq->start_time;
-++ for (tbucket = 0; tmp > 1; tbucket++)
-++ tmp >>= 1;
-++ if (tbucket >= IOSTAT_NCOUNTERS)
-++ tbucket = IOSTAT_NCOUNTERS - 1;
-++ //printk("%u ticks in D to %u\n", jiffies - rq->start_time, tbucket);
-++
-++ tcounter = rq_data_dir(rq) == WRITE ?
-++ &stats->iostat_wtime[tbucket] : &stats->iostat_rtime[tbucket];
-++
-++ spin_lock_irqsave(&stats->iostat_lock, irqflags);
-++
-++ /* update delay stats */
-++ (*tcounter)++;
-++
-++ /* update queue depth stats */
-++ i = stats->iostat_queue_depth;
-++ if (i >= IOSTAT_NCOUNTERS)
-++ i = IOSTAT_NCOUNTERS - 1;
-++ stats->iostat_queue_ticks[i] += jiffies - stats->iostat_queue_stamp;
-++ stats->iostat_queue_ticks_sum += jiffies - stats->iostat_queue_stamp;
-++ BUG_ON(stats->iostat_queue_depth == 0);
-++ stats->iostat_queue_depth--;
-++
-++ /* update seek stats. XXX: not sure about nr_sectors */
-++ stats->iostat_sectors += rq->nr_sectors;
-++ stats->iostat_reqs++;
-++ if (rq->sector != stats->iostat_next_sector) {
-++ stats->iostat_seek_sectors +=
-++ rq->sector > stats->iostat_next_sector ?
-++ rq->sector - stats->iostat_next_sector :
-++ stats->iostat_next_sector - rq->sector;
-++ stats->iostat_seeks++;
-++ }
-++ stats->iostat_next_sector = rq->sector + rq->nr_sectors;
-++
-++ stats->iostat_queue_stamp = jiffies;
-++
-++ spin_unlock_irqrestore(&stats->iostat_lock, irqflags);
-++}
-++
-++void sd_iostats_start_req(struct scsi_cmnd *SCpnt)
-++{
-++ struct request *rq = SCpnt->request;
-++ iostat_stats_t *stats;
-++ iostat_counter_t *counter;
-++ int bucket;
-++ int tbucket;
-++ int tmp;
-++ unsigned long irqflags;
-++ unsigned long i;
-++ int nsect;
-++
-++ stats = scsi_disk(rq->rq_disk)->stats;
-++ if (stats == NULL)
-++ return;
-++
-++ nsect = scsi_bufflen(SCpnt) >> 9;
-++ for (bucket = 0, tmp = nsect; tmp > 1; bucket++)
-++ tmp >>= 1;
-++
-++ if (bucket >= IOSTAT_NCOUNTERS) {
-++ printk (KERN_ERR "sd_iostats_bump: nsect %d too big\n", nsect);
-++ BUG();
-++ }
-++
-++ counter = rq_data_dir(rq) == WRITE ?
-++ &stats->iostat_write_histogram[bucket] :
-++ &stats->iostat_read_histogram[bucket];
-++
-++ tmp = jiffies - rq->start_time;
-++ for (tbucket = 0; tmp > 1; tbucket++)
-++ tmp >>= 1;
-++ if (tbucket >= IOSTAT_NCOUNTERS)
-++ tbucket = IOSTAT_NCOUNTERS - 1;
-++ //printk("%u ticks in Q to %u\n", jiffies - rq->start_time, tbucket);
-++
-++ /* an ugly hack to know exact processing time. the right
-++ * solution is to add one more field to struct request
-++ * hopefully it will break nothing ... */
-++ rq->start_time = jiffies;
-++
-++ spin_lock_irqsave(&stats->iostat_lock, irqflags);
-++
-++ /* update queue depth stats */
-++ i = stats->iostat_queue_depth;
-++ if (i >= IOSTAT_NCOUNTERS)
-++ i = IOSTAT_NCOUNTERS - 1;
-++ stats->iostat_queue_ticks[i] += jiffies - stats->iostat_queue_stamp;
-++ stats->iostat_queue_ticks_sum += jiffies - stats->iostat_queue_stamp;
-++ stats->iostat_queue_depth++;
-++
-++ /* update delay stats */
-++ if (rq_data_dir(rq) == WRITE) {
-++ stats->iostat_wtime_in_queue[tbucket]++;
-++ stats->iostat_write_reqs++;
-++ } else {
-++ stats->iostat_rtime_in_queue[tbucket]++;
-++ stats->iostat_read_reqs++;
-++ }
-++
-++ /* update size stats */
-++ counter->iostat_size += nsect;
-++ counter->iostat_count++;
-++
-++ stats->iostat_queue_stamp = jiffies;
-++
-++ spin_unlock_irqrestore(&stats->iostat_lock, irqflags);
-++}
-++#endif
-++
-+ /**
-+ * scsi_disk_release - Called to free the scsi_disk structure
-+ * @dev: pointer to embedded class device
-+@@ -1773,10 +2184,16 @@
-+ idr_remove(&sd_index_idr, sdkp->index);
-+ spin_unlock(&sd_index_lock);
-+
-++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-++ if (sdkp->stats) {
-++ remove_proc_entry(disk->disk_name, sd_iostats_procdir);
-++ kfree(sdkp->stats);
-++ sdkp->stats = NULL;
-++ }
-++#endif
-+ disk->private_data = NULL;
-+ put_disk(disk);
-+ put_device(&sdkp->device->sdev_gendev);
-+-
-+ kfree(sdkp);
-+ }
-+
-+@@ -1890,6 +2307,8 @@
-+ if (!majors)
-+ return -ENODEV;
-+
-++ sd_iostats_init();
-++
-+ err = class_register(&sd_disk_class);
-+ if (err)
-+ goto err_out;
-+@@ -1905,6 +2324,7 @@
-+ err_out:
-+ for (i = 0; i < SD_MAJORS; i++)
-+ unregister_blkdev(sd_major(i), "sd");
-++ sd_iostats_fini();
-+ return err;
-+ }
-+
-+Index: linux-source-2.6.26/include/scsi/sd.h
-+===================================================================
-+--- linux-source-2.6.26.orig/include/scsi/sd.h 2009-10-09 13:33:25.000000000 +0200
-++++ linux-source-2.6.26/include/scsi/sd.h 2009-10-09 13:39:06.000000000 +0200
-+@@ -31,6 +31,46 @@
-+ */
-+ #define SD_BUF_SIZE 512
-+
-++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-++typedef struct {
-++ unsigned long long iostat_size;
-++ unsigned long long iostat_count;
-++} iostat_counter_t;
-++
-++#define IOSTAT_NCOUNTERS 16
-++typedef struct {
-++ iostat_counter_t iostat_read_histogram[IOSTAT_NCOUNTERS];
-++ iostat_counter_t iostat_write_histogram[IOSTAT_NCOUNTERS];
-++ struct timeval iostat_timeval;
-++
-++ /* queue depth: how well the pipe is filled up */
-++ unsigned long long iostat_queue_ticks[IOSTAT_NCOUNTERS];
-++ unsigned long long iostat_queue_ticks_sum;
-++ unsigned long iostat_queue_depth;
-++ unsigned long iostat_queue_stamp;
-++
-++ /* seeks: how linear the traffic is */
-++ unsigned long long iostat_next_sector;
-++ unsigned long long iostat_seek_sectors;
-++ unsigned long long iostat_seeks;
-++ unsigned long long iostat_sectors;
-++ unsigned long long iostat_reqs;
-++ unsigned long iostat_read_reqs;
-++ unsigned long iostat_write_reqs;
-++
-++ /* process time: how long it takes to process requests */
-++ unsigned long iostat_rtime[IOSTAT_NCOUNTERS];
-++ unsigned long iostat_wtime[IOSTAT_NCOUNTERS];
-++
-++ /* queue time: how long process spent in elevator's queue */
-++ unsigned long iostat_rtime_in_queue[IOSTAT_NCOUNTERS];
-++ unsigned long iostat_wtime_in_queue[IOSTAT_NCOUNTERS];
-++
-++ /* must be the last field, as it's used to know size to be memset'ed */
-++ spinlock_t iostat_lock;
-++} ____cacheline_aligned_in_smp iostat_stats_t;
-++#endif
-++
-+ struct scsi_disk {
-+ struct scsi_driver *driver; /* always &sd_template */
-+ struct scsi_device *device;
-+@@ -45,6 +85,9 @@
-+ unsigned WCE : 1; /* state of disk WCE bit */
-+ unsigned RCD : 1; /* state of disk RCD bit, unused */
-+ unsigned DPOFUA : 1; /* state of disk DPOFUA bit */
-++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-++ iostat_stats_t *stats; /* scsi disk statistics */
-++#endif
-+ };
-+ #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
-+
---- /dev/null
-+++ lustre-1.8.5+dfsg/lustre/kernel_patches/patches/quota-Split-off-quota-tree-handling-into-a-separate.patch
-@@ -0,0 +1,1593 @@
-+From: Jan Kara <jack at suse.cz>
-+References: fate#302681
-+Subject: [PATCH 12/28] quota: Split off quota tree handling into a separate file
-+Patch-mainline: 2.6.29?
-+
-+There is going to be a new version of quota format having 64-bit
-+quota limits and a new quota format for OCFS2. They are both
-+going to use the same tree structure as VFSv0 quota format. So
-+split out tree handling into a separate file and make size of
-+leaf blocks, amount of space usable in each block (needed for
-+checksumming) and structures contained in them configurable
-+so that the code can be shared.
-+
-+Signed-off-by: Jan Kara <jack at suse.cz>
-+---
-+ fs/Kconfig | 5
-+ fs/Makefile | 1
-+ fs/quota_tree.c | 645 ++++++++++++++++++++++++++++++++++++++++++++
-+ fs/quota_tree.h | 25 +
-+ fs/quota_v2.c | 598 +++-------------------------------------
-+ fs/quotaio_v2.h | 33 --
-+ include/linux/dqblk_qtree.h | 56 +++
-+ include/linux/dqblk_v2.h | 19 -
-+ 8 files changed, 800 insertions(+), 582 deletions(-)
-+ create mode 100644 fs/quota_tree.c
-+ create mode 100644 fs/quota_tree.h
-+ create mode 100644 include/linux/dqblk_qtree.h
-+
-+Index: linux-2.6.27.36/fs/Kconfig
-+===================================================================
-+--- linux-2.6.27.36.orig/fs/Kconfig 2009-10-05 17:19:01.000000000 +0200
-++++ linux-2.6.27.36/fs/Kconfig 2009-10-08 16:32:48.000000000 +0200
-+@@ -569,6 +569,10 @@
-+ Note that this behavior is currently deprecated and may go away in
-+ future. Please use notification via netlink socket instead.
-+
-++# Generic support for tree structured quota files. Seleted when needed.
-++config QUOTA_TREE
-++ tristate
-++
-+ config QFMT_V1
-+ tristate "Old quota format support"
-+ depends on QUOTA
-+@@ -580,6 +584,7 @@
-+ config QFMT_V2
-+ tristate "Quota format v2 support"
-+ depends on QUOTA
-++ select QUOTA_TREE
-+ help
-+ This quota format allows using quotas with 32-bit UIDs/GIDs. If you
-+ need this functionality say Y here.
-+Index: linux-2.6.27.36/fs/Makefile
-+===================================================================
-+--- linux-2.6.27.36.orig/fs/Makefile 2009-10-05 17:19:01.000000000 +0200
-++++ linux-2.6.27.36/fs/Makefile 2009-10-08 16:32:48.000000000 +0200
-+@@ -53,6 +53,7 @@
-+ obj-$(CONFIG_QUOTA) += dquot.o
-+ obj-$(CONFIG_QFMT_V1) += quota_v1.o
-+ obj-$(CONFIG_QFMT_V2) += quota_v2.o
-++obj-$(CONFIG_QUOTA_TREE) += quota_tree.o
-+ obj-$(CONFIG_QUOTACTL) += quota.o
-+
-+ obj-$(CONFIG_DNOTIFY) += dnotify.o
-+Index: linux-2.6.27.36/include/linux/quotaio_v2.h
-+===================================================================
-+--- linux-2.6.27.36.orig/include/linux/quotaio_v2.h 2009-10-05 17:19:01.000000000 +0200
-++++ linux-2.6.27.36/include/linux/quotaio_v2.h 2009-10-08 16:32:48.000000000 +0200
-+@@ -21,6 +21,12 @@
-+ 0 /* GRPQUOTA */\
-+ }
-+
-++/* First generic header */
-++struct v2_disk_dqheader {
-++ __le32 dqh_magic; /* Magic number identifying file */
-++ __le32 dqh_version; /* File version */
-++};
-++
-+ /*
-+ * The following structure defines the format of the disk quota file
-+ * (as it appears on disk) - the file is a radix tree whose leaves point
-+@@ -38,15 +44,6 @@
-+ __le64 dqb_itime; /* time limit for excessive inode use */
-+ };
-+
-+-/*
-+- * Here are header structures as written on disk and their in-memory copies
-+- */
-+-/* First generic header */
-+-struct v2_disk_dqheader {
-+- __le32 dqh_magic; /* Magic number identifying file */
-+- __le32 dqh_version; /* File version */
-+-};
-+-
-+ /* Header with type and version specific information */
-+ struct v2_disk_dqinfo {
-+ __le32 dqi_bgrace; /* Time before block soft limit becomes hard limit */
-+@@ -57,23 +54,7 @@
-+ __le32 dqi_free_entry; /* Number of block with at least one free entry */
-+ };
-+
-+-/*
-+- * Structure of header of block with quota structures. It is padded to 16 bytes so
-+- * there will be space for exactly 21 quota-entries in a block
-+- */
-+-struct v2_disk_dqdbheader {
-+- __le32 dqdh_next_free; /* Number of next block with free entry */
-+- __le32 dqdh_prev_free; /* Number of previous block with free entry */
-+- __le16 dqdh_entries; /* Number of valid entries in block */
-+- __le16 dqdh_pad1;
-+- __le32 dqdh_pad2;
-+-};
-+-
-+ #define V2_DQINFOOFF sizeof(struct v2_disk_dqheader) /* Offset of info header in file */
-+-#define V2_DQBLKSIZE_BITS 10
-+-#define V2_DQBLKSIZE (1 << V2_DQBLKSIZE_BITS) /* Size of block with quota structures */
-+-#define V2_DQTREEOFF 1 /* Offset of tree in file in blocks */
-+-#define V2_DQTREEDEPTH 4 /* Depth of quota tree */
-+-#define V2_DQSTRINBLK ((V2_DQBLKSIZE - sizeof(struct v2_disk_dqdbheader)) / sizeof(struct v2_disk_dqblk)) /* Number of entries in one blocks */
-++#define V2_DQBLKSIZE_BITS 10 /* Size of leaf block in tree */
-+
-+ #endif /* _LINUX_QUOTAIO_V2_H */
-+Index: linux-2.6.27.36/fs/quota_tree.c
-+===================================================================
-+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-++++ linux-2.6.27.36/fs/quota_tree.c 2009-10-08 16:32:48.000000000 +0200
-+@@ -0,0 +1,645 @@
-++/*
-++ * vfsv0 quota IO operations on file
-++ */
-++
-++#include <linux/errno.h>
-++#include <linux/fs.h>
-++#include <linux/mount.h>
-++#include <linux/dqblk_v2.h>
-++#include <linux/kernel.h>
-++#include <linux/init.h>
-++#include <linux/module.h>
-++#include <linux/slab.h>
-++#include <linux/quotaops.h>
-++
-++#include <asm/byteorder.h>
-++
-++#include "quota_tree.h"
-++
-++MODULE_AUTHOR("Jan Kara");
-++MODULE_DESCRIPTION("Quota trie support");
-++MODULE_LICENSE("GPL");
-++
-++#define __QUOTA_QT_PARANOIA
-++
-++typedef char *dqbuf_t;
-++
-++static int get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth)
-++{
-++ unsigned int epb = info->dqi_usable_bs >> 2;
-++
-++ depth = info->dqi_qtree_depth - depth - 1;
-++ while (depth--)
-++ id /= epb;
-++ return id % epb;
-++}
-++
-++/* Number of entries in one blocks */
-++static inline int qtree_dqstr_in_blk(struct qtree_mem_dqinfo *info)
-++{
-++ return (info->dqi_usable_bs - sizeof(struct qt_disk_dqdbheader))
-++ / info->dqi_entry_size;
-++}
-++
-++static dqbuf_t getdqbuf(size_t size)
-++{
-++ dqbuf_t buf = kmalloc(size, GFP_NOFS);
-++ if (!buf)
-++ printk(KERN_WARNING "VFS: Not enough memory for quota buffers.\n");
-++ return buf;
-++}
-++
-++static inline void freedqbuf(dqbuf_t buf)
-++{
-++ kfree(buf);
-++}
-++
-++static inline ssize_t read_blk(struct qtree_mem_dqinfo *info, uint blk, dqbuf_t buf)
-++{
-++ struct super_block *sb = info->dqi_sb;
-++
-++ memset(buf, 0, info->dqi_usable_bs);
-++ return sb->s_op->quota_read(sb, info->dqi_type, (char *)buf,
-++ info->dqi_usable_bs, blk << info->dqi_blocksize_bits);
-++}
-++
-++static inline ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, dqbuf_t buf)
-++{
-++ struct super_block *sb = info->dqi_sb;
-++
-++ return sb->s_op->quota_write(sb, info->dqi_type, (char *)buf,
-++ info->dqi_usable_bs, blk << info->dqi_blocksize_bits);
-++}
-++
-++/* Remove empty block from list and return it */
-++static int get_free_dqblk(struct qtree_mem_dqinfo *info)
-++{
-++ dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
-++ struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
-++ int ret, blk;
-++
-++ if (!buf)
-++ return -ENOMEM;
-++ if (info->dqi_free_blk) {
-++ blk = info->dqi_free_blk;
-++ ret = read_blk(info, blk, buf);
-++ if (ret < 0)
-++ goto out_buf;
-++ info->dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
-++ }
-++ else {
-++ memset(buf, 0, info->dqi_usable_bs);
-++ /* Assure block allocation... */
-++ ret = write_blk(info, info->dqi_blocks, buf);
-++ if (ret < 0)
-++ goto out_buf;
-++ blk = info->dqi_blocks++;
-++ }
-++ mark_info_dirty(info->dqi_sb, info->dqi_type);
-++ ret = blk;
-++out_buf:
-++ freedqbuf(buf);
-++ return ret;
-++}
-++
-++/* Insert empty block to the list */
-++static int put_free_dqblk(struct qtree_mem_dqinfo *info, dqbuf_t buf, uint blk)
-++{
-++ struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
-++ int err;
-++
-++ dh->dqdh_next_free = cpu_to_le32(info->dqi_free_blk);
-++ dh->dqdh_prev_free = cpu_to_le32(0);
-++ dh->dqdh_entries = cpu_to_le16(0);
-++ err = write_blk(info, blk, buf);
-++ if (err < 0)
-++ return err;
-++ info->dqi_free_blk = blk;
-++ mark_info_dirty(info->dqi_sb, info->dqi_type);
-++ return 0;
-++}
-++
-++/* Remove given block from the list of blocks with free entries */
-++static int remove_free_dqentry(struct qtree_mem_dqinfo *info, dqbuf_t buf, uint blk)
-++{
-++ dqbuf_t tmpbuf = getdqbuf(info->dqi_usable_bs);
-++ struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
-++ uint nextblk = le32_to_cpu(dh->dqdh_next_free);
-++ uint prevblk = le32_to_cpu(dh->dqdh_prev_free);
-++ int err;
-++
-++ if (!tmpbuf)
-++ return -ENOMEM;
-++ if (nextblk) {
-++ err = read_blk(info, nextblk, tmpbuf);
-++ if (err < 0)
-++ goto out_buf;
-++ ((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_prev_free =
-++ dh->dqdh_prev_free;
-++ err = write_blk(info, nextblk, tmpbuf);
-++ if (err < 0)
-++ goto out_buf;
-++ }
-++ if (prevblk) {
-++ err = read_blk(info, prevblk, tmpbuf);
-++ if (err < 0)
-++ goto out_buf;
-++ ((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_next_free =
-++ dh->dqdh_next_free;
-++ err = write_blk(info, prevblk, tmpbuf);
-++ if (err < 0)
-++ goto out_buf;
-++ } else {
-++ info->dqi_free_entry = nextblk;
-++ mark_info_dirty(info->dqi_sb, info->dqi_type);
-++ }
-++ freedqbuf(tmpbuf);
-++ dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
-++ /* No matter whether write succeeds block is out of list */
-++ if (write_blk(info, blk, buf) < 0)
-++ printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk);
-++ return 0;
-++out_buf:
-++ freedqbuf(tmpbuf);
-++ return err;
-++}
-++
-++/* Insert given block to the beginning of list with free entries */
-++static int insert_free_dqentry(struct qtree_mem_dqinfo *info, dqbuf_t buf, uint blk)
-++{
-++ dqbuf_t tmpbuf = getdqbuf(info->dqi_usable_bs);
-++ struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
-++ int err;
-++
-++ if (!tmpbuf)
-++ return -ENOMEM;
-++ dh->dqdh_next_free = cpu_to_le32(info->dqi_free_entry);
-++ dh->dqdh_prev_free = cpu_to_le32(0);
-++ err = write_blk(info, blk, buf);
-++ if (err < 0)
-++ goto out_buf;
-++ if (info->dqi_free_entry) {
-++ err = read_blk(info, info->dqi_free_entry, tmpbuf);
-++ if (err < 0)
-++ goto out_buf;
-++ ((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_prev_free =
-++ cpu_to_le32(blk);
-++ err = write_blk(info, info->dqi_free_entry, tmpbuf);
-++ if (err < 0)
-++ goto out_buf;
-++ }
-++ freedqbuf(tmpbuf);
-++ info->dqi_free_entry = blk;
-++ mark_info_dirty(info->dqi_sb, info->dqi_type);
-++ return 0;
-++out_buf:
-++ freedqbuf(tmpbuf);
-++ return err;
-++}
-++
-++/* Is the entry in the block free? */
-++int qtree_entry_unused(struct qtree_mem_dqinfo *info, char *disk)
-++{
-++ int i;
-++
-++ for (i = 0; i < info->dqi_entry_size; i++)
-++ if (disk[i])
-++ return 0;
-++ return 1;
-++}
-++EXPORT_SYMBOL(qtree_entry_unused);
-++
-++/* Find space for dquot */
-++static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
-++ struct dquot *dquot, int *err)
-++{
-++ uint blk, i;
-++ struct qt_disk_dqdbheader *dh;
-++ dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
-++ char *ddquot;
-++
-++ *err = 0;
-++ if (!buf) {
-++ *err = -ENOMEM;
-++ return 0;
-++ }
-++ dh = (struct qt_disk_dqdbheader *)buf;
-++ if (info->dqi_free_entry) {
-++ blk = info->dqi_free_entry;
-++ *err = read_blk(info, blk, buf);
-++ if (*err < 0)
-++ goto out_buf;
-++ } else {
-++ blk = get_free_dqblk(info);
-++ if ((int)blk < 0) {
-++ *err = blk;
-++ freedqbuf(buf);
-++ return 0;
-++ }
-++ memset(buf, 0, info->dqi_usable_bs);
-++ /* This is enough as block is already zeroed and entry list is empty... */
-++ info->dqi_free_entry = blk;
-++ mark_info_dirty(dquot->dq_sb, dquot->dq_type);
-++ }
-++ /* Block will be full? */
-++ if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) {
-++ *err = remove_free_dqentry(info, buf, blk);
-++ if (*err < 0) {
-++ printk(KERN_ERR "VFS: find_free_dqentry(): Can't "
-++ "remove block (%u) from entry free list.\n",
-++ blk);
-++ goto out_buf;
-++ }
-++ }
-++ le16_add_cpu(&dh->dqdh_entries, 1);
-++ /* Find free structure in block */
-++ for (i = 0, ddquot = ((char *)buf) + sizeof(struct qt_disk_dqdbheader);
-++ i < qtree_dqstr_in_blk(info) && !qtree_entry_unused(info, ddquot);
-++ i++, ddquot += info->dqi_entry_size);
-++#ifdef __QUOTA_QT_PARANOIA
-++ if (i == qtree_dqstr_in_blk(info)) {
-++ printk(KERN_ERR "VFS: find_free_dqentry(): Data block full "
-++ "but it shouldn't.\n");
-++ *err = -EIO;
-++ goto out_buf;
-++ }
-++#endif
-++ *err = write_blk(info, blk, buf);
-++ if (*err < 0) {
-++ printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota "
-++ "data block %u.\n", blk);
-++ goto out_buf;
-++ }
-++ dquot->dq_off = (blk << info->dqi_blocksize_bits) +
-++ sizeof(struct qt_disk_dqdbheader) +
-++ i * info->dqi_entry_size;
-++ freedqbuf(buf);
-++ return blk;
-++out_buf:
-++ freedqbuf(buf);
-++ return 0;
-++}
-++
-++/* Insert reference to structure into the trie */
-++static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
-++ uint *treeblk, int depth)
-++{
-++ dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
-++ int ret = 0, newson = 0, newact = 0;
-++ __le32 *ref;
-++ uint newblk;
-++
-++ if (!buf)
-++ return -ENOMEM;
-++ if (!*treeblk) {
-++ ret = get_free_dqblk(info);
-++ if (ret < 0)
-++ goto out_buf;
-++ *treeblk = ret;
-++ memset(buf, 0, info->dqi_usable_bs);
-++ newact = 1;
-++ } else {
-++ ret = read_blk(info, *treeblk, buf);
-++ if (ret < 0) {
-++ printk(KERN_ERR "VFS: Can't read tree quota block "
-++ "%u.\n", *treeblk);
-++ goto out_buf;
-++ }
-++ }
-++ ref = (__le32 *)buf;
-++ newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
-++ if (!newblk)
-++ newson = 1;
-++ if (depth == info->dqi_qtree_depth - 1) {
-++#ifdef __QUOTA_QT_PARANOIA
-++ if (newblk) {
-++ printk(KERN_ERR "VFS: Inserting already present quota "
-++ "entry (block %u).\n",
-++ le32_to_cpu(ref[get_index(info,
-++ dquot->dq_id, depth)]));
-++ ret = -EIO;
-++ goto out_buf;
-++ }
-++#endif
-++ newblk = find_free_dqentry(info, dquot, &ret);
-++ } else {
-++ ret = do_insert_tree(info, dquot, &newblk, depth+1);
-++ }
-++ if (newson && ret >= 0) {
-++ ref[get_index(info, dquot->dq_id, depth)] =
-++ cpu_to_le32(newblk);
-++ ret = write_blk(info, *treeblk, buf);
-++ } else if (newact && ret < 0) {
-++ put_free_dqblk(info, buf, *treeblk);
-++ }
-++out_buf:
-++ freedqbuf(buf);
-++ return ret;
-++}
-++
-++/* Wrapper for inserting quota structure into tree */
-++static inline int dq_insert_tree(struct qtree_mem_dqinfo *info,
-++ struct dquot *dquot)
-++{
-++ int tmp = QT_TREEOFF;
-++ return do_insert_tree(info, dquot, &tmp, 0);
-++}
-++
-++/*
-++ * We don't have to be afraid of deadlocks as we never have quotas on quota files...
-++ */
-++int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
-++{
-++ int type = dquot->dq_type;
-++ struct super_block *sb = dquot->dq_sb;
-++ ssize_t ret;
-++ dqbuf_t ddquot = getdqbuf(info->dqi_entry_size);
-++
-++ if (!ddquot)
-++ return -ENOMEM;
-++
-++ /* dq_off is guarded by dqio_mutex */
-++ if (!dquot->dq_off) {
-++ ret = dq_insert_tree(info, dquot);
-++ if (ret < 0) {
-++ printk(KERN_ERR "VFS: Error %zd occurred while "
-++ "creating quota.\n", ret);
-++ freedqbuf(ddquot);
-++ return ret;
-++ }
-++ }
-++ spin_lock(&dq_data_lock);
-++ info->dqi_ops->mem2disk_dqblk(ddquot, dquot);
-++ spin_unlock(&dq_data_lock);
-++ ret = sb->s_op->quota_write(sb, type, (char *)ddquot,
-++ info->dqi_entry_size, dquot->dq_off);
-++ if (ret != info->dqi_entry_size) {
-++ printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
-++ sb->s_id);
-++ if (ret >= 0)
-++ ret = -ENOSPC;
-++ } else {
-++ ret = 0;
-++ }
-++ dqstats.writes++;
-++ freedqbuf(ddquot);
-++
-++ return ret;
-++}
-++EXPORT_SYMBOL(qtree_write_dquot);
-++
-++/* Free dquot entry in data block */
-++static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
-++ uint blk)
-++{
-++ struct qt_disk_dqdbheader *dh;
-++ dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
-++ int ret = 0;
-++
-++ if (!buf)
-++ return -ENOMEM;
-++ if (dquot->dq_off >> info->dqi_blocksize_bits != blk) {
-++ printk(KERN_ERR "VFS: Quota structure has offset to other "
-++ "block (%u) than it should (%u).\n", blk,
-++ (uint)(dquot->dq_off >> info->dqi_blocksize_bits));
-++ goto out_buf;
-++ }
-++ ret = read_blk(info, blk, buf);
-++ if (ret < 0) {
-++ printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk);
-++ goto out_buf;
-++ }
-++ dh = (struct qt_disk_dqdbheader *)buf;
-++ le16_add_cpu(&dh->dqdh_entries, -1);
-++ if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */
-++ ret = remove_free_dqentry(info, buf, blk);
-++ if (ret >= 0)
-++ ret = put_free_dqblk(info, buf, blk);
-++ if (ret < 0) {
-++ printk(KERN_ERR "VFS: Can't move quota data block (%u) "
-++ "to free list.\n", blk);
-++ goto out_buf;
-++ }
-++ } else {
-++ memset(buf +
-++ (dquot->dq_off & ((1 << info->dqi_blocksize_bits) - 1)),
-++ 0, info->dqi_entry_size);
-++ if (le16_to_cpu(dh->dqdh_entries) ==
-++ qtree_dqstr_in_blk(info) - 1) {
-++ /* Insert will write block itself */
-++ ret = insert_free_dqentry(info, buf, blk);
-++ if (ret < 0) {
-++ printk(KERN_ERR "VFS: Can't insert quota data "
-++ "block (%u) to free entry list.\n", blk);
-++ goto out_buf;
-++ }
-++ } else {
-++ ret = write_blk(info, blk, buf);
-++ if (ret < 0) {
-++ printk(KERN_ERR "VFS: Can't write quota data "
-++ "block %u\n", blk);
-++ goto out_buf;
-++ }
-++ }
-++ }
-++ dquot->dq_off = 0; /* Quota is now unattached */
-++out_buf:
-++ freedqbuf(buf);
-++ return ret;
-++}
-++
-++/* Remove reference to dquot from tree */
-++static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
-++ uint *blk, int depth)
-++{
-++ dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
-++ int ret = 0;
-++ uint newblk;
-++ __le32 *ref = (__le32 *)buf;
-++
-++ if (!buf)
-++ return -ENOMEM;
-++ ret = read_blk(info, *blk, buf);
-++ if (ret < 0) {
-++ printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk);
-++ goto out_buf;
-++ }
-++ newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
-++ if (depth == info->dqi_qtree_depth - 1) {
-++ ret = free_dqentry(info, dquot, newblk);
-++ newblk = 0;
-++ } else {
-++ ret = remove_tree(info, dquot, &newblk, depth+1);
-++ }
-++ if (ret >= 0 && !newblk) {
-++ int i;
-++ ref[get_index(info, dquot->dq_id, depth)] = cpu_to_le32(0);
-++ /* Block got empty? */
-++ for (i = 0;
-++ i < (info->dqi_usable_bs >> 2) && !ref[i];
-++ i++);
-++ /* Don't put the root block into the free block list */
-++ if (i == (info->dqi_usable_bs >> 2)
-++ && *blk != QT_TREEOFF) {
-++ put_free_dqblk(info, buf, *blk);
-++ *blk = 0;
-++ } else {
-++ ret = write_blk(info, *blk, buf);
-++ if (ret < 0)
-++ printk(KERN_ERR "VFS: Can't write quota tree "
-++ "block %u.\n", *blk);
-++ }
-++ }
-++out_buf:
-++ freedqbuf(buf);
-++ return ret;
-++}
-++
-++/* Delete dquot from tree */
-++int qtree_delete_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
-++{
-++ uint tmp = QT_TREEOFF;
-++
-++ if (!dquot->dq_off) /* Even not allocated? */
-++ return 0;
-++ return remove_tree(info, dquot, &tmp, 0);
-++}
-++EXPORT_SYMBOL(qtree_delete_dquot);
-++
-++/* Find entry in block */
-++static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info,
-++ struct dquot *dquot, uint blk)
-++{
-++ dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
-++ loff_t ret = 0;
-++ int i;
-++ char *ddquot;
-++
-++ if (!buf)
-++ return -ENOMEM;
-++ ret = read_blk(info, blk, buf);
-++ if (ret < 0) {
-++ printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
-++ goto out_buf;
-++ }
-++ for (i = 0, ddquot = ((char *)buf) + sizeof(struct qt_disk_dqdbheader);
-++ i < qtree_dqstr_in_blk(info) && !info->dqi_ops->is_id(ddquot, dquot);
-++ i++, ddquot += info->dqi_entry_size);
-++ if (i == qtree_dqstr_in_blk(info)) {
-++ printk(KERN_ERR "VFS: Quota for id %u referenced "
-++ "but not present.\n", dquot->dq_id);
-++ ret = -EIO;
-++ goto out_buf;
-++ } else {
-++ ret = (blk << info->dqi_blocksize_bits) + sizeof(struct
-++ qt_disk_dqdbheader) + i * info->dqi_entry_size;
-++ }
-++out_buf:
-++ freedqbuf(buf);
-++ return ret;
-++}
-++
-++/* Find entry for given id in the tree */
-++static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info,
-++ struct dquot *dquot, uint blk, int depth)
-++{
-++ dqbuf_t buf = getdqbuf(info->dqi_usable_bs);
-++ loff_t ret = 0;
-++ __le32 *ref = (__le32 *)buf;
-++
-++ if (!buf)
-++ return -ENOMEM;
-++ ret = read_blk(info, blk, buf);
-++ if (ret < 0) {
-++ printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
-++ goto out_buf;
-++ }
-++ ret = 0;
-++ blk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
-++ if (!blk) /* No reference? */
-++ goto out_buf;
-++ if (depth < info->dqi_qtree_depth - 1)
-++ ret = find_tree_dqentry(info, dquot, blk, depth+1);
-++ else
-++ ret = find_block_dqentry(info, dquot, blk);
-++out_buf:
-++ freedqbuf(buf);
-++ return ret;
-++}
-++
-++/* Find entry for given id in the tree - wrapper function */
-++static inline loff_t find_dqentry(struct qtree_mem_dqinfo *info,
-++ struct dquot *dquot)
-++{
-++ return find_tree_dqentry(info, dquot, QT_TREEOFF, 0);
-++}
-++
-++int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
-++{
-++ int type = dquot->dq_type;
-++ struct super_block *sb = dquot->dq_sb;
-++ loff_t offset;
-++ dqbuf_t ddquot;
-++ int ret = 0;
-++
-++#ifdef __QUOTA_QT_PARANOIA
-++ /* Invalidated quota? */
-++ if (!sb_dqopt(dquot->dq_sb)->files[type]) {
-++ printk(KERN_ERR "VFS: Quota invalidated while reading!\n");
-++ return -EIO;
-++ }
-++#endif
-++ /* Do we know offset of the dquot entry in the quota file? */
-++ if (!dquot->dq_off) {
-++ offset = find_dqentry(info, dquot);
-++ if (offset <= 0) { /* Entry not present? */
-++ if (offset < 0)
-++ printk(KERN_ERR "VFS: Can't read quota "
-++ "structure for id %u.\n", dquot->dq_id);
-++ dquot->dq_off = 0;
-++ set_bit(DQ_FAKE_B, &dquot->dq_flags);
-++ memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
-++ ret = offset;
-++ goto out;
-++ }
-++ dquot->dq_off = offset;
-++ }
-++ ddquot = getdqbuf(info->dqi_entry_size);
-++ if (!ddquot)
-++ return -ENOMEM;
-++ ret = sb->s_op->quota_read(sb, type, (char *)ddquot,
-++ info->dqi_entry_size, dquot->dq_off);
-++ if (ret != info->dqi_entry_size) {
-++ if (ret >= 0)
-++ ret = -EIO;
-++ printk(KERN_ERR "VFS: Error while reading quota "
-++ "structure for id %u.\n", dquot->dq_id);
-++ set_bit(DQ_FAKE_B, &dquot->dq_flags);
-++ memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
-++ freedqbuf(ddquot);
-++ goto out;
-++ }
-++ spin_lock(&dq_data_lock);
-++ info->dqi_ops->disk2mem_dqblk(dquot, ddquot);
-++ if (!dquot->dq_dqb.dqb_bhardlimit &&
-++ !dquot->dq_dqb.dqb_bsoftlimit &&
-++ !dquot->dq_dqb.dqb_ihardlimit &&
-++ !dquot->dq_dqb.dqb_isoftlimit)
-++ set_bit(DQ_FAKE_B, &dquot->dq_flags);
-++ spin_unlock(&dq_data_lock);
-++ freedqbuf(ddquot);
-++out:
-++ dqstats.reads++;
-++ return ret;
-++}
-++EXPORT_SYMBOL(qtree_read_dquot);
-++
-++/* Check whether dquot should not be deleted. We know we are
-++ * the only one operating on dquot (thanks to dq_lock) */
-++int qtree_release_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
-++{
-++ if (test_bit(DQ_FAKE_B, &dquot->dq_flags) && !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace))
-++ return qtree_delete_dquot(info, dquot);
-++ return 0;
-++}
-++EXPORT_SYMBOL(qtree_release_dquot);
-+Index: linux-2.6.27.36/fs/quota_tree.h
-+===================================================================
-+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-++++ linux-2.6.27.36/fs/quota_tree.h 2009-10-08 16:32:48.000000000 +0200
-+@@ -0,0 +1,25 @@
-++/*
-++ * Definitions of structures for vfsv0 quota format
-++ */
-++
-++#ifndef _LINUX_QUOTA_TREE_H
-++#define _LINUX_QUOTA_TREE_H
-++
-++#include <linux/types.h>
-++#include <linux/quota.h>
-++
-++/*
-++ * Structure of header of block with quota structures. It is padded to 16 bytes so
-++ * there will be space for exactly 21 quota-entries in a block
-++ */
-++struct qt_disk_dqdbheader {
-++ __le32 dqdh_next_free; /* Number of next block with free entry */
-++ __le32 dqdh_prev_free; /* Number of previous block with free entry */
-++ __le16 dqdh_entries; /* Number of valid entries in block */
-++ __le16 dqdh_pad1;
-++ __le32 dqdh_pad2;
-++};
-++
-++#define QT_TREEOFF 1 /* Offset of tree in file in blocks */
-++
-++#endif /* _LINUX_QUOTAIO_TREE_H */
-+Index: linux-2.6.27.36/fs/quota_v2.c
-+===================================================================
-+--- linux-2.6.27.36.orig/fs/quota_v2.c 2009-10-05 17:19:01.000000000 +0200
-++++ linux-2.6.27.36/fs/quota_v2.c 2009-10-08 16:34:36.000000000 +0200
-+@@ -6,6 +6,7 @@
-+ #include <linux/fs.h>
-+ #include <linux/mount.h>
-+ #include <linux/dqblk_v2.h>
-++#include "quota_tree.h"
-+ #include <linux/quotaio_v2.h>
-+ #include <linux/kernel.h>
-+ #include <linux/init.h>
-+@@ -15,16 +16,22 @@
-+
-+ #include <asm/byteorder.h>
-+
-++
-+ MODULE_AUTHOR("Jan Kara");
-+ MODULE_DESCRIPTION("Quota format v2 support");
-+ MODULE_LICENSE("GPL");
-+
-+ #define __QUOTA_V2_PARANOIA
-+
-+-typedef char *dqbuf_t;
-+-
-+-#define GETIDINDEX(id, depth) (((id) >> ((V2_DQTREEDEPTH-(depth)-1)*8)) & 0xff)
-+-#define GETENTRIES(buf) ((struct v2_disk_dqblk *)(((char *)buf)+sizeof(struct v2_disk_dqdbheader)))
-++static void v2_mem2diskdqb(void *dp, struct dquot *dquot);
-++static void v2_disk2memdqb(struct dquot *dquot, void *dp);
-++static int v2_is_id(void *dp, struct dquot *dquot);
-++
-++static struct qtree_fmt_operations v2_qtree_ops = {
-++ .mem2disk_dqblk = v2_mem2diskdqb,
-++ .disk2mem_dqblk = v2_disk2memdqb,
-++ .is_id = v2_is_id,
-++};
-+
-+ /* Check whether given file is really vfsv0 quotafile */
-+ static int v2_check_quota_file(struct super_block *sb, int type)
-+@@ -50,7 +57,7 @@
-+ static int v2_read_file_info(struct super_block *sb, int type)
-+ {
-+ struct v2_disk_dqinfo dinfo;
-+- struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
-++ struct mem_dqinfo *info = sb_dqinfo(sb, type);
-+ ssize_t size;
-+
-+ size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
-+@@ -66,9 +73,16 @@
-+ info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
-+ info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
-+ info->dqi_flags = le32_to_cpu(dinfo.dqi_flags);
-+- info->u.v2_i.dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
-+- info->u.v2_i.dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk);
-+- info->u.v2_i.dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry);
-++ info->u.v2_i.i.dqi_sb = sb;
-++ info->u.v2_i.i.dqi_type = type;
-++ info->u.v2_i.i.dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
-++ info->u.v2_i.i.dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk);
-++ info->u.v2_i.i.dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry);
-++ info->u.v2_i.i.dqi_blocksize_bits = V2_DQBLKSIZE_BITS;
-++ info->u.v2_i.i.dqi_usable_bs = 1 << V2_DQBLKSIZE_BITS;
-++ info->u.v2_i.i.dqi_qtree_depth = qtree_depth(&info->u.v2_i.i);
-++ info->u.v2_i.i.dqi_entry_size = sizeof(struct v2_disk_dqblk);
-++ info->u.v2_i.i.dqi_ops = &v2_qtree_ops;
-+ return 0;
-+ }
-+
-+@@ -76,7 +90,7 @@
-+ static int v2_write_file_info(struct super_block *sb, int type)
-+ {
-+ struct v2_disk_dqinfo dinfo;
-+- struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
-++ struct mem_dqinfo *info = sb_dqinfo(sb, type);
-+ ssize_t size;
-+
-+ spin_lock(&dq_data_lock);
-+@@ -85,9 +99,9 @@
-+ dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace);
-+ dinfo.dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK);
-+ spin_unlock(&dq_data_lock);
-+- dinfo.dqi_blocks = cpu_to_le32(info->u.v2_i.dqi_blocks);
-+- dinfo.dqi_free_blk = cpu_to_le32(info->u.v2_i.dqi_free_blk);
-+- dinfo.dqi_free_entry = cpu_to_le32(info->u.v2_i.dqi_free_entry);
-++ dinfo.dqi_blocks = cpu_to_le32(info->u.v2_i.i.dqi_blocks);
-++ dinfo.dqi_free_blk = cpu_to_le32(info->u.v2_i.i.dqi_free_blk);
-++ dinfo.dqi_free_entry = cpu_to_le32(info->u.v2_i.i.dqi_free_entry);
-+ size = sb->s_op->quota_write(sb, type, (char *)&dinfo,
-+ sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
-+ if (size != sizeof(struct v2_disk_dqinfo)) {
-+@@ -98,8 +112,11 @@
-+ return 0;
-+ }
-+
-+-static void disk2memdqb(struct mem_dqblk *m, struct v2_disk_dqblk *d)
-++static void v2_disk2memdqb(struct dquot *dquot, void *dp)
-+ {
-++ struct v2_disk_dqblk *d = dp, empty;
-++ struct mem_dqblk *m = &dquot->dq_dqb;
-++
-+ m->dqb_ihardlimit = le32_to_cpu(d->dqb_ihardlimit);
-+ m->dqb_isoftlimit = le32_to_cpu(d->dqb_isoftlimit);
-+ m->dqb_curinodes = le32_to_cpu(d->dqb_curinodes);
-+@@ -108,10 +125,20 @@
-+ m->dqb_bsoftlimit = le32_to_cpu(d->dqb_bsoftlimit);
-+ m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
-+ m->dqb_btime = le64_to_cpu(d->dqb_btime);
-++ /* We need to escape back all-zero structure */
-++ memset(&empty, 0, sizeof(struct v2_disk_dqblk));
-++ empty.dqb_itime = cpu_to_le64(1);
-++ if (!memcmp(&empty, dp, sizeof(struct v2_disk_dqblk)))
-++ m->dqb_itime = 0;
-+ }
-+
-+-static void mem2diskdqb(struct v2_disk_dqblk *d, struct mem_dqblk *m, qid_t id)
-++static void v2_mem2diskdqb(void *dp, struct dquot *dquot)
-+ {
-++ struct v2_disk_dqblk *d = dp;
-++ struct mem_dqblk *m = &dquot->dq_dqb;
-++ struct qtree_mem_dqinfo *info =
-++ &sb_dqinfo(dquot->dq_sb, dquot->dq_type)->u.v2_i.i;
-++
-+ d->dqb_ihardlimit = cpu_to_le32(m->dqb_ihardlimit);
-+ d->dqb_isoftlimit = cpu_to_le32(m->dqb_isoftlimit);
-+ d->dqb_curinodes = cpu_to_le32(m->dqb_curinodes);
-+@@ -120,553 +147,35 @@
-+ d->dqb_bsoftlimit = cpu_to_le32(m->dqb_bsoftlimit);
-+ d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
-+ d->dqb_btime = cpu_to_le64(m->dqb_btime);
-+- d->dqb_id = cpu_to_le32(id);
-+-}
-+-
-+-static dqbuf_t getdqbuf(void)
-+-{
-+- dqbuf_t buf = kmalloc(V2_DQBLKSIZE, GFP_NOFS);
-+- if (!buf)
-+- printk(KERN_WARNING "VFS: Not enough memory for quota buffers.\n");
-+- return buf;
-+-}
-+-
-+-static inline void freedqbuf(dqbuf_t buf)
-+-{
-+- kfree(buf);
-+-}
-+-
-+-static inline ssize_t read_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
-+-{
-+- memset(buf, 0, V2_DQBLKSIZE);
-+- return sb->s_op->quota_read(sb, type, (char *)buf,
-+- V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
-+-}
-+-
-+-static inline ssize_t write_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
-+-{
-+- return sb->s_op->quota_write(sb, type, (char *)buf,
-+- V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
-++ d->dqb_id = cpu_to_le32(dquot->dq_id);
-++ if (qtree_entry_unused(info, dp))
-++ d->dqb_itime = cpu_to_le64(1);
-+ }
-+
-+-/* Remove empty block from list and return it */
-+-static int get_free_dqblk(struct super_block *sb, int type)
-++static int v2_is_id(void *dp, struct dquot *dquot)
-+ {
-+- dqbuf_t buf = getdqbuf();
-+- struct mem_dqinfo *info = sb_dqinfo(sb, type);
-+- struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
-+- int ret, blk;
-++ struct v2_disk_dqblk *d = dp;
-++ struct qtree_mem_dqinfo *info =
-++ &sb_dqinfo(dquot->dq_sb, dquot->dq_type)->u.v2_i.i;
-+
-+- if (!buf)
-+- return -ENOMEM;
-+- if (info->u.v2_i.dqi_free_blk) {
-+- blk = info->u.v2_i.dqi_free_blk;
-+- if ((ret = read_blk(sb, type, blk, buf)) < 0)
-+- goto out_buf;
-+- info->u.v2_i.dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
-+- }
-+- else {
-+- memset(buf, 0, V2_DQBLKSIZE);
-+- /* Assure block allocation... */
-+- if ((ret = write_blk(sb, type, info->u.v2_i.dqi_blocks, buf)) < 0)
-+- goto out_buf;
-+- blk = info->u.v2_i.dqi_blocks++;
-+- }
-+- mark_info_dirty(sb, type);
-+- ret = blk;
-+-out_buf:
-+- freedqbuf(buf);
-+- return ret;
-+-}
-+-
-+-/* Insert empty block to the list */
-+-static int put_free_dqblk(struct super_block *sb, int type, dqbuf_t buf, uint blk)
-+-{
-+- struct mem_dqinfo *info = sb_dqinfo(sb, type);
-+- struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
-+- int err;
-+-
-+- dh->dqdh_next_free = cpu_to_le32(info->u.v2_i.dqi_free_blk);
-+- dh->dqdh_prev_free = cpu_to_le32(0);
-+- dh->dqdh_entries = cpu_to_le16(0);
-+- info->u.v2_i.dqi_free_blk = blk;
-+- mark_info_dirty(sb, type);
-+- /* Some strange block. We had better leave it... */
-+- if ((err = write_blk(sb, type, blk, buf)) < 0)
-+- return err;
-+- return 0;
-+-}
-+-
-+-/* Remove given block from the list of blocks with free entries */
-+-static int remove_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
-+-{
-+- dqbuf_t tmpbuf = getdqbuf();
-+- struct mem_dqinfo *info = sb_dqinfo(sb, type);
-+- struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
-+- uint nextblk = le32_to_cpu(dh->dqdh_next_free), prevblk = le32_to_cpu(dh->dqdh_prev_free);
-+- int err;
-+-
-+- if (!tmpbuf)
-+- return -ENOMEM;
-+- if (nextblk) {
-+- if ((err = read_blk(sb, type, nextblk, tmpbuf)) < 0)
-+- goto out_buf;
-+- ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = dh->dqdh_prev_free;
-+- if ((err = write_blk(sb, type, nextblk, tmpbuf)) < 0)
-+- goto out_buf;
-+- }
-+- if (prevblk) {
-+- if ((err = read_blk(sb, type, prevblk, tmpbuf)) < 0)
-+- goto out_buf;
-+- ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_next_free = dh->dqdh_next_free;
-+- if ((err = write_blk(sb, type, prevblk, tmpbuf)) < 0)
-+- goto out_buf;
-+- }
-+- else {
-+- info->u.v2_i.dqi_free_entry = nextblk;
-+- mark_info_dirty(sb, type);
-+- }
-+- freedqbuf(tmpbuf);
-+- dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
-+- /* No matter whether write succeeds block is out of list */
-+- if (write_blk(sb, type, blk, buf) < 0)
-+- printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk);
-+- return 0;
-+-out_buf:
-+- freedqbuf(tmpbuf);
-+- return err;
-+-}
-+-
-+-/* Insert given block to the beginning of list with free entries */
-+-static int insert_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
-+-{
-+- dqbuf_t tmpbuf = getdqbuf();
-+- struct mem_dqinfo *info = sb_dqinfo(sb, type);
-+- struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
-+- int err;
-+-
-+- if (!tmpbuf)
-+- return -ENOMEM;
-+- dh->dqdh_next_free = cpu_to_le32(info->u.v2_i.dqi_free_entry);
-+- dh->dqdh_prev_free = cpu_to_le32(0);
-+- if ((err = write_blk(sb, type, blk, buf)) < 0)
-+- goto out_buf;
-+- if (info->u.v2_i.dqi_free_entry) {
-+- if ((err = read_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
-+- goto out_buf;
-+- ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = cpu_to_le32(blk);
-+- if ((err = write_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
-+- goto out_buf;
-+- }
-+- freedqbuf(tmpbuf);
-+- info->u.v2_i.dqi_free_entry = blk;
-+- mark_info_dirty(sb, type);
-+- return 0;
-+-out_buf:
-+- freedqbuf(tmpbuf);
-+- return err;
-+-}
-+-
-+-/* Find space for dquot */
-+-static uint find_free_dqentry(struct dquot *dquot, int *err)
-+-{
-+- struct super_block *sb = dquot->dq_sb;
-+- struct mem_dqinfo *info = sb_dqopt(sb)->info+dquot->dq_type;
-+- uint blk, i;
-+- struct v2_disk_dqdbheader *dh;
-+- struct v2_disk_dqblk *ddquot;
-+- struct v2_disk_dqblk fakedquot;
-+- dqbuf_t buf;
-+-
-+- *err = 0;
-+- if (!(buf = getdqbuf())) {
-+- *err = -ENOMEM;
-++ if (qtree_entry_unused(info, dp))
-+ return 0;
-+- }
-+- dh = (struct v2_disk_dqdbheader *)buf;
-+- ddquot = GETENTRIES(buf);
-+- if (info->u.v2_i.dqi_free_entry) {
-+- blk = info->u.v2_i.dqi_free_entry;
-+- if ((*err = read_blk(sb, dquot->dq_type, blk, buf)) < 0)
-+- goto out_buf;
-+- }
-+- else {
-+- blk = get_free_dqblk(sb, dquot->dq_type);
-+- if ((int)blk < 0) {
-+- *err = blk;
-+- freedqbuf(buf);
-+- return 0;
-+- }
-+- memset(buf, 0, V2_DQBLKSIZE);
-+- /* This is enough as block is already zeroed and entry list is empty... */
-+- info->u.v2_i.dqi_free_entry = blk;
-+- mark_info_dirty(sb, dquot->dq_type);
-+- }
-+- if (le16_to_cpu(dh->dqdh_entries)+1 >= V2_DQSTRINBLK) /* Block will be full? */
-+- if ((*err = remove_free_dqentry(sb, dquot->dq_type, buf, blk)) < 0) {
-+- printk(KERN_ERR "VFS: find_free_dqentry(): Can't remove block (%u) from entry free list.\n", blk);
-+- goto out_buf;
-+- }
-+- le16_add_cpu(&dh->dqdh_entries, 1);
-+- memset(&fakedquot, 0, sizeof(struct v2_disk_dqblk));
-+- /* Find free structure in block */
-+- for (i = 0; i < V2_DQSTRINBLK && memcmp(&fakedquot, ddquot+i, sizeof(struct v2_disk_dqblk)); i++);
-+-#ifdef __QUOTA_V2_PARANOIA
-+- if (i == V2_DQSTRINBLK) {
-+- printk(KERN_ERR "VFS: find_free_dqentry(): Data block full but it shouldn't.\n");
-+- *err = -EIO;
-+- goto out_buf;
-+- }
-+-#endif
-+- if ((*err = write_blk(sb, dquot->dq_type, blk, buf)) < 0) {
-+- printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota data block %u.\n", blk);
-+- goto out_buf;
-+- }
-+- dquot->dq_off = (blk<<V2_DQBLKSIZE_BITS)+sizeof(struct v2_disk_dqdbheader)+i*sizeof(struct v2_disk_dqblk);
-+- freedqbuf(buf);
-+- return blk;
-+-out_buf:
-+- freedqbuf(buf);
-+- return 0;
-+-}
-+-
-+-/* Insert reference to structure into the trie */
-+-static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth)
-+-{
-+- struct super_block *sb = dquot->dq_sb;
-+- dqbuf_t buf;
-+- int ret = 0, newson = 0, newact = 0;
-+- __le32 *ref;
-+- uint newblk;
-+-
-+- if (!(buf = getdqbuf()))
-+- return -ENOMEM;
-+- if (!*treeblk) {
-+- ret = get_free_dqblk(sb, dquot->dq_type);
-+- if (ret < 0)
-+- goto out_buf;
-+- *treeblk = ret;
-+- memset(buf, 0, V2_DQBLKSIZE);
-+- newact = 1;
-+- }
-+- else {
-+- if ((ret = read_blk(sb, dquot->dq_type, *treeblk, buf)) < 0) {
-+- printk(KERN_ERR "VFS: Can't read tree quota block %u.\n", *treeblk);
-+- goto out_buf;
-+- }
-+- }
-+- ref = (__le32 *)buf;
-+- newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
-+- if (!newblk)
-+- newson = 1;
-+- if (depth == V2_DQTREEDEPTH-1) {
-+-#ifdef __QUOTA_V2_PARANOIA
-+- if (newblk) {
-+- printk(KERN_ERR "VFS: Inserting already present quota entry (block %u).\n", le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]));
-+- ret = -EIO;
-+- goto out_buf;
-+- }
-+-#endif
-+- newblk = find_free_dqentry(dquot, &ret);
-+- }
-+- else
-+- ret = do_insert_tree(dquot, &newblk, depth+1);
-+- if (newson && ret >= 0) {
-+- ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(newblk);
-+- ret = write_blk(sb, dquot->dq_type, *treeblk, buf);
-+- }
-+- else if (newact && ret < 0)
-+- put_free_dqblk(sb, dquot->dq_type, buf, *treeblk);
-+-out_buf:
-+- freedqbuf(buf);
-+- return ret;
-++ return le32_to_cpu(d->dqb_id) == dquot->dq_id;
-+ }
-+
-+-/* Wrapper for inserting quota structure into tree */
-+-static inline int dq_insert_tree(struct dquot *dquot)
-++static int v2_read_dquot(struct dquot *dquot)
-+ {
-+- int tmp = V2_DQTREEOFF;
-+- return do_insert_tree(dquot, &tmp, 0);
-++ return qtree_read_dquot(&sb_dqinfo(dquot->dq_sb, dquot->dq_type)->u.v2_i.i, dquot);
-+ }
-+
-+-/*
-+- * We don't have to be afraid of deadlocks as we never have quotas on quota files...
-+- */
-+ static int v2_write_dquot(struct dquot *dquot)
-+ {
-+- int type = dquot->dq_type;
-+- ssize_t ret;
-+- struct v2_disk_dqblk ddquot, empty;
-+-
-+- /* dq_off is guarded by dqio_mutex */
-+- if (!dquot->dq_off)
-+- if ((ret = dq_insert_tree(dquot)) < 0) {
-+- printk(KERN_ERR "VFS: Error %zd occurred while creating quota.\n", ret);
-+- return ret;
-+- }
-+- spin_lock(&dq_data_lock);
-+- mem2diskdqb(&ddquot, &dquot->dq_dqb, dquot->dq_id);
-+- /* Argh... We may need to write structure full of zeroes but that would be
-+- * treated as an empty place by the rest of the code. Format change would
-+- * be definitely cleaner but the problems probably are not worth it */
-+- memset(&empty, 0, sizeof(struct v2_disk_dqblk));
-+- if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
-+- ddquot.dqb_itime = cpu_to_le64(1);
-+- spin_unlock(&dq_data_lock);
-+- ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type,
-+- (char *)&ddquot, sizeof(struct v2_disk_dqblk), dquot->dq_off);
-+- if (ret != sizeof(struct v2_disk_dqblk)) {
-+- printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", dquot->dq_sb->s_id);
-+- if (ret >= 0)
-+- ret = -ENOSPC;
-+- }
-+- else
-+- ret = 0;
-+- dqstats.writes++;
-+-
-+- return ret;
-+-}
-+-
-+-/* Free dquot entry in data block */
-+-static int free_dqentry(struct dquot *dquot, uint blk)
-+-{
-+- struct super_block *sb = dquot->dq_sb;
-+- int type = dquot->dq_type;
-+- struct v2_disk_dqdbheader *dh;
-+- dqbuf_t buf = getdqbuf();
-+- int ret = 0;
-+-
-+- if (!buf)
-+- return -ENOMEM;
-+- if (dquot->dq_off >> V2_DQBLKSIZE_BITS != blk) {
-+- printk(KERN_ERR "VFS: Quota structure has offset to other "
-+- "block (%u) than it should (%u).\n", blk,
-+- (uint)(dquot->dq_off >> V2_DQBLKSIZE_BITS));
-+- goto out_buf;
-+- }
-+- if ((ret = read_blk(sb, type, blk, buf)) < 0) {
-+- printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk);
-+- goto out_buf;
-+- }
-+- dh = (struct v2_disk_dqdbheader *)buf;
-+- le16_add_cpu(&dh->dqdh_entries, -1);
-+- if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */
-+- if ((ret = remove_free_dqentry(sb, type, buf, blk)) < 0 ||
-+- (ret = put_free_dqblk(sb, type, buf, blk)) < 0) {
-+- printk(KERN_ERR "VFS: Can't move quota data block (%u) "
-+- "to free list.\n", blk);
-+- goto out_buf;
-+- }
-+- }
-+- else {
-+- memset(buf+(dquot->dq_off & ((1 << V2_DQBLKSIZE_BITS)-1)), 0,
-+- sizeof(struct v2_disk_dqblk));
-+- if (le16_to_cpu(dh->dqdh_entries) == V2_DQSTRINBLK-1) {
-+- /* Insert will write block itself */
-+- if ((ret = insert_free_dqentry(sb, type, buf, blk)) < 0) {
-+- printk(KERN_ERR "VFS: Can't insert quota data block (%u) to free entry list.\n", blk);
-+- goto out_buf;
-+- }
-+- }
-+- else
-+- if ((ret = write_blk(sb, type, blk, buf)) < 0) {
-+- printk(KERN_ERR "VFS: Can't write quota data "
-+- "block %u\n", blk);
-+- goto out_buf;
-+- }
-+- }
-+- dquot->dq_off = 0; /* Quota is now unattached */
-+-out_buf:
-+- freedqbuf(buf);
-+- return ret;
-+-}
-+-
-+-/* Remove reference to dquot from tree */
-+-static int remove_tree(struct dquot *dquot, uint *blk, int depth)
-+-{
-+- struct super_block *sb = dquot->dq_sb;
-+- int type = dquot->dq_type;
-+- dqbuf_t buf = getdqbuf();
-+- int ret = 0;
-+- uint newblk;
-+- __le32 *ref = (__le32 *)buf;
-+-
-+- if (!buf)
-+- return -ENOMEM;
-+- if ((ret = read_blk(sb, type, *blk, buf)) < 0) {
-+- printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk);
-+- goto out_buf;
-+- }
-+- newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
-+- if (depth == V2_DQTREEDEPTH-1) {
-+- ret = free_dqentry(dquot, newblk);
-+- newblk = 0;
-+- }
-+- else
-+- ret = remove_tree(dquot, &newblk, depth+1);
-+- if (ret >= 0 && !newblk) {
-+- int i;
-+- ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(0);
-+- for (i = 0; i < V2_DQBLKSIZE && !buf[i]; i++); /* Block got empty? */
-+- /* Don't put the root block into the free block list */
-+- if (i == V2_DQBLKSIZE && *blk != V2_DQTREEOFF) {
-+- put_free_dqblk(sb, type, buf, *blk);
-+- *blk = 0;
-+- }
-+- else
-+- if ((ret = write_blk(sb, type, *blk, buf)) < 0)
-+- printk(KERN_ERR "VFS: Can't write quota tree "
-+- "block %u.\n", *blk);
-+- }
-+-out_buf:
-+- freedqbuf(buf);
-+- return ret;
-+-}
-+-
-+-/* Delete dquot from tree */
-+-static int v2_delete_dquot(struct dquot *dquot)
-+-{
-+- uint tmp = V2_DQTREEOFF;
-+-
-+- if (!dquot->dq_off) /* Even not allocated? */
-+- return 0;
-+- return remove_tree(dquot, &tmp, 0);
-+-}
-+-
-+-/* Find entry in block */
-+-static loff_t find_block_dqentry(struct dquot *dquot, uint blk)
-+-{
-+- dqbuf_t buf = getdqbuf();
-+- loff_t ret = 0;
-+- int i;
-+- struct v2_disk_dqblk *ddquot = GETENTRIES(buf);
-+-
-+- if (!buf)
-+- return -ENOMEM;
-+- if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
-+- printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
-+- goto out_buf;
-+- }
-+- if (dquot->dq_id)
-+- for (i = 0; i < V2_DQSTRINBLK &&
-+- le32_to_cpu(ddquot[i].dqb_id) != dquot->dq_id; i++);
-+- else { /* ID 0 as a bit more complicated searching... */
-+- struct v2_disk_dqblk fakedquot;
-+-
-+- memset(&fakedquot, 0, sizeof(struct v2_disk_dqblk));
-+- for (i = 0; i < V2_DQSTRINBLK; i++)
-+- if (!le32_to_cpu(ddquot[i].dqb_id) &&
-+- memcmp(&fakedquot, ddquot+i, sizeof(struct v2_disk_dqblk)))
-+- break;
-+- }
-+- if (i == V2_DQSTRINBLK) {
-+- printk(KERN_ERR "VFS: Quota for id %u referenced "
-+- "but not present.\n", dquot->dq_id);
-+- ret = -EIO;
-+- goto out_buf;
-+- }
-+- else
-+- ret = (blk << V2_DQBLKSIZE_BITS) + sizeof(struct
-+- v2_disk_dqdbheader) + i * sizeof(struct v2_disk_dqblk);
-+-out_buf:
-+- freedqbuf(buf);
-+- return ret;
-+-}
-+-
-+-/* Find entry for given id in the tree */
-+-static loff_t find_tree_dqentry(struct dquot *dquot, uint blk, int depth)
-+-{
-+- dqbuf_t buf = getdqbuf();
-+- loff_t ret = 0;
-+- __le32 *ref = (__le32 *)buf;
-+-
-+- if (!buf)
-+- return -ENOMEM;
-+- if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
-+- printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
-+- goto out_buf;
-+- }
-+- ret = 0;
-+- blk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
-+- if (!blk) /* No reference? */
-+- goto out_buf;
-+- if (depth < V2_DQTREEDEPTH-1)
-+- ret = find_tree_dqentry(dquot, blk, depth+1);
-+- else
-+- ret = find_block_dqentry(dquot, blk);
-+-out_buf:
-+- freedqbuf(buf);
-+- return ret;
-++ return qtree_write_dquot(&sb_dqinfo(dquot->dq_sb, dquot->dq_type)->u.v2_i.i, dquot);
-+ }
-+
-+-/* Find entry for given id in the tree - wrapper function */
-+-static inline loff_t find_dqentry(struct dquot *dquot)
-+-{
-+- return find_tree_dqentry(dquot, V2_DQTREEOFF, 0);
-+-}
-+-
-+-static int v2_read_dquot(struct dquot *dquot)
-+-{
-+- int type = dquot->dq_type;
-+- loff_t offset;
-+- struct v2_disk_dqblk ddquot, empty;
-+- int ret = 0;
-+-
-+-#ifdef __QUOTA_V2_PARANOIA
-+- /* Invalidated quota? */
-+- if (!dquot->dq_sb || !sb_dqopt(dquot->dq_sb)->files[type]) {
-+- printk(KERN_ERR "VFS: Quota invalidated while reading!\n");
-+- return -EIO;
-+- }
-+-#endif
-+- offset = find_dqentry(dquot);
-+- if (offset <= 0) { /* Entry not present? */
-+- if (offset < 0)
-+- printk(KERN_ERR "VFS: Can't read quota "
-+- "structure for id %u.\n", dquot->dq_id);
-+- dquot->dq_off = 0;
-+- set_bit(DQ_FAKE_B, &dquot->dq_flags);
-+- memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
-+- ret = offset;
-+- }
-+- else {
-+- dquot->dq_off = offset;
-+- if ((ret = dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type,
-+- (char *)&ddquot, sizeof(struct v2_disk_dqblk), offset))
-+- != sizeof(struct v2_disk_dqblk)) {
-+- if (ret >= 0)
-+- ret = -EIO;
-+- printk(KERN_ERR "VFS: Error while reading quota "
-+- "structure for id %u.\n", dquot->dq_id);
-+- memset(&ddquot, 0, sizeof(struct v2_disk_dqblk));
-+- }
-+- else {
-+- ret = 0;
-+- /* We need to escape back all-zero structure */
-+- memset(&empty, 0, sizeof(struct v2_disk_dqblk));
-+- empty.dqb_itime = cpu_to_le64(1);
-+- if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
-+- ddquot.dqb_itime = 0;
-+- }
-+- disk2memdqb(&dquot->dq_dqb, &ddquot);
-+- if (!dquot->dq_dqb.dqb_bhardlimit &&
-+- !dquot->dq_dqb.dqb_bsoftlimit &&
-+- !dquot->dq_dqb.dqb_ihardlimit &&
-+- !dquot->dq_dqb.dqb_isoftlimit)
-+- set_bit(DQ_FAKE_B, &dquot->dq_flags);
-+- }
-+- dqstats.reads++;
-+-
-+- return ret;
-+-}
-+-
-+-/* Check whether dquot should not be deleted. We know we are
-+- * the only one operating on dquot (thanks to dq_lock) */
-+ static int v2_release_dquot(struct dquot *dquot)
-+ {
-+- if (test_bit(DQ_FAKE_B, &dquot->dq_flags) && !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace))
-+- return v2_delete_dquot(dquot);
-+- return 0;
-++ return qtree_release_dquot(&sb_dqinfo(dquot->dq_sb, dquot->dq_type)->u.v2_i.i, dquot);
-+ }
-+
-+ static struct quota_format_ops v2_format_ops = {
-+Index: linux-2.6.27.36/include/linux/dqblk_qtree.h
-+===================================================================
-+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-++++ linux-2.6.27.36/include/linux/dqblk_qtree.h 2009-10-08 16:32:48.000000000 +0200
-+@@ -0,0 +1,56 @@
-++/*
-++ * Definitions of structures and functions for quota formats using trie
-++ */
-++
-++#ifndef _LINUX_DQBLK_QTREE_H
-++#define _LINUX_DQBLK_QTREE_H
-++
-++#include <linux/types.h>
-++
-++/* Numbers of blocks needed for updates - we count with the smallest
-++ * possible block size (1024) */
-++#define QTREE_INIT_ALLOC 4
-++#define QTREE_INIT_REWRITE 2
-++#define QTREE_DEL_ALLOC 0
-++#define QTREE_DEL_REWRITE 6
-++
-++struct dquot;
-++
-++/* Operations */
-++struct qtree_fmt_operations {
-++ void (*mem2disk_dqblk)(void *disk, struct dquot *dquot); /* Convert given entry from in memory format to disk one */
-++ void (*disk2mem_dqblk)(struct dquot *dquot, void *disk); /* Convert given entry from disk format to in memory one */
-++ int (*is_id)(void *disk, struct dquot *dquot); /* Is this structure for given id? */
-++};
-++
-++/* Inmemory copy of version specific information */
-++struct qtree_mem_dqinfo {
-++ struct super_block *dqi_sb; /* Sb quota is on */
-++ int dqi_type; /* Quota type */
-++ unsigned int dqi_blocks; /* # of blocks in quota file */
-++ unsigned int dqi_free_blk; /* First block in list of free blocks */
-++ unsigned int dqi_free_entry; /* First block with free entry */
-++ unsigned int dqi_blocksize_bits; /* Block size of quota file */
-++ unsigned int dqi_entry_size; /* Size of quota entry in quota file */
-++ unsigned int dqi_usable_bs; /* Space usable in block for quota data */
-++ unsigned int dqi_qtree_depth; /* Precomputed depth of quota tree */
-++ struct qtree_fmt_operations *dqi_ops; /* Operations for entry manipulation */
-++};
-++
-++int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot);
-++int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot);
-++int qtree_delete_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot);
-++int qtree_release_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot);
-++int qtree_entry_unused(struct qtree_mem_dqinfo *info, char *disk);
-++static inline int qtree_depth(struct qtree_mem_dqinfo *info)
-++{
-++ unsigned int epb = info->dqi_usable_bs >> 2;
-++ unsigned long long entries = epb;
-++ int i;
-++
-++ for (i = 1; entries < (1ULL << 32); i++)
-++ entries *= epb;
-++ return i;
-++}
-++
-++#endif /* _LINUX_DQBLK_QTREE_H */
-+Index: linux-2.6.27.36/include/linux/dqblk_v2.h
-+===================================================================
-+--- linux-2.6.27.36.orig/include/linux/dqblk_v2.h 2009-10-05 17:19:01.000000000 +0200
-++++ linux-2.6.27.36/include/linux/dqblk_v2.h 2009-10-08 16:32:48.000000000 +0200
-+@@ -1,26 +1,23 @@
-+ /*
-+- * Definitions of structures for vfsv0 quota format
-++ * Definitions for vfsv0 quota format
-+ */
-+
-+ #ifndef _LINUX_DQBLK_V2_H
-+ #define _LINUX_DQBLK_V2_H
-+
-+-#include <linux/types.h>
-++#include <linux/dqblk_qtree.h>
-+
-+-/* id numbers of quota format */
-++/* Id number of quota format */
-+ #define QFMT_VFS_V0 2
-+
-+ /* Numbers of blocks needed for updates */
-+-#define V2_INIT_ALLOC 4
-+-#define V2_INIT_REWRITE 2
-+-#define V2_DEL_ALLOC 0
-+-#define V2_DEL_REWRITE 6
-++#define V2_INIT_ALLOC QTREE_INIT_ALLOC
-++#define V2_INIT_REWRITE QTREE_INIT_REWRITE
-++#define V2_DEL_ALLOC QTREE_DEL_ALLOC
-++#define V2_DEL_REWRITE QTREE_DEL_REWRITE
-+
-+-/* Inmemory copy of version specific information */
-+ struct v2_mem_dqinfo {
-+- unsigned int dqi_blocks;
-+- unsigned int dqi_free_blk;
-+- unsigned int dqi_free_entry;
-++ struct qtree_mem_dqinfo i;
-+ };
-+
-+ #endif /* _LINUX_DQBLK_V2_H */
---- /dev/null
-+++ lustre-1.8.5+dfsg/lustre/kernel_patches/patches/debian-2.6.26.diff
-@@ -0,0 +1,1210 @@
-+diff -u -r debian-2.6.26/Documentation/filesystems/ext2.txt debian-2.6.26_lustre.1.8.2/Documentation/filesystems/ext2.txt
-+--- debian-2.6.26/Documentation/filesystems/ext2.txt 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/Documentation/filesystems/ext2.txt 2010-02-12 15:11:19.000000000 +0100
-+@@ -58,6 +58,22 @@
-+
-+ xip Use execute in place (no caching) if possible
-+
-++iopen Makes an invisible pseudo-directory called
-++ __iopen__ available in the root directory
-++ of the filesystem. Allows open-by-inode-
-++ number. i.e., inode 3145 can be accessed
-++ via /mntpt/__iopen__/3145
-++
-++iopen_nopriv This option makes the iopen directory be
-++ world-readable. This may be safer since it
-++ allows daemons to run as an unprivileged user,
-++ however it significantly changes the security
-++ model of a Unix filesystem, since previously
-++ all files under a mode 700 directory were not
-++ generally avilable even if the
-++ permissions on the file itself is
-++ world-readable.
-++
-+ grpquota,noquota,quota,usrquota Quota options are silently ignored by ext2.
-+
-+
-+diff -u -r debian-2.6.26/block/blk-core.c debian-2.6.26_lustre.1.8.2/block/blk-core.c
-+--- debian-2.6.26/block/blk-core.c 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/block/blk-core.c 2010-02-12 15:14:32.000000000 +0100
-+@@ -1270,6 +1270,8 @@
-+
-+ #endif /* CONFIG_FAIL_MAKE_REQUEST */
-+
-++int dev_check_rdonly(struct block_device *bdev);
-++
-+ /*
-+ * Check whether this bio extends beyond the end of the device.
-+ */
-+@@ -1371,6 +1373,12 @@
-+
-+ if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
-+ goto end_io;
-++ /* this is cfs's dev_rdonly check */
-++ if (bio->bi_rw == WRITE &&
-++ dev_check_rdonly(bio->bi_bdev)) {
-++ bio_endio(bio, 0);
-++ break;
-++ }
-+
-+ if (should_fail_request(bio))
-+ goto end_io;
-+@@ -2028,6 +2036,91 @@
-+ }
-+ EXPORT_SYMBOL(kblockd_flush_work);
-+
-++ /*
-++ * Debug code for turning block devices "read-only" (will discard writes
-++ * silently). This is for filesystem crash/recovery testing.
-++ */
-++struct deventry {
-++ dev_t dev;
-++ struct deventry *next;
-++};
-++
-++static struct deventry *devlist = NULL;
-++static spinlock_t devlock = SPIN_LOCK_UNLOCKED;
-++
-++int dev_check_rdonly(struct block_device *bdev)
-++{
-++ struct deventry *cur;
-++ if (!bdev) return 0;
-++ spin_lock(&devlock);
-++ cur = devlist;
-++ while(cur) {
-++ if (bdev->bd_dev == cur->dev) {
-++ spin_unlock(&devlock);
-++ return 1;
-++ }
-++ cur = cur->next;
-++ }
-++ spin_unlock(&devlock);
-++ return 0;
-++}
-++
-++void dev_set_rdonly(struct block_device *bdev)
-++{
-++ struct deventry *newdev, *cur;
-++
-++ if (!bdev)
-++ return;
-++ newdev = kmalloc(sizeof(struct deventry), GFP_KERNEL);
-++ if (!newdev)
-++ return;
-++
-++ spin_lock(&devlock);
-++ cur = devlist;
-++ while(cur) {
-++ if (bdev->bd_dev == cur->dev) {
-++ spin_unlock(&devlock);
-++ kfree(newdev);
-++ return;
-++ }
-++ cur = cur->next;
-++ }
-++ newdev->dev = bdev->bd_dev;
-++ newdev->next = devlist;
-++ devlist = newdev;
-++ spin_unlock(&devlock);
-++ printk(KERN_WARNING "Turning device %s (%#x) read-only\n",
-++ bdev->bd_disk ? bdev->bd_disk->disk_name : "", bdev->bd_dev);
-++}
-++
-++void dev_clear_rdonly(struct block_device *bdev)
-++{
-++ struct deventry *cur, *last = NULL;
-++ if (!bdev) return;
-++ spin_lock(&devlock);
-++ cur = devlist;
-++ while(cur) {
-++ if (bdev->bd_dev == cur->dev) {
-++ if (last)
-++ last->next = cur->next;
-++ else
-++ devlist = cur->next;
-++ spin_unlock(&devlock);
-++ kfree(cur);
-++ printk(KERN_WARNING "Removing read-only on %s (%#x)\n",
-++ bdev->bd_disk ? bdev->bd_disk->disk_name :
-++ "unknown block", bdev->bd_dev);
-++ return;
-++ }
-++ last = cur;
-++ cur = cur->next;
-++ }
-++ spin_unlock(&devlock);
-++}
-++
-++EXPORT_SYMBOL(dev_set_rdonly);
-++EXPORT_SYMBOL(dev_clear_rdonly);
-++
-+ int __init blk_dev_init(void)
-+ {
-+ int i;
-+diff -u -r debian-2.6.26/drivers/md/raid5.c debian-2.6.26_lustre.1.8.2/drivers/md/raid5.c
-+--- debian-2.6.26/drivers/md/raid5.c 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/drivers/md/raid5.c 2010-02-12 15:19:25.000000000 +0100
-+@@ -1817,6 +1817,8 @@
-+ bi->bi_next = *bip;
-+ *bip = bi;
-+ bi->bi_phys_segments ++;
-++ if (bio_sync(bi) && !forwrite)
-++ clear_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); /* force to read from disk. */
-+ spin_unlock_irq(&conf->device_lock);
-+ spin_unlock(&sh->lock);
-+
-+@@ -3699,6 +3701,8 @@
-+ test_bit(BIO_UPTODATE, &bi->bi_flags)
-+ ? 0 : -EIO);
-+ }
-++ if (bio_sync(bi))
-++ raid5_unplug_device(q);
-+ return 0;
-+ }
-+
-+diff -u -r debian-2.6.26/drivers/scsi/Kconfig debian-2.6.26_lustre.1.8.2/drivers/scsi/Kconfig
-+--- debian-2.6.26/drivers/scsi/Kconfig 2009-12-26 09:14:53.000000000 +0100
-++++ debian-2.6.26_lustre.1.8.2/drivers/scsi/Kconfig 2010-02-12 15:20:02.000000000 +0100
-+@@ -81,6 +81,14 @@
-+ In this case, do not compile the driver for your SCSI host adapter
-+ (below) as a module either.
-+
-++config SD_IOSTATS
-++ bool "Enable SCSI disk I/O stats"
-++ depends on BLK_DEV_SD
-++ default y
-++ ---help---
-++ This enables SCSI disk I/O stats collection. You must also enable
-++ /proc file system support if you want this feature.
-++
-+ config CHR_DEV_ST
-+ tristate "SCSI tape support"
-+ depends on SCSI
-+diff -u -r debian-2.6.26/drivers/scsi/scsi_proc.c debian-2.6.26_lustre.1.8.2/drivers/scsi/scsi_proc.c
-+--- debian-2.6.26/drivers/scsi/scsi_proc.c 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/drivers/scsi/scsi_proc.c 2010-02-12 15:22:05.000000000 +0100
-+@@ -40,7 +40,8 @@
-+ /* 4K page size, but our output routines, use some slack for overruns */
-+ #define PROC_BLOCK_SIZE (3*1024)
-+
-+-static struct proc_dir_entry *proc_scsi;
-++struct proc_dir_entry *proc_scsi;
-++EXPORT_SYMBOL(proc_scsi);
-+
-+ /* Protect sht->present and sht->proc_dir */
-+ static DEFINE_MUTEX(global_host_template_mutex);
-+diff -u -r debian-2.6.26/drivers/scsi/sd.c debian-2.6.26_lustre.1.8.2/drivers/scsi/sd.c
-+--- debian-2.6.26/drivers/scsi/sd.c 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/drivers/scsi/sd.c 2010-02-17 14:13:32.000000000 +0100
-+@@ -107,6 +107,24 @@
-+ * object after last put) */
-+ static DEFINE_MUTEX(sd_ref_mutex);
-+
-++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-++# include <linux/proc_fs.h>
-++# include <linux/seq_file.h>
-++struct proc_dir_entry *sd_iostats_procdir = NULL;
-++char sd_iostats_procdir_name[] = "sd_iostats";
-++static struct file_operations sd_iostats_proc_fops;
-++
-++extern void sd_iostats_init(void);
-++extern void sd_iostats_fini(void);
-++void sd_iostats_start_req(struct scsi_cmnd *SCpnt);
-++void sd_iostats_finish_req(struct scsi_cmnd *SCpnt);
-++#else
-++static inline void sd_iostats_init(void) {}
-++static inline void sd_iostats_fini(void) {}
-++static inline void sd_iostats_start_req(struct scsi_cmnd *SCpnt) {}
-++static inline void sd_iostats_finish_req(struct scsi_cmnd *SCpnt) {}
-++#endif
-++
-+ static const char *sd_cache_types[] = {
-+ "write through", "none", "write back",
-+ "write back, no read (daft)"
-+@@ -531,6 +549,8 @@
-+ }
-+ SCpnt->sdb.length = this_count * sdp->sector_size;
-+
-++ sd_iostats_start_req(SCpnt);
-++
-+ /*
-+ * We shouldn't disconnect in the middle of a sector, so with a dumb
-+ * host adapter, it's safe to assume that we can at least transfer
-+@@ -667,7 +687,7 @@
-+ int diskinfo[4];
-+
-+ /* default to most commonly used values */
-+- diskinfo[0] = 0x40; /* 1 << 6 */
-++ diskinfo[0] = 0x40; /* 1 << 6 */
-+ diskinfo[1] = 0x20; /* 1 << 5 */
-+ diskinfo[2] = sdkp->capacity >> 11;
-+
-+@@ -1023,6 +1043,7 @@
-+ break;
-+ }
-+ out:
-++ sd_iostats_finish_req(SCpnt);
-+ return good_bytes;
-+ }
-+
-+@@ -1711,6 +1732,36 @@
-+ gd->flags = GENHD_FL_DRIVERFS;
-+ if (sdp->removable)
-+ gd->flags |= GENHD_FL_REMOVABLE;
-++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-++ sdkp->stats = kzalloc(sizeof(iostat_stats_t), GFP_KERNEL);
-++ if (!sdkp->stats) {
-++ printk(KERN_WARNING "cannot allocate iostat structure for"
-++ "%s\n", gd->disk_name);
-++ } else {
-++ do_gettimeofday(&sdkp->stats->iostat_timeval);
-++ sdkp->stats->iostat_queue_stamp = jiffies;
-++ spin_lock_init(&sdkp->stats->iostat_lock);
-++ if (sd_iostats_procdir) {
-++ struct proc_dir_entry *pde;
-++ pde = create_proc_entry(gd->disk_name, S_IRUGO | S_IWUSR,
-++ sd_iostats_procdir);
-++ if (!pde) {
-++ printk(KERN_WARNING "Can't create /proc/scsi/"
-++ "%s/%s\n",
-++ sd_iostats_procdir_name,
-++ gd->disk_name);
-++ kfree(sdkp->stats);
-++ sdkp->stats = NULL;
-++ } else {
-++ pde->proc_fops = &sd_iostats_proc_fops;
-++ pde->data = gd;
-++ }
-++ } else {
-++ kfree(sdkp->stats);
-++ sdkp->stats = NULL;
-++ }
-++ }
-++#endif
-+
-+ dev_set_drvdata(dev, sdkp);
-+ add_disk(gd);
-+@@ -1755,6 +1806,366 @@
-+ return 0;
-+ }
-+
-++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-++static int
-++ sd_iostats_seq_show(struct seq_file *seq, void *v)
-++ {
-++ struct timeval now;
-++ struct gendisk *disk = seq->private;
-++ iostat_stats_t *stats;
-++ unsigned long long read_len;
-++ unsigned long long read_len_tot;
-++ unsigned long read_num;
-++ unsigned long read_num_tot;
-++ unsigned long long write_len;
-++ unsigned long long write_len_tot;
-++ unsigned long write_num;
-++ unsigned long write_num_tot;
-++ int i;
-++ int maxi;
-++
-++ stats = scsi_disk(disk)->stats;
-++ if (stats == NULL) {
-++ printk(KERN_ERR "sd_iostats_seq_show: NULL stats entry\n");
-++ BUG();
-++ }
-++
-++ do_gettimeofday(&now);
-++ now.tv_sec -= stats->iostat_timeval.tv_sec;
-++ now.tv_usec -= stats->iostat_timeval.tv_usec;
-++ if (now.tv_usec < 0) {
-++ now.tv_usec += 1000000;
-++ now.tv_sec--;
-++ }
-++
-++ /* this sampling races with updates */
-++ seq_printf(seq, "index: %lu snapshot_time: %lu.%06lu\n",
-++ (unsigned long) scsi_disk(disk)->index,
-++ now.tv_sec, now.tv_usec);
-++
-++ for (i = IOSTAT_NCOUNTERS - 1; i > 0; i--)
-++ if (stats->iostat_read_histogram[i].iostat_count != 0 ||
-++ stats->iostat_write_histogram[i].iostat_count != 0)
-++ break;
-++ maxi = i;
-++
-++ seq_printf(seq, "%8s %8s %12s %8s %12s\n", "size",
-++ "reads", "total", "writes", "total");
-++
-++ read_len_tot = write_len_tot = 0;
-++ read_num_tot = write_num_tot = 0;
-++ for (i = 0; i <= maxi; i++) {
-++ read_len = stats->iostat_read_histogram[i].iostat_size;
-++ read_len_tot += read_len;
-++ read_num = stats->iostat_read_histogram[i].iostat_count;
-++ read_num_tot += read_num;
-++
-++ write_len = stats->iostat_write_histogram[i].iostat_size;
-++ write_len_tot += write_len;
-++ write_num = stats->iostat_write_histogram[i].iostat_count;
-++ write_num_tot += write_num;
-++
-++ seq_printf (seq, "%8d %8lu %12llu %8lu %12llu\n",
-++ 512<<i, read_num, read_len, write_num, write_len);
-++ }
-++
-++ seq_printf(seq, "%8s %8lu %12llu %8lu %12llu\n\n", "total",
-++ read_num_tot, read_len_tot,
-++ write_num_tot, write_len_tot);
-++
-++ seq_printf(seq, "%8s %8s %8s\n", "qdepth", "ticks", "%");
-++ for (i = 0; i < IOSTAT_NCOUNTERS; i++) {
-++ unsigned long long ticks, percent;
-++ ticks = stats->iostat_queue_ticks[i];
-++ if (ticks == 0)
-++ continue;
-++ percent = stats->iostat_queue_ticks[i] * 100;
-++ do_div(percent, stats->iostat_queue_ticks_sum);
-++ seq_printf(seq, "%8d %8llu %8llu\n", i, ticks, percent);
-++ }
-++
-++ if (stats->iostat_reqs != 0) {
-++ unsigned long long aveseek = 0, percent = 0;
-++
-++ if (stats->iostat_seeks) {
-++ aveseek = stats->iostat_seek_sectors;
-++ do_div(aveseek, stats->iostat_seeks);
-++ percent = stats->iostat_seeks * 100;
-++ do_div(percent, stats->iostat_reqs);
-++ }
-++
-++ seq_printf(seq, "\n%llu sectors in %llu reqs: %llu seek(s) over "
-++ "%llu sectors in ave, %llu%% of all reqs\n",
-++ stats->iostat_sectors, stats->iostat_reqs,
-++ stats->iostat_seeks, aveseek, percent);
-++ }
-++
-++ seq_printf(seq, "\n%16s %8s %8s %8s %8s\n", "process time", "reads",
-++ "%%", "writes", "%%");
-++ for (i = 0; i < IOSTAT_NCOUNTERS; i++) {
-++ unsigned long read_percent = 0, write_percent = 0;
-++ if (stats->iostat_wtime[i] == 0 &&
-++ stats->iostat_rtime[i] == 0)
-++ continue;
-++ if (stats->iostat_read_reqs)
-++ read_percent = stats->iostat_rtime[i] * 100 /
-++ stats->iostat_read_reqs;
-++ if (stats->iostat_write_reqs)
-++ write_percent = stats->iostat_wtime[i] * 100 /
-++ stats->iostat_write_reqs;
-++ seq_printf(seq, "%16u %8lu %8lu %8lu %8lu\n",
-++ jiffies_to_msecs(((1UL << i) >> 1) << 1),
-++ stats->iostat_rtime[i], read_percent,
-++ stats->iostat_wtime[i], write_percent);
-++ }
-++
-++ seq_printf(seq, "\n%16s %8s %8s %8s %8s\n", "time in queue", "reads",
-++ "%%", "writes", "%%");
-++ for (i = 0; i < IOSTAT_NCOUNTERS; i++) {
-++ unsigned long read_percent = 0, write_percent = 0;
-++ if (stats->iostat_wtime_in_queue[i] == 0 &&
-++ stats->iostat_rtime_in_queue[i] == 0)
-++ continue;
-++ if (stats->iostat_read_reqs)
-++ read_percent = stats->iostat_rtime_in_queue[i] * 100 /
-++ stats->iostat_read_reqs;
-++ if (stats->iostat_write_reqs)
-++ write_percent = stats->iostat_wtime_in_queue[i] * 100 /
-++ stats->iostat_write_reqs;
-++ seq_printf(seq, "%16u %8lu %8lu %8lu %8lu\n",
-++ jiffies_to_msecs(((1UL << i) >> 1) << 1),
-++ stats->iostat_rtime_in_queue[i],
-++ read_percent,
-++ stats->iostat_wtime_in_queue[i],
-++ write_percent);
-++ }
-++
-++ return 0;
-++ }
-++
-++ static void *
-++ sd_iostats_seq_start(struct seq_file *p, loff_t *pos)
-++ {
-++ return (*pos == 0) ? (void *)1 : NULL;
-++ }
-++
-++ static void *
-++ sd_iostats_seq_next(struct seq_file *p, void *v, loff_t *pos)
-++ {
-++ ++*pos;
-++ return NULL;
-++ }
-++
-++ static void
-++ sd_iostats_seq_stop(struct seq_file *p, void *v)
-++ {
-++ }
-++
-++ static struct seq_operations sd_iostats_seqops = {
-++ .start = sd_iostats_seq_start,
-++ .stop = sd_iostats_seq_stop,
-++ .next = sd_iostats_seq_next,
-++ .show = sd_iostats_seq_show,
-++ };
-++
-++ static int
-++ sd_iostats_seq_open (struct inode *inode, struct file *file)
-++ {
-++ int rc;
-++
-++ rc = seq_open(file, &sd_iostats_seqops);
-++ if (rc != 0)
-++ return rc;
-++
-++ ((struct seq_file *)file->private_data)->private = PDE(inode)->data;
-++ return 0;
-++ }
-++
-++ static ssize_t
-++ sd_iostats_seq_write(struct file *file, const char *buffer,
-++ size_t len, loff_t *off)
-++ {
-++ struct seq_file *seq = file->private_data;
-++ struct gendisk *disk = seq->private;
-++ iostat_stats_t *stats = scsi_disk(disk)->stats;
-++ unsigned long flags;
-++ unsigned long qdepth;
-++
-++
-++ spin_lock_irqsave (&stats->iostat_lock, flags);
-++ qdepth = stats->iostat_queue_depth;
-++ memset (stats, 0, offsetof(iostat_stats_t, iostat_lock));
-++ do_gettimeofday(&stats->iostat_timeval);
-++ stats->iostat_queue_stamp = jiffies;
-++ stats->iostat_queue_depth = qdepth;
-++ spin_unlock_irqrestore (&stats->iostat_lock, flags);
-++
-++ return len;
-++ }
-++
-++ static struct file_operations sd_iostats_proc_fops = {
-++ .owner = THIS_MODULE,
-++ .open = sd_iostats_seq_open,
-++ .read = seq_read,
-++ .write = sd_iostats_seq_write,
-++ .llseek = seq_lseek,
-++ .release = seq_release,
-++ };
-++
-++ extern struct proc_dir_entry *proc_scsi;
-++
-++ void
-++ sd_iostats_init(void)
-++ {
-++ if (proc_scsi == NULL) {
-++ printk(KERN_WARNING "No access to sd iostats: "
-++ "proc_scsi is NULL\n");
-++ return;
-++ }
-++
-++ sd_iostats_procdir = create_proc_entry(sd_iostats_procdir_name,
-++ S_IFDIR | S_IRUGO | S_IXUGO,
-++ proc_scsi);
-++ if (sd_iostats_procdir == NULL) {
-++ printk(KERN_WARNING "No access to sd iostats: "
-++ "can't create /proc/scsi/%s\n", sd_iostats_procdir_name);
-++ return;
-++ }
-++ }
-++
-++ void sd_iostats_fini(void)
-++ {
-++ if (proc_scsi != NULL && sd_iostats_procdir != NULL)
-++ remove_proc_entry(sd_iostats_procdir_name, proc_scsi);
-++
-++ sd_iostats_procdir = NULL;
-++ }
-++
-++ void sd_iostats_finish_req(struct scsi_cmnd *SCpnt)
-++ {
-++ struct request *rq = SCpnt->request;
-++ iostat_stats_t *stats;
-++ unsigned long *tcounter;
-++ int tbucket;
-++ int tmp;
-++ unsigned long irqflags;
-++ unsigned long i;
-++
-++ stats = scsi_disk(rq->rq_disk)->stats;
-++ if (stats == NULL)
-++ return;
-++
-++ tmp = jiffies - rq->start_time;
-++ for (tbucket = 0; tmp > 1; tbucket++)
-++ tmp >>= 1;
-++ if (tbucket >= IOSTAT_NCOUNTERS)
-++ tbucket = IOSTAT_NCOUNTERS - 1;
-++ //printk("%u ticks in D to %u\n", jiffies - rq->start_time, tbucket);
-++
-++ tcounter = rq_data_dir(rq) == WRITE ?
-++ &stats->iostat_wtime[tbucket] : &stats->iostat_rtime[tbucket];
-++
-++ spin_lock_irqsave(&stats->iostat_lock, irqflags);
-++
-++ /* update delay stats */
-++ (*tcounter)++;
-++
-++ /* update queue depth stats */
-++ i = stats->iostat_queue_depth;
-++ if (i >= IOSTAT_NCOUNTERS)
-++ i = IOSTAT_NCOUNTERS - 1;
-++ stats->iostat_queue_ticks[i] += jiffies - stats->iostat_queue_stamp;
-++ stats->iostat_queue_ticks_sum += jiffies - stats->iostat_queue_stamp;
-++ BUG_ON(stats->iostat_queue_depth == 0);
-++ stats->iostat_queue_depth--;
-++
-++ /* update seek stats. XXX: not sure about nr_sectors */
-++ stats->iostat_sectors += rq->nr_sectors;
-++ stats->iostat_reqs++;
-++ if (rq->sector != stats->iostat_next_sector) {
-++ stats->iostat_seek_sectors +=
-++ rq->sector > stats->iostat_next_sector ?
-++ rq->sector - stats->iostat_next_sector :
-++ stats->iostat_next_sector - rq->sector;
-++ stats->iostat_seeks++;
-++ }
-++ stats->iostat_next_sector = rq->sector + rq->nr_sectors;
-++
-++ stats->iostat_queue_stamp = jiffies;
-++
-++ spin_unlock_irqrestore(&stats->iostat_lock, irqflags);
-++ }
-++
-++ void sd_iostats_start_req(struct scsi_cmnd *SCpnt)
-++ {
-++ struct request *rq = SCpnt->request;
-++ iostat_stats_t *stats;
-++ iostat_counter_t *counter;
-++ int bucket;
-++ int tbucket;
-++ int tmp;
-++ unsigned long irqflags;
-++ unsigned long i;
-++ int nsect;
-++
-++ stats = scsi_disk(rq->rq_disk)->stats;
-++ if (stats == NULL)
-++ return;
-++
-++ nsect = scsi_bufflen(SCpnt) >> 9;
-++ for (bucket = 0, tmp = nsect; tmp > 1; bucket++)
-++ tmp >>= 1;
-++
-++ if (bucket >= IOSTAT_NCOUNTERS) {
-++ printk (KERN_ERR "sd_iostats_bump: nsect %d too big\n", nsect);
-++ BUG();
-++ }
-++
-++ counter = rq_data_dir(rq) == WRITE ?
-++ &stats->iostat_write_histogram[bucket] :
-++ &stats->iostat_read_histogram[bucket];
-++
-++ tmp = jiffies - rq->start_time;
-++ for (tbucket = 0; tmp > 1; tbucket++)
-++ tmp >>= 1;
-++ if (tbucket >= IOSTAT_NCOUNTERS)
-++ tbucket = IOSTAT_NCOUNTERS - 1;
-++ //printk("%u ticks in Q to %u\n", jiffies - rq->start_time, tbucket);
-++
-++ /* an ugly hack to know exact processing time. the right
-++ * solution is to add one more field to struct request
-++ * hopefully it will break nothing ... */
-++ rq->start_time = jiffies;
-++
-++ spin_lock_irqsave(&stats->iostat_lock, irqflags);
-++
-++ /* update queue depth stats */
-++ i = stats->iostat_queue_depth;
-++ if (i >= IOSTAT_NCOUNTERS)
-++ i = IOSTAT_NCOUNTERS - 1;
-++ stats->iostat_queue_ticks[i] += jiffies - stats->iostat_queue_stamp;
-++ stats->iostat_queue_ticks_sum += jiffies - stats->iostat_queue_stamp;
-++ stats->iostat_queue_depth++;
-++
-++ /* update delay stats */
-++ if (rq_data_dir(rq) == WRITE) {
-++ stats->iostat_wtime_in_queue[tbucket]++;
-++ stats->iostat_write_reqs++;
-++ } else {
-++ stats->iostat_rtime_in_queue[tbucket]++;
-++ stats->iostat_read_reqs++;
-++ }
-++
-++ /* update size stats */
-++ counter->iostat_size += nsect;
-++ counter->iostat_count++;
-++
-++ stats->iostat_queue_stamp = jiffies;
-++
-++ spin_unlock_irqrestore(&stats->iostat_lock, irqflags);
-++}
-++#endif
-++
-+ /**
-+ * scsi_disk_release - Called to free the scsi_disk structure
-+ * @dev: pointer to embedded class device
-+@@ -1773,6 +2184,13 @@
-+ idr_remove(&sd_index_idr, sdkp->index);
-+ spin_unlock(&sd_index_lock);
-+
-++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-++ if (sdkp->stats) {
-++ remove_proc_entry(disk->disk_name, sd_iostats_procdir);
-++ kfree(sdkp->stats);
-++ sdkp->stats = NULL;
-++ }
-++#endif
-+ disk->private_data = NULL;
-+ put_disk(disk);
-+ put_device(&sdkp->device->sdev_gendev);
-+@@ -1890,6 +2308,8 @@
-+ if (!majors)
-+ return -ENODEV;
-+
-++ sd_iostats_init();
-++
-+ err = class_register(&sd_disk_class);
-+ if (err)
-+ goto err_out;
-+@@ -1905,6 +2325,7 @@
-+ err_out:
-+ for (i = 0; i < SD_MAJORS; i++)
-+ unregister_blkdev(sd_major(i), "sd");
-++ sd_iostats_fini();
-+ return err;
-+ }
-+
-+diff -u -r debian-2.6.26/fs/block_dev.c debian-2.6.26_lustre.1.8.2/fs/block_dev.c
-+--- debian-2.6.26/fs/block_dev.c 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/fs/block_dev.c 2010-02-17 14:19:50.000000000 +0100
-+@@ -1125,6 +1125,7 @@
-+ if (bdev != bdev->bd_contains)
-+ victim = bdev->bd_contains;
-+ bdev->bd_contains = NULL;
-++ dev_clear_rdonly(bdev);
-+ }
-+ unlock_kernel();
-+ mutex_unlock(&bdev->bd_mutex);
-+diff -u -r debian-2.6.26/fs/dcache.c debian-2.6.26_lustre.1.8.2/fs/dcache.c
-+--- debian-2.6.26/fs/dcache.c 2009-12-26 09:14:56.000000000 +0100
-++++ debian-2.6.26_lustre.1.8.2/fs/dcache.c 2010-02-17 14:24:24.000000000 +0100
-+@@ -250,6 +250,13 @@
-+ spin_unlock(&dcache_lock);
-+ return 0;
-+ }
-++
-++ /* network invalidation by Lustre */
-++ if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
-++ spin_unlock(&dcache_lock);
-++ return 0;
-++ }
-++
-+ /*
-+ * Check whether to do a partial shrink_dcache
-+ * to get rid of unused child entries.
-+@@ -1427,14 +1434,23 @@
-+ *
-+ * Adds a dentry to the hash according to its name.
-+ */
-+-
-++
-++void d_rehash_cond(struct dentry * entry, int lock)
-++{
-++ if (lock)
-++ spin_lock(&dcache_lock);
-++ spin_lock(&entry->d_lock);
-++ _d_rehash(entry);
-++ spin_unlock(&entry->d_lock);
-++ if (lock)
-++ spin_unlock(&dcache_lock);
-++}
-++
-++EXPORT_SYMBOL(d_rehash_cond);
-++
-+ void d_rehash(struct dentry * entry)
-+ {
-+- spin_lock(&dcache_lock);
-+- spin_lock(&entry->d_lock);
-+- _d_rehash(entry);
-+- spin_unlock(&entry->d_lock);
-+- spin_unlock(&dcache_lock);
-++ d_rehash_cond(entry, 1);
-+ }
-+
-+ #define do_switch(x,y) do { \
-+@@ -1510,7 +1526,7 @@
-+ * Update the dcache to reflect the move of a file name. Negative
-+ * dcache entries should not be moved in this way.
-+ */
-+-static void d_move_locked(struct dentry * dentry, struct dentry * target)
-++void d_move_locked(struct dentry * dentry, struct dentry * target)
-+ {
-+ struct hlist_head *list;
-+
-+@@ -1568,6 +1584,7 @@
-+ spin_unlock(&dentry->d_lock);
-+ write_sequnlock(&rename_lock);
-+ }
-++EXPORT_SYMBOL(d_move_locked);
-+
-+ /**
-+ * d_move - move a dentry
-+@@ -2051,6 +2068,7 @@
-+
-+ return result;
-+ }
-++EXPORT_SYMBOL(is_subdir);
-+
-+ void d_genocide(struct dentry *root)
-+ {
-+diff -u -r debian-2.6.26/fs/filesystems.c debian-2.6.26_lustre.1.8.2/fs/filesystems.c
-+--- debian-2.6.26/fs/filesystems.c 2009-12-26 09:14:56.000000000 +0100
-++++ debian-2.6.26_lustre.1.8.2/fs/filesystems.c 2010-02-17 14:26:59.000000000 +0100
-+@@ -28,7 +28,9 @@
-+ */
-+
-+ static struct file_system_type *file_systems;
-+-static DEFINE_RWLOCK(file_systems_lock);
-++DEFINE_RWLOCK(file_systems_lock);
-++
-++EXPORT_SYMBOL(file_systems_lock);
-+
-+ /* WARNING: This can be used only if we _already_ own a reference */
-+ void get_filesystem(struct file_system_type *fs)
-+diff -u -r debian-2.6.26/fs/inode.c debian-2.6.26_lustre.1.8.2/fs/inode.c
-+--- debian-2.6.26/fs/inode.c 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/fs/inode.c 2010-02-17 14:27:51.000000000 +0100
-+@@ -409,7 +409,9 @@
-+ int nr_scanned;
-+ unsigned long reap = 0;
-+
-+- mutex_lock(&iprune_mutex);
-++ if (!mutex_trylock(&iprune_mutex))
-++ return;
-++
-+ spin_lock(&inode_lock);
-+ for (nr_scanned = 0; nr_scanned < nr_to_scan; nr_scanned++) {
-+ struct inode *inode;
-+diff -u -r debian-2.6.26/fs/jbd2/checkpoint.c debian-2.6.26_lustre.1.8.2/fs/jbd2/checkpoint.c
-+--- debian-2.6.26/fs/jbd2/checkpoint.c 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/fs/jbd2/checkpoint.c 2010-02-17 14:28:49.000000000 +0100
-+@@ -696,6 +696,7 @@
-+ J_ASSERT(transaction->t_checkpoint_list == NULL);
-+ J_ASSERT(transaction->t_checkpoint_io_list == NULL);
-+ J_ASSERT(transaction->t_updates == 0);
-++ J_ASSERT(list_empty(&transaction->t_jcb));
-+ J_ASSERT(journal->j_committing_transaction != transaction);
-+ J_ASSERT(journal->j_running_transaction != transaction);
-+
-+diff -u -r debian-2.6.26/fs/jbd2/commit.c debian-2.6.26_lustre.1.8.2/fs/jbd2/commit.c
-+--- debian-2.6.26/fs/jbd2/commit.c 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/fs/jbd2/commit.c 2010-02-17 14:29:44.000000000 +0100
-+@@ -874,6 +874,30 @@
-+ transaction can be removed from any checkpoint list it was on
-+ before. */
-+
-++ /*
-++ * Call any callbacks that had been registered for handles in this
-++ * transaction. It is up to the callback to free any allocated
-++ * memory.
-++ *
-++ * The spinlocking (t_jcb_lock) here is surely unnecessary...
-++ */
-++ spin_lock(&commit_transaction->t_jcb_lock);
-++ if (!list_empty(&commit_transaction->t_jcb)) {
-++ struct list_head *p, *n;
-++ int error = is_journal_aborted(journal);
-++
-++ list_for_each_safe(p, n, &commit_transaction->t_jcb) {
-++ struct journal_callback *jcb;
-++
-++ jcb = list_entry(p, struct journal_callback, jcb_list);
-++ list_del(p);
-++ spin_unlock(&commit_transaction->t_jcb_lock);
-++ jcb->jcb_func(jcb, error);
-++ spin_lock(&commit_transaction->t_jcb_lock);
-++ }
-++ }
-++ spin_unlock(&commit_transaction->t_jcb_lock);
-++
-+ jbd_debug(3, "JBD: commit phase 7\n");
-+
-+ J_ASSERT(commit_transaction->t_sync_datalist == NULL);
-+diff -u -r debian-2.6.26/fs/jbd2/journal.c debian-2.6.26_lustre.1.8.2/fs/jbd2/journal.c
-+--- debian-2.6.26/fs/jbd2/journal.c 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/fs/jbd2/journal.c 2010-02-17 14:38:15.000000000 +0100
-+@@ -82,6 +82,8 @@
-+ EXPORT_SYMBOL(jbd2_journal_invalidatepage);
-+ EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers);
-+ EXPORT_SYMBOL(jbd2_journal_force_commit);
-++EXPORT_SYMBOL(jbd2_journal_callback_set);
-++EXPORT_SYMBOL(jbd2_journal_bmap);
-+
-+ static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
-+ static void __journal_abort_soft (journal_t *journal, int errno);
-+@@ -460,6 +462,7 @@
-+ spin_unlock(&journal->j_state_lock);
-+ return ret;
-+ }
-++EXPORT_SYMBOL(jbd2_log_start_commit);
-+
-+ /*
-+ * Force and wait upon a commit if the calling process is not within
-+diff -u -r debian-2.6.26/fs/jbd2/transaction.c debian-2.6.26_lustre.1.8.2/fs/jbd2/transaction.c
-+--- debian-2.6.26/fs/jbd2/transaction.c 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/fs/jbd2/transaction.c 2010-02-17 14:42:20.000000000 +0100
-+@@ -51,10 +51,12 @@
-+ transaction->t_state = T_RUNNING;
-+ transaction->t_tid = journal->j_transaction_sequence++;
-+ transaction->t_expires = jiffies + journal->j_commit_interval;
-++ INIT_LIST_HEAD(&transaction->t_jcb);
-+ spin_lock_init(&transaction->t_handle_lock);
-++ spin_lock_init(&transaction->t_jcb_lock);
-+
-+ /* Set up the commit timer for the new transaction. */
-+- journal->j_commit_timer.expires = round_jiffies(transaction->t_expires);
-++ journal->j_commit_timer.expires = transaction->t_expires;
-+ add_timer(&journal->j_commit_timer);
-+
-+ J_ASSERT(journal->j_running_transaction == NULL);
-+@@ -252,6 +254,7 @@
-+ memset(handle, 0, sizeof(*handle));
-+ handle->h_buffer_credits = nblocks;
-+ handle->h_ref = 1;
-++ INIT_LIST_HEAD(&handle->h_jcb);
-+
-+ lockdep_init_map(&handle->h_lockdep_map, "jbd2_handle",
-+ &jbd2_handle_key, 0);
-+@@ -1350,6 +1353,36 @@
-+ }
-+
-+ /**
-++ * void jbd2_journal_callback_set() - Register a callback function for this handle.
-++ * @handle: handle to attach the callback to.
-++ * @func: function to callback.
-++ * @jcb: structure with additional information required by func() , and
-++ * some space for jbd2 internal information.
-++ *
-++ * The function will be
-++ * called when the transaction that this handle is part of has been
-++ * committed to disk with the original callback data struct and the
-++ * error status of the journal as parameters. There is no guarantee of
-++ * ordering between handles within a single transaction, nor between
-++ * callbacks registered on the same handle.
-++ *
-++ * The caller is responsible for allocating the journal_callback struct.
-++ * This is to allow the caller to add as much extra data to the callback
-++ * as needed, but reduce the overhead of multiple allocations. The caller
-++ * allocated struct must start with a struct journal_callback at offset 0,
-++ * and has the caller-specific data afterwards.
-++ */
-++void jbd2_journal_callback_set(handle_t *handle,
-++ void (*func)(struct journal_callback *jcb, int error),
-++ struct journal_callback *jcb)
-++{
-++ spin_lock(&handle->h_transaction->t_jcb_lock);
-++ list_add_tail(&jcb->jcb_list, &handle->h_jcb);
-++ spin_unlock(&handle->h_transaction->t_jcb_lock);
-++ jcb->jcb_func = func;
-++}
-++
-++/**
-+ * int jbd2_journal_stop() - complete a transaction
-+ * @handle: tranaction to complete.
-+ *
-+@@ -1423,6 +1456,11 @@
-+ wake_up(&journal->j_wait_transaction_locked);
-+ }
-+
-++ /* Move callbacks from the handle to the transaction. */
-++ spin_lock(&transaction->t_jcb_lock);
-++ list_splice(&handle->h_jcb, &transaction->t_jcb);
-++ spin_unlock(&transaction->t_jcb_lock);
-++
-+ /*
-+ * If the handle is marked SYNC, we need to set another commit
-+ * going! We also want to force a commit if the current
-+diff -u -r debian-2.6.26/fs/namespace.c debian-2.6.26_lustre.1.8.2/fs/namespace.c
-+--- debian-2.6.26/fs/namespace.c 2009-12-26 09:14:56.000000000 +0100
-++++ debian-2.6.26_lustre.1.8.2/fs/namespace.c 2010-02-17 14:43:07.000000000 +0100
-+@@ -1660,6 +1660,7 @@
-+
-+ return do_add_mount(mnt, nd, mnt_flags, NULL);
-+ }
-++EXPORT_SYMBOL(set_fs_pwd);
-+
-+ /*
-+ * add a mount into a namespace's mount tree
-+diff -u -r debian-2.6.26/include/linux/blkdev.h debian-2.6.26_lustre.1.8.2/include/linux/blkdev.h
-+--- debian-2.6.26/include/linux/blkdev.h 2009-12-26 09:14:55.000000000 +0100
-++++ debian-2.6.26_lustre.1.8.2/include/linux/blkdev.h 2010-02-18 07:44:31.000000000 +0100
-+@@ -806,7 +806,7 @@
-+ #define MAX_PHYS_SEGMENTS 128
-+ #define MAX_HW_SEGMENTS 128
-+ #define SAFE_MAX_SECTORS 255
-+-#define BLK_DEF_MAX_SECTORS 1024
-++#define BLK_DEF_MAX_SECTORS 2048
-+
-+ #define MAX_SEGMENT_SIZE 65536
-+
-+diff -u -r debian-2.6.26/include/linux/dcache.h debian-2.6.26_lustre.1.8.2/include/linux/dcache.h
-+--- debian-2.6.26/include/linux/dcache.h 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/include/linux/dcache.h 2010-02-18 07:46:08.000000000 +0100
-+@@ -173,6 +173,7 @@
-+
-+ #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */
-+ #define DCACHE_UNHASHED 0x0010
-++#define DCACHE_LUSTRE_INVALID 0x0040 /* Lustre invalidated */
-+
-+ #define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 /* Parent inode is watched */
-+
-+@@ -250,6 +251,7 @@
-+ * This adds the entry to the hash queues.
-+ */
-+ extern void d_rehash(struct dentry *);
-++extern void d_rehash_cond(struct dentry *, int lock);
-+
-+ /**
-+ * d_add - add dentry to hash queues
-+@@ -285,6 +287,7 @@
-+
-+ /* used for rename() and baskets */
-+ extern void d_move(struct dentry *, struct dentry *);
-++extern void d_move_locked(struct dentry *, struct dentry *);
-+
-+ /* appendix may either be NULL or be used for transname suffixes */
-+ extern struct dentry * d_lookup(struct dentry *, struct qstr *);
-+diff -u -r debian-2.6.26/include/linux/fs.h debian-2.6.26_lustre.1.8.2/include/linux/fs.h
-+--- debian-2.6.26/include/linux/fs.h 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/include/linux/fs.h 2010-02-18 07:57:56.000000000 +0100
-+@@ -1832,6 +1832,10 @@
-+ extern void submit_bio(int, struct bio *);
-+ extern int bdev_read_only(struct block_device *);
-+ #endif
-++#define HAVE_CLEAR_RDONLY_ON_PUT
-++extern void dev_set_rdonly(struct block_device *bdev);
-++extern int dev_check_rdonly(struct block_device *bdev);
-++extern void dev_clear_rdonly(struct block_device *bdev);
-+ extern int set_blocksize(struct block_device *, int);
-+ extern int sb_set_blocksize(struct super_block *, int);
-+ extern int sb_min_blocksize(struct super_block *, int);
-+@@ -1930,6 +1934,7 @@
-+
-+ extern const struct file_operations generic_ro_fops;
-+
-++extern rwlock_t file_systems_lock;
-+ #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
-+
-+ extern int vfs_readlink(struct dentry *, char __user *, int, const char *);
-+diff -u -r debian-2.6.26/include/linux/jbd2.h debian-2.6.26_lustre.1.8.2/include/linux/jbd2.h
-+--- debian-2.6.26/include/linux/jbd2.h 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/include/linux/jbd2.h 2010-02-18 08:08:30.000000000 +0100
-+@@ -379,6 +379,27 @@
-+ bit_spin_unlock(BH_JournalHead, &bh->b_state);
-+ }
-+
-++#define HAVE_JOURNAL_CALLBACK_STATUS
-++/**
-++ * struct journal_callback - Base structure for callback information.
-++ * @jcb_list: list information for other callbacks attached to the same handle.
-++ * @jcb_func: Function to call with this callback structure.
-++ *
-++ * This struct is a 'seed' structure for a using with your own callback
-++ * structs. If you are using callbacks you must allocate one of these
-++ * or another struct of your own definition which has this struct
-++ * as it's first element and pass it to journal_callback_set().
-++ *
-++ * This is used internally by jbd2 to maintain callback information.
-++ *
-++ * See journal_callback_set for more information.
-++ **/
-++struct journal_callback {
-++ struct list_head jcb_list; /* t_jcb_lock */
-++ void (*jcb_func)(struct journal_callback *jcb, int error);
-++ /* user data goes here */
-++};
-++
-+ struct jbd2_revoke_table_s;
-+
-+ /**
-+@@ -387,6 +408,7 @@
-+ * @h_transaction: Which compound transaction is this update a part of?
-+ * @h_buffer_credits: Number of remaining buffers we are allowed to dirty.
-+ * @h_ref: Reference count on this handle
-++ * @h_jcb: List of application registered callbacks for this handle.
-+ * @h_err: Field for caller's use to track errors through large fs operations
-+ * @h_sync: flag for sync-on-close
-+ * @h_jdata: flag to force data journaling
-+@@ -412,6 +434,13 @@
-+ /* operations */
-+ int h_err;
-+
-++ /*
-++ * List of application registered callbacks for this handle. The
-++ * function(s) will be called after the transaction that this handle is
-++ * part of has been committed to disk. [t_jcb_lock]
-++ */
-++ struct list_head h_jcb;
-++
-+ /* Flags [no locking] */
-+ unsigned int h_sync: 1; /* sync-on-close */
-+ unsigned int h_jdata: 1; /* force data journaling */
-+@@ -467,6 +496,9 @@
-+ * j_state_lock
-+ * ->j_list_lock (journal_unmap_buffer)
-+ *
-++ * t_handle_lock
-++ * ->t_jcb_lock
-++ *
-+ */
-+
-+ struct transaction_s
-+@@ -613,6 +645,15 @@
-+ */
-+ int t_handle_count;
-+
-++ /*
-++ * Protects the callback list
-++ */
-++ spinlock_t t_jcb_lock;
-++ /*
-++ * List of registered callback functions for this transaction.
-++ * Called when the transaction is committed. [t_jcb_lock]
-++ */
-++ struct list_head t_jcb;
-+ };
-+
-+ struct transaction_run_stats_s {
-+@@ -1016,6 +1057,9 @@
-+ extern int jbd2_journal_flush (journal_t *);
-+ extern void jbd2_journal_lock_updates (journal_t *);
-+ extern void jbd2_journal_unlock_updates (journal_t *);
-++extern void jbd2_journal_callback_set(handle_t *handle,
-++ void (*fn)(struct journal_callback *,int),
-++ struct journal_callback *jcb);
-+
-+ extern journal_t * jbd2_journal_init_dev(struct block_device *bdev,
-+ struct block_device *fs_dev,
-+diff -u -r debian-2.6.26/include/linux/mm.h debian-2.6.26_lustre.1.8.2/include/linux/mm.h
-+--- debian-2.6.26/include/linux/mm.h 2009-12-26 09:14:57.000000000 +0100
-++++ debian-2.6.26_lustre.1.8.2/include/linux/mm.h 2010-02-18 08:10:11.000000000 +0100
-+@@ -564,6 +564,8 @@
-+ {
-+ return __va(page_to_pfn(page) << PAGE_SHIFT);
-+ }
-++/* truncate.c */
-++extern void truncate_complete_page(struct address_space *mapping,struct page *);
-+
-+ #if defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL)
-+ #define HASHED_PAGE_VIRTUAL
-+diff -u -r debian-2.6.26/include/scsi/sd.h debian-2.6.26_lustre.1.8.2/include/scsi/sd.h
-+--- debian-2.6.26/include/scsi/sd.h 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/include/scsi/sd.h 2010-02-17 14:18:52.000000000 +0100
-+@@ -31,6 +31,47 @@
-+ */
-+ #define SD_BUF_SIZE 512
-+
-++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-++typedef struct {
-++ unsigned long long iostat_size;
-++ unsigned long long iostat_count;
-++} iostat_counter_t;
-++
-++#define IOSTAT_NCOUNTERS 16
-++typedef struct {
-++ iostat_counter_t iostat_read_histogram[IOSTAT_NCOUNTERS];
-++ iostat_counter_t iostat_write_histogram[IOSTAT_NCOUNTERS];
-++ struct timeval iostat_timeval;
-++
-++ /* queue depth: how well the pipe is filled up */
-++ unsigned long long iostat_queue_ticks[IOSTAT_NCOUNTERS];
-++ unsigned long long iostat_queue_ticks_sum;
-++ unsigned long iostat_queue_depth;
-++ unsigned long iostat_queue_stamp;
-++
-++ /* seeks: how linear the traffic is */
-++ unsigned long long iostat_next_sector;
-++ unsigned long long iostat_seek_sectors;
-++ unsigned long long iostat_seeks;
-++ unsigned long long iostat_sectors;
-++ unsigned long long iostat_reqs;
-++ unsigned long iostat_read_reqs;
-++ unsigned long iostat_write_reqs;
-++
-++ /* process time: how long it takes to process requests */
-++ unsigned long iostat_rtime[IOSTAT_NCOUNTERS];
-++ unsigned long iostat_wtime[IOSTAT_NCOUNTERS];
-++
-++ /* queue time: how long process spent in elevator's queue */
-++ unsigned long iostat_rtime_in_queue[IOSTAT_NCOUNTERS];
-++ unsigned long iostat_wtime_in_queue[IOSTAT_NCOUNTERS];
-++
-++ /* must be the last field, as it's used to know size to be memset'ed */
-++ spinlock_t iostat_lock;
-++} ____cacheline_aligned_in_smp iostat_stats_t;
-++#endif
-++
-++
-+ struct scsi_disk {
-+ struct scsi_driver *driver; /* always &sd_template */
-+ struct scsi_device *device;
-+@@ -45,6 +86,9 @@
-+ unsigned WCE : 1; /* state of disk WCE bit */
-+ unsigned RCD : 1; /* state of disk RCD bit, unused */
-+ unsigned DPOFUA : 1; /* state of disk DPOFUA bit */
-++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-++ iostat_stats_t *stats; /* scsi disk statistics */
-++#endif
-+ };
-+ #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
-+
-+diff -u -r debian-2.6.26/kernel/sched.c debian-2.6.26_lustre.1.8.2/kernel/sched.c
-+--- debian-2.6.26/kernel/sched.c 2009-12-26 09:14:56.000000000 +0100
-++++ debian-2.6.26_lustre.1.8.2/kernel/sched.c 2010-02-18 08:11:02.000000000 +0100
-+@@ -5477,6 +5477,7 @@
-+
-+ show_stack(p, NULL);
-+ }
-++EXPORT_SYMBOL(sched_show_task);
-+
-+ void show_state_filter(unsigned long state_filter)
-+ {
-+diff -u -r debian-2.6.26/mm/truncate.c debian-2.6.26_lustre.1.8.2/mm/truncate.c
-+--- debian-2.6.26/mm/truncate.c 2008-07-13 23:51:29.000000000 +0200
-++++ debian-2.6.26_lustre.1.8.2/mm/truncate.c 2010-02-18 08:12:58.000000000 +0100
-+@@ -92,7 +92,7 @@
-+ * its lock, b) when a concurrent invalidate_mapping_pages got there first and
-+ * c) when tmpfs swizzles a page between a tmpfs inode and swapper_space.
-+ */
-+-static void
-++void
-+ truncate_complete_page(struct address_space *mapping, struct page *page)
-+ {
-+ if (page->mapping != mapping)
-+@@ -108,6 +108,7 @@
-+ ClearPageMappedToDisk(page);
-+ page_cache_release(page); /* pagecache ref */
-+ }
-++EXPORT_SYMBOL_GPL(truncate_complete_page);
-+
-+ /*
-+ * This is for invalidate_mapping_pages(). That function can be called at
-+diff -u -r debian-2.6.26/security/security.c debian-2.6.26_lustre.1.8.2/security/security.c
-+--- debian-2.6.26/security/security.c 2009-12-26 09:14:57.000000000 +0100
-++++ debian-2.6.26_lustre.1.8.2/security/security.c 2010-02-18 08:13:38.000000000 +0100
-+@@ -406,6 +406,7 @@
-+ return 0;
-+ return security_ops->inode_unlink(dir, dentry);
-+ }
-++EXPORT_SYMBOL(security_inode_unlink);
-+
-+ int security_inode_symlink(struct inode *dir, struct dentry *dentry,
-+ const char *old_name)
---- /dev/null
-+++ lustre-1.8.5+dfsg/lustre/kernel_patches/patches/md-mmp-unplug-dev-2.6.27-vanilla.patch
-@@ -0,0 +1,22 @@
-+Index: linux-2.6.27.36/drivers/md/raid5.c
-+===================================================================
-+--- linux-2.6.27.36.orig/drivers/md/raid5.c 2009-10-05 17:19:01.000000000 +0200
-++++ linux-2.6.27.36/drivers/md/raid5.c 2009-10-08 15:06:10.000000000 +0200
-+@@ -1726,6 +1726,8 @@
-+ bi->bi_next = *bip;
-+ *bip = bi;
-+ bi->bi_phys_segments ++;
-++ if (bio_sync(bi) && !forwrite)
-++ clear_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); /* force to read from disk. */
-+ spin_unlock_irq(&conf->device_lock);
-+ spin_unlock(&sh->lock);
-+
-+@@ -3478,6 +3480,8 @@
-+
-+ bio_endio(bi, 0);
-+ }
-++ if (bio_sync(bi))
-++ raid5_unplug_device(q);
-+ return 0;
-+ }
-+
---- /dev/null
-+++ lustre-1.8.5+dfsg/lustre/kernel_patches/patches/jbd2-jcberr-2.6.26-vanilla.patch
-@@ -0,0 +1,211 @@
-+Index: linux-source-2.6.26/include/linux/jbd2.h
-+===================================================================
-+--- linux-source-2.6.26.orig/include/linux/jbd2.h 2008-07-13 23:51:29.000000000 +0200
-++++ linux-source-2.6.26/include/linux/jbd2.h 2009-10-09 13:42:21.000000000 +0200
-+@@ -379,6 +379,27 @@
-+ bit_spin_unlock(BH_JournalHead, &bh->b_state);
-+ }
-+
-++#define HAVE_JOURNAL_CALLBACK_STATUS
-++/**
-++ * struct journal_callback - Base structure for callback information.
-++ * @jcb_list: list information for other callbacks attached to the same handle.
-++ * @jcb_func: Function to call with this callback structure.
-++ *
-++ * This struct is a 'seed' structure for a using with your own callback
-++ * structs. If you are using callbacks you must allocate one of these
-++ * or another struct of your own definition which has this struct
-++ * as it's first element and pass it to journal_callback_set().
-++ *
-++ * This is used internally by jbd2 to maintain callback information.
-++ *
-++ * See journal_callback_set for more information.
-++ **/
-++struct journal_callback {
-++ struct list_head jcb_list; /* t_jcb_lock */
-++ void (*jcb_func)(struct journal_callback *jcb, int error);
-++ /* user data goes here */
-++};
-++
-+ struct jbd2_revoke_table_s;
-+
-+ /**
-+@@ -387,6 +408,7 @@
-+ * @h_transaction: Which compound transaction is this update a part of?
-+ * @h_buffer_credits: Number of remaining buffers we are allowed to dirty.
-+ * @h_ref: Reference count on this handle
-++ * @h_jcb: List of application registered callbacks for this handle.
-+ * @h_err: Field for caller's use to track errors through large fs operations
-+ * @h_sync: flag for sync-on-close
-+ * @h_jdata: flag to force data journaling
-+@@ -412,6 +434,13 @@
-+ /* operations */
-+ int h_err;
-+
-++ /*
-++ * List of application registered callbacks for this handle. The
-++ * function(s) will be called after the transaction that this handle is
-++ * part of has been committed to disk. [t_jcb_lock]
-++ */
-++ struct list_head h_jcb;
-++
-+ /* Flags [no locking] */
-+ unsigned int h_sync: 1; /* sync-on-close */
-+ unsigned int h_jdata: 1; /* force data journaling */
-+@@ -467,6 +496,8 @@
-+ * j_state_lock
-+ * ->j_list_lock (journal_unmap_buffer)
-+ *
-++ * t_handle_lock
-++ * ->t_jcb_lock
-+ */
-+
-+ struct transaction_s
-+@@ -613,6 +644,15 @@
-+ */
-+ int t_handle_count;
-+
-++ /*
-++ * Protects the callback list
-++ */
-++ spinlock_t t_jcb_lock;
-++ /*
-++ * List of registered callback functions for this transaction.
-++ * Called when the transaction is committed. [t_jcb_lock]
-++ */
-++ struct list_head t_jcb;
-+ };
-+
-+ struct transaction_run_stats_s {
-+@@ -1016,6 +1056,9 @@
-+ extern int jbd2_journal_flush (journal_t *);
-+ extern void jbd2_journal_lock_updates (journal_t *);
-+ extern void jbd2_journal_unlock_updates (journal_t *);
-++extern void jbd2_journal_callback_set(handle_t *handle,
-++ void (*fn)(struct journal_callback *,int),
-++ struct journal_callback *jcb);
-+
-+ extern journal_t * jbd2_journal_init_dev(struct block_device *bdev,
-+ struct block_device *fs_dev,
-+Index: linux-source-2.6.26/fs/jbd2/checkpoint.c
-+===================================================================
-+--- linux-source-2.6.26.orig/fs/jbd2/checkpoint.c 2008-07-13 23:51:29.000000000 +0200
-++++ linux-source-2.6.26/fs/jbd2/checkpoint.c 2009-10-09 13:42:21.000000000 +0200
-+@@ -696,6 +696,7 @@
-+ J_ASSERT(transaction->t_checkpoint_list == NULL);
-+ J_ASSERT(transaction->t_checkpoint_io_list == NULL);
-+ J_ASSERT(transaction->t_updates == 0);
-++ J_ASSERT(list_empty(&transaction->t_jcb));
-+ J_ASSERT(journal->j_committing_transaction != transaction);
-+ J_ASSERT(journal->j_running_transaction != transaction);
-+
-+Index: linux-source-2.6.26/fs/jbd2/commit.c
-+===================================================================
-+--- linux-source-2.6.26.orig/fs/jbd2/commit.c 2008-07-13 23:51:29.000000000 +0200
-++++ linux-source-2.6.26/fs/jbd2/commit.c 2009-10-09 13:42:21.000000000 +0200
-+@@ -854,6 +854,30 @@
-+ /* AKPM: bforget here */
-+ }
-+
-++ /*
-++ * Call any callbacks that had been registered for handles in this
-++ * transaction. It is up to the callback to free any allocated
-++ * memory.
-++ *
-++ * The spinlocking (t_jcb_lock) here is surely unnecessary...
-++ */
-++ spin_lock(&commit_transaction->t_jcb_lock);
-++ if (!list_empty(&commit_transaction->t_jcb)) {
-++ struct list_head *p, *n;
-++ int error = is_journal_aborted(journal);
-++
-++ list_for_each_safe(p, n, &commit_transaction->t_jcb) {
-++ struct journal_callback *jcb;
-++
-++ jcb = list_entry(p, struct journal_callback, jcb_list);
-++ list_del(p);
-++ spin_unlock(&commit_transaction->t_jcb_lock);
-++ jcb->jcb_func(jcb, error);
-++ spin_lock(&commit_transaction->t_jcb_lock);
-++ }
-++ }
-++ spin_unlock(&commit_transaction->t_jcb_lock);
-++
-+ jbd_debug(3, "JBD: commit phase 6\n");
-+
-+ if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
-+Index: linux-source-2.6.26/fs/jbd2/journal.c
-+===================================================================
-+--- linux-source-2.6.26.orig/fs/jbd2/journal.c 2009-10-09 13:39:04.000000000 +0200
-++++ linux-source-2.6.26/fs/jbd2/journal.c 2009-10-09 13:43:03.000000000 +0200
-+@@ -82,6 +82,9 @@
-+ EXPORT_SYMBOL(jbd2_journal_invalidatepage);
-+ EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers);
-+ EXPORT_SYMBOL(jbd2_journal_force_commit);
-++EXPORT_SYMBOL(jbd2_journal_callback_set);
-++EXPORT_SYMBOL(jbd2_journal_bmap);
-++
-+
-+ static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
-+ static void __journal_abort_soft (journal_t *journal, int errno);
-+Index: linux-source-2.6.26/fs/jbd2/transaction.c
-+===================================================================
-+--- linux-source-2.6.26.orig/fs/jbd2/transaction.c 2008-07-13 23:51:29.000000000 +0200
-++++ linux-source-2.6.26/fs/jbd2/transaction.c 2009-10-09 13:42:21.000000000 +0200
-+@@ -252,6 +252,7 @@
-+ memset(handle, 0, sizeof(*handle));
-+ handle->h_buffer_credits = nblocks;
-+ handle->h_ref = 1;
-++ INIT_LIST_HEAD(&handle->h_jcb);
-+
-+ lockdep_init_map(&handle->h_lockdep_map, "jbd2_handle",
-+ &jbd2_handle_key, 0);
-+@@ -1350,6 +1351,36 @@
-+ }
-+
-+ /**
-++ * void jbd2_journal_callback_set() - Register a callback function for this handle.
-++ * @handle: handle to attach the callback to.
-++ * @func: function to callback.
-++ * @jcb: structure with additional information required by func() , and
-++ * some space for jbd2 internal information.
-++ *
-++ * The function will be
-++ * called when the transaction that this handle is part of has been
-++ * committed to disk with the original callback data struct and the
-++ * error status of the journal as parameters. There is no guarantee of
-++ * ordering between handles within a single transaction, nor between
-++ * callbacks registered on the same handle.
-++ *
-++ * The caller is responsible for allocating the journal_callback struct.
-++ * This is to allow the caller to add as much extra data to the callback
-++ * as needed, but reduce the overhead of multiple allocations. The caller
-++ * allocated struct must start with a struct journal_callback at offset 0,
-++ * and has the caller-specific data afterwards.
-++ */
-++void jbd2_journal_callback_set(handle_t *handle,
-++ void (*func)(struct journal_callback *jcb, int error),
-++ struct journal_callback *jcb)
-++{
-++ spin_lock(&handle->h_transaction->t_jcb_lock);
-++ list_add_tail(&jcb->jcb_list, &handle->h_jcb);
-++ spin_unlock(&handle->h_transaction->t_jcb_lock);
-++ jcb->jcb_func = func;
-++}
-++
-++/**
-+ * int jbd2_journal_stop() - complete a transaction
-+ * @handle: tranaction to complete.
-+ *
-+@@ -1423,6 +1454,11 @@
-+ wake_up(&journal->j_wait_transaction_locked);
-+ }
-+
-++ /* Move callbacks from the handle to the transaction. */
-++ spin_lock(&transaction->t_jcb_lock);
-++ list_splice(&handle->h_jcb, &transaction->t_jcb);
-++ spin_unlock(&transaction->t_jcb_lock);
-++
-+ /*
-+ * If the handle is marked SYNC, we need to set another commit
-+ * going! We also want to force a commit if the current
diff --git a/debian/patches/series b/debian/patches/series
index 35cfc77..9b13eee 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -17,4 +17,3 @@ fix-bashisms-for-dash.patch
#fix_dentry_conf_test.patch
#cacheflush_remove_mark_rodata.patch
#615749_no_add_needed
-#modified-debian-specific-stuff.patch
--
Lustre Debian Packaging
More information about the Pkg-lustre-svn-commit
mailing list