From 3ed66bd2e676a36603f8637a934f516296a07a45 Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Wed, 17 Jul 2019 18:52:33 -0400 Subject: [PATCH] LU-12561 kernel: Remove unused patches With 2.6 kernel support removed, these patches are no longer used. Test-Parameters: trivial Signed-off-by: Patrick Farrell Change-Id: If374a060f4a4522a10111923c92fa7ccaf791df3 Reviewed-on: https://review.whamcloud.com/35547 Tested-by: jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Andreas Dilger --- .../patches/blkdev_tunables-2.6-rhel6.patch | 40 -- .../patches/dev_read_only-2.6.32-rhel6.patch | 174 ----- .../patches/dev_read_only-2.6.32-sles11.patch | 150 ----- lustre/kernel_patches/patches/kallsyms-rhel6.patch | 10 - .../patches/module-load-deadlock-rhel6.patch | 333 ---------- .../patches/mpt-fusion-max-sge-rhel6.patch | 37 -- .../patches/quota-avoid-dqget-calls.patch | 62 -- .../patches/quota-replace-dqptr-sem-el6.8.patch | 698 --------------------- .../patches/quota-replace-dqptr-sem-sles11.patch | 663 ------------------- .../patches/quota-replace-dqptr-sem.patch | 683 -------------------- .../patches/raid5-mmp-unplug-dev-rhel6.patch | 28 - .../patches/raid5-mmp-unplug-dev-sles11sp1.patch | 30 - 12 files changed, 2908 deletions(-) delete mode 100644 lustre/kernel_patches/patches/blkdev_tunables-2.6-rhel6.patch delete mode 100644 lustre/kernel_patches/patches/dev_read_only-2.6.32-rhel6.patch delete mode 100644 lustre/kernel_patches/patches/dev_read_only-2.6.32-sles11.patch delete mode 100644 lustre/kernel_patches/patches/kallsyms-rhel6.patch delete mode 100644 lustre/kernel_patches/patches/module-load-deadlock-rhel6.patch delete mode 100644 lustre/kernel_patches/patches/mpt-fusion-max-sge-rhel6.patch delete mode 100644 lustre/kernel_patches/patches/quota-avoid-dqget-calls.patch delete mode 100644 lustre/kernel_patches/patches/quota-replace-dqptr-sem-el6.8.patch delete mode 100644 lustre/kernel_patches/patches/quota-replace-dqptr-sem-sles11.patch delete mode 100644 lustre/kernel_patches/patches/quota-replace-dqptr-sem.patch delete mode 100644 lustre/kernel_patches/patches/raid5-mmp-unplug-dev-rhel6.patch delete mode 100644 lustre/kernel_patches/patches/raid5-mmp-unplug-dev-sles11sp1.patch diff --git a/lustre/kernel_patches/patches/blkdev_tunables-2.6-rhel6.patch b/lustre/kernel_patches/patches/blkdev_tunables-2.6-rhel6.patch deleted file mode 100644 index e58bc07..0000000 --- a/lustre/kernel_patches/patches/blkdev_tunables-2.6-rhel6.patch +++ /dev/null @@ -1,40 +0,0 @@ -Index: b/include/linux/blkdev.h -=================================================================== ---- a/include/linux/blkdev.h -+++ b/include/linux/blkdev.h -@@ -1026,6 +1026,6 @@ extern int blk_verify_command(unsigned c - enum blk_default_limits { -- BLK_MAX_SEGMENTS = 128, -+ BLK_MAX_SEGMENTS = 256, - BLK_SAFE_MAX_SECTORS = 255, -- BLK_DEF_MAX_SECTORS = 1024, -+ BLK_DEF_MAX_SECTORS = 2048, - BLK_MAX_SEGMENT_SIZE = 65536, - BLK_SEG_BOUNDARY_MASK = 0xFFFFFFFFUL, - }; -Index: linux-2.6.32.x86_64/include/scsi/scsi.h -=================================================================== ---- linux-2.6.32.x86_64.orig/include/scsi/scsi.h 2010-10-26 21:45:52.000000000 +0300 -+++ linux-2.6.32.x86_64/include/scsi/scsi.h 2010-10-29 11:16:35.000000000 +0300 -@@ -19,7 +19,7 @@ struct scsi_cmnd; - * to SG_MAX_SINGLE_ALLOC to pack correctly at the highest order. The - * minimum value is 32 - */ --#define SCSI_MAX_SG_SEGMENTS 128 -+#define SCSI_MAX_SG_SEGMENTS 256 - - /* - * Like SCSI_MAX_SG_SEGMENTS, but for archs that have sg chaining. This limit -Index: linux-2.6.32.x86_64/drivers/scsi/isci/init.c -=================================================================== ---- linux-2.6.32.x86_64/drivers/scsi/isci/init.c -+++ linux-2.6.32.x86_64/drivers/scsi/isci/init.c -@@ -19,7 +19,7 @@ - .can_queue = ISCI_CAN_QUEUE_VAL, - .cmd_per_lun = 1, - .this_id = -1, -- .sg_tablesize = SG_ALL, -+ .sg_tablesize = 128, - .max_sectors = SCSI_DEFAULT_MAX_SECTORS, - .use_clustering = ENABLE_CLUSTERING, - .eh_device_reset_handler = sas_eh_device_reset_handler, diff --git a/lustre/kernel_patches/patches/dev_read_only-2.6.32-rhel6.patch b/lustre/kernel_patches/patches/dev_read_only-2.6.32-rhel6.patch deleted file mode 100644 index 8c79b40..0000000 --- a/lustre/kernel_patches/patches/dev_read_only-2.6.32-rhel6.patch +++ /dev/null @@ -1,174 +0,0 @@ -This patch is no longer needed for Lustre. It is only included -for testing and ease of using the same kernel with older Lustre -versions. This testing functionality was replaced in Linux 3.0 -by the dm-flakey driver. - -This functionality is mainly used during testing, in order to -simulate a server crash for ldiskfs by discarding all of the -writes to the filesystem. For recovery testing we could simulate -this by using a special loopback or DM device that also discards -writes to the device. - -This functionality is also used by target "failback" in order -to speed up service shutdown and takeover by the other node -during controlled operation. However, it would also be possible -to do this by simply allowing all of the in-flight requests to -complete and then waiting for the service to stop. This will -also be needed by the DMU-OSD, because discarding of writes on -a DMU-based target is not safe as it could trigger a storage -failure if the data is ever read from disk again and the -checksum does not match that expected by the block pointer. - -Index: linux-2.6.32-131.0.15.el6.x86_64/block/blk-core.c -=================================================================== ---- linux-2.6.32-131.0.15.el6.x86_64.orig/block/blk-core.c 2011-05-10 21:38:33.000000000 +0300 -+++ linux-2.6.32-131.0.15.el6.x86_64/block/blk-core.c 2011-05-19 21:01:04.000000000 +0300 -@@ -1416,6 +1416,8 @@ static inline int should_fail_request(st - - #endif /* CONFIG_FAIL_MAKE_REQUEST */ - -+int dev_check_rdonly(struct block_device *bdev); -+ - /* - * Check whether this bio extends beyond the end of the device. - */ -@@ -1517,6 +1519,12 @@ static inline void __generic_make_reques - goto end_io; - } - -+ /* this is cfs's dev_rdonly check */ -+ if (bio_rw(bio) == WRITE && dev_check_rdonly(bio->bi_bdev)) { -+ err = 0; -+ goto end_io; -+ } -+ - if (should_fail_request(bio)) - goto end_io; - -@@ -2619,6 +2638,99 @@ int kblockd_schedule_work(struct request - } - EXPORT_SYMBOL(kblockd_schedule_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); -+EXPORT_SYMBOL(dev_check_rdonly); - int __init blk_dev_init(void) - { - BUILD_BUG_ON(__REQ_NR_BITS > 8 * -Index: linux-2.6.32-131.0.15.el6.x86_64/fs/block_dev.c -=================================================================== ---- linux-2.6.32-131.0.15.el6.x86_64.orig/fs/block_dev.c 2011-05-10 21:38:29.000000000 +0300 -+++ linux-2.6.32-131.0.15.el6.x86_64/fs/block_dev.c 2011-05-19 21:01:04.000000000 +0300 -@@ -1389,6 +1389,7 @@ static int __blkdev_put(struct block_dev - if (bdev != bdev->bd_contains) - victim = bdev->bd_contains; - bdev->bd_contains = NULL; -+ dev_clear_rdonly(bdev); - - put_disk(disk); - module_put(owner); -Index: linux-2.6.32-131.0.15.el6.x86_64/include/linux/fs.h -=================================================================== ---- linux-2.6.32-131.0.15.el6.x86_64.orig/include/linux/fs.h 2011-05-10 21:38:29.000000000 +0300 -+++ linux-2.6.32-131.0.15.el6.x86_64/include/linux/fs.h 2011-05-19 21:01:04.000000000 +0300 -@@ -2244,6 +2244,10 @@ struct bio; - 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); diff --git a/lustre/kernel_patches/patches/dev_read_only-2.6.32-sles11.patch b/lustre/kernel_patches/patches/dev_read_only-2.6.32-sles11.patch deleted file mode 100644 index db8fe02..0000000 --- a/lustre/kernel_patches/patches/dev_read_only-2.6.32-sles11.patch +++ /dev/null @@ -1,150 +0,0 @@ -diff -ur linux-2.6.32.46-0.orig//block/blk-core.c linux-2.6.32.46-0/block/blk-core.c ---- linux-2.6.32.46-0.orig//block/blk-core.c 2013-04-26 10:23:22.000000000 -0400 -+++ linux-2.6.32.46-0/block/blk-core.c 2013-04-26 10:25:46.000000000 -0400 -@@ -1350,6 +1350,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. - */ -@@ -1451,6 +1453,12 @@ - if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) - goto end_io; - -+ /* this is cfs's dev_rdonly check */ -+ if (bio_rw(bio) == WRITE && dev_check_rdonly(bio->bi_bdev)) { -+ err = 0; -+ goto end_io; -+ } -+ - if (should_fail_request(bio)) - goto end_io; - -@@ -2494,6 +2502,99 @@ - } - EXPORT_SYMBOL(kblockd_schedule_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); -+EXPORT_SYMBOL(dev_check_rdonly); - int __init blk_dev_init(void) - { - BUILD_BUG_ON(__REQ_NR_BITS > 8 * -diff -ur linux-2.6.32.46-0.orig//fs/block_dev.c linux-2.6.32.46-0/fs/block_dev.c ---- linux-2.6.32.46-0.orig//fs/block_dev.c 2013-04-26 10:23:31.000000000 -0400 -+++ linux-2.6.32.46-0/fs/block_dev.c 2013-04-26 10:25:46.000000000 -0400 -@@ -1374,6 +1374,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 -ur linux-2.6.32.46-0.orig//include/linux/fs.h linux-2.6.32.46-0/include/linux/fs.h ---- linux-2.6.32.46-0.orig//include/linux/fs.h 2013-04-26 10:23:39.000000000 -0400 -+++ linux-2.6.32.46-0/include/linux/fs.h 2013-04-26 10:25:46.000000000 -0400 -@@ -2237,6 +2237,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); diff --git a/lustre/kernel_patches/patches/kallsyms-rhel6.patch b/lustre/kernel_patches/patches/kallsyms-rhel6.patch deleted file mode 100644 index 94430577..0000000 --- a/lustre/kernel_patches/patches/kallsyms-rhel6.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/kernel/kallsyms.c.orig 2017-07-12 13:01:00.143416830 -0700 -+++ a/kernel/kallsyms.c 2017-07-12 13:01:40.438112247 -0700 -@@ -181,6 +181,7 @@ unsigned long kallsyms_lookup_name(const - } - return module_kallsyms_lookup_name(name); - } -+EXPORT_SYMBOL_GPL(kallsyms_lookup_name); - - int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, - unsigned long), diff --git a/lustre/kernel_patches/patches/module-load-deadlock-rhel6.patch b/lustre/kernel_patches/patches/module-load-deadlock-rhel6.patch deleted file mode 100644 index 9ca6ec5..0000000 --- a/lustre/kernel_patches/patches/module-load-deadlock-rhel6.patch +++ /dev/null @@ -1,333 +0,0 @@ -module: Fix a few concurrent module loading races - -Concurrently starting multiple OSTs on a single OSS frequently -triggers 30s deadlocks on module_mutex. This RHEL 6 kernel bug -applies to any module that results in additional request_module() -calls in its init callback. In Lustre, at least ptlrpc and libcfs are -affected. This patch adapts fixes from the following upstream -commits: - - 9bea7f2 module: fix bne2 "gave up waiting for init of module - libcrc32c" - be593f4 module: verify_export_symbols under the lock - 3bafeb6 module: move find_module check to end - 80a3d1b module: move sysfs exposure to end of load_module - -diff -rNup linux-2.6.32-431.20.3.el6.orig/kernel/module.c linux-2.6.32-431.20.3.el6/kernel/module.c ---- linux-2.6.32-431.20.3.el6.orig/kernel/module.c 2014-06-07 05:42:39.000000000 +0800 -+++ linux-2.6.32-431.20.3.el6/kernel/module.c 2014-07-28 00:04:43.000000000 +0800 -@@ -658,6 +658,33 @@ static int already_uses(struct module *a - } - - /* Module a uses b */ -+static int ref_module(struct module *a, struct module *b) -+{ -+ struct module_use *use; -+ int err; -+ -+ if (b == NULL || already_uses(a, b)) -+ return 0; -+ -+ /* If module isn't available, we fail. */ -+ err = strong_try_module_get(b); -+ if (err) -+ return err; -+ -+ DEBUGP("Allocating new usage for %s.\n", a->name); -+ use = kmalloc(sizeof(*use), GFP_ATOMIC); -+ if (!use) { -+ printk("%s: out of memory loading\n", a->name); -+ module_put(b); -+ return -ENOMEM; -+ } -+ -+ use->module_which_uses = a; -+ list_add(&use->list, &b->modules_which_use_me); -+ return 0; -+} -+ -+/* Module a uses b */ - int use_module(struct module *a, struct module *b) - { - struct module_use *use; -@@ -707,7 +734,6 @@ static void module_unload_free(struct mo - module_put(i); - list_del(&use->list); - kfree(use); -- sysfs_remove_link(i->holders_dir, mod->name); - /* There can be at most one match. */ - break; - } -@@ -962,6 +988,11 @@ static inline void module_unload_free(st - { - } - -+static inline int ref_module(struct module *a, struct module *b) -+{ -+ return strong_try_module_get(b); -+} -+ - int use_module(struct module *a, struct module *b) - { - return strong_try_module_get(b) == 0; -@@ -1130,24 +1161,60 @@ static inline int same_magic(const char - static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, - unsigned int versindex, - const char *name, -- struct module *mod) -+ struct module *mod, -+ char ownername[]) - { - struct module *owner; - const struct kernel_symbol *sym; - const unsigned long *crc; -+ int err; - -+ mutex_lock(&module_mutex); - sym = find_symbol(name, &owner, &crc, - !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); -- /* use_module can fail due to OOM, -- or module initialization or unloading */ -- if (sym) { -- if (!check_version(sechdrs, versindex, name, mod, crc, owner) -- || !use_module(mod, owner)) -- sym = NULL; -+ if (!sym) -+ goto unlock; -+ -+ if (!check_version(sechdrs, versindex, name, mod, crc, owner)) { -+ sym = ERR_PTR(-EINVAL); -+ goto getname; - } -+ -+ err = ref_module(mod, owner); -+ if (err) { -+ sym = ERR_PTR(err); -+ goto getname; -+ } -+ -+getname: -+ /* We must make copy under the lock if we failed to get ref. */ -+ strncpy(ownername, module_name(owner), MODULE_NAME_LEN); -+unlock: -+ mutex_unlock(&module_mutex); - return sym; - } - -+static const struct kernel_symbol *resolve_symbol_wait(Elf_Shdr *sechdrs, -+ unsigned int versindex, -+ const char *name, -+ struct module *mod) -+{ -+ const struct kernel_symbol *ksym; -+ char ownername[MODULE_NAME_LEN]; -+ -+ mutex_unlock(&module_mutex); -+ if (wait_event_interruptible_timeout(module_wq, -+ !IS_ERR(ksym = resolve_symbol(sechdrs, versindex, name, -+ mod, ownername)) || -+ PTR_ERR(ksym) != -EBUSY, -+ msecs_to_jiffies(30 * MSEC_PER_SEC)) <= 0) { -+ printk(KERN_WARNING "%s: gave up waiting for init of module %s.\n", -+ mod->name, ownername); -+ } -+ mutex_lock(&module_mutex); -+ return ksym; -+} -+ - /* - * /sys/module/foo/sections stuff - * J. Corbet -@@ -1375,6 +1442,30 @@ static inline void remove_notes_attrs(st - #endif - - #ifdef CONFIG_SYSFS -+static void add_usage_links(struct module *mod) -+{ -+#ifdef CONFIG_MODULE_UNLOAD -+ struct module_use *use; -+ int nowarn; -+ -+ list_for_each_entry(use, &mod->modules_which_use_me, list) { -+ nowarn = sysfs_create_link(use->module_which_uses->holders_dir, -+ &mod->mkobj.kobj, mod->name); -+ } -+#endif -+} -+ -+static void del_usage_links(struct module *mod) -+{ -+#ifdef CONFIG_MODULE_UNLOAD -+ struct module_use *use; -+ -+ list_for_each_entry(use, &mod->modules_which_use_me, list) -+ sysfs_remove_link(use->module_which_uses->holders_dir, mod->name); -+#endif -+} -+ -+ - int module_add_modinfo_attrs(struct module *mod) - { - struct module_attribute *attr; -@@ -1456,6 +1547,10 @@ int mod_sysfs_setup(struct module *mod, - { - int err; - -+ err = mod_sysfs_init(mod); -+ if (err) -+ goto out; -+ - mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj); - if (!mod->holders_dir) { - err = -ENOMEM; -@@ -1470,6 +1565,8 @@ int mod_sysfs_setup(struct module *mod, - if (err) - goto out_unreg_param; - -+ add_usage_links(mod); -+ - kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD); - return 0; - -@@ -1479,6 +1576,7 @@ out_unreg_holders: - kobject_put(mod->holders_dir); - out_unreg: - kobject_put(&mod->mkobj.kobj); -+out: - return err; - } - -@@ -1493,10 +1591,15 @@ static void mod_sysfs_fini(struct module - { - } - -+static void del_usage_links(struct module *mod) -+{ -+} -+ - #endif /* CONFIG_SYSFS */ - - static void mod_kobject_remove(struct module *mod) - { -+ del_usage_links(mod); - module_remove_modinfo_attrs(mod); - module_param_sysfs_remove(mod); - kobject_put(mod->mkobj.drivers_dir); -@@ -1576,6 +1679,8 @@ EXPORT_SYMBOL_GPL(__symbol_get); - /* - * Ensure that an exported symbol [global namespace] does not already exist - * in the kernel or in some other module's exported symbol table. -+ * -+ * You must hold the module_mutex. - */ - static int verify_export_symbols(struct module *mod) - { -@@ -1641,21 +1746,23 @@ static int simplify_symbols(Elf_Shdr *se - break; - - case SHN_UNDEF: -- ksym = resolve_symbol(sechdrs, versindex, -- strtab + sym[i].st_name, mod); -+ ksym = resolve_symbol_wait(sechdrs, versindex, -+ strtab + sym[i].st_name, -+ mod); - /* Ok if resolved. */ -- if (ksym) { -+ if (ksym && !IS_ERR(ksym)) { - sym[i].st_value = ksym->value; - break; - } - - /* Ok if weak. */ -- if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK) -+ if (!ksym && ELF_ST_BIND(sym[i].st_info) == STB_WEAK) - break; - -- printk(KERN_WARNING "%s: Unknown symbol %s\n", -- mod->name, strtab + sym[i].st_name); -- ret = -ENOENT; -+ printk(KERN_WARNING "%s: Unknown symbol %s (err %li)\n", -+ mod->name, strtab + sym[i].st_name, -+ PTR_ERR(ksym)); -+ ret = PTR_ERR(ksym) ?: -ENOENT; - break; - - default: -@@ -2240,11 +2347,6 @@ static noinline struct module *load_modu - goto free_mod; - } - -- if (find_module(mod->name)) { -- err = -EEXIST; -- goto free_mod; -- } -- - mod->state = MODULE_STATE_COMING; - - /* Allow arches to frob section contents and sizes. */ -@@ -2338,11 +2440,6 @@ static noinline struct module *load_modu - /* Now we've moved module, initialize linked lists, etc. */ - module_unload_init(mod); - -- /* add kobject, so we can reference it. */ -- err = mod_sysfs_init(mod); -- if (err) -- goto free_unload; -- - /* Set up license info based on the info section */ - set_license(mod, get_modinfo(sechdrs, infoindex, "license")); - -@@ -2461,11 +2558,6 @@ static noinline struct module *load_modu - goto cleanup; - } - -- /* Find duplicate symbols */ -- err = verify_export_symbols(mod); -- if (err < 0) -- goto cleanup; -- - /* Set up and sort exception table */ - mod->extable = section_objs(hdr, sechdrs, secstrings, "__ex_table", - sizeof(*mod->extable), &mod->num_exentries); -@@ -2521,6 +2613,16 @@ static noinline struct module *load_modu - * function to insert in a way safe to concurrent readers. - * The mutex protects against concurrent writers. - */ -+ if (find_module(mod->name)) { -+ err = -EEXIST; -+ goto already_exists; -+ } -+ -+ /* Find duplicate symbols */ -+ err = verify_export_symbols(mod); -+ if (err < 0) -+ goto already_exists; -+ - list_add_rcu(&mod->list, &modules); - - err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL); -@@ -2530,6 +2632,7 @@ static noinline struct module *load_modu - err = mod_sysfs_setup(mod, mod->kp, mod->num_kp); - if (err < 0) - goto unlink; -+ - add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); - add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs); - -@@ -2544,15 +2647,13 @@ static noinline struct module *load_modu - unlink: - /* Unlink carefully: kallsyms could be walking list. */ - list_del_rcu(&mod->list); -+ already_exists: - synchronize_sched(); - module_arch_cleanup(mod); - ddebug: - dynamic_debug_remove(debug); - cleanup: - free_modinfo(mod); -- kobject_del(&mod->mkobj.kobj); -- kobject_put(&mod->mkobj.kobj); -- free_unload: - module_unload_free(mod); - #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) - percpu_modfree(mod->refptr); diff --git a/lustre/kernel_patches/patches/mpt-fusion-max-sge-rhel6.patch b/lustre/kernel_patches/patches/mpt-fusion-max-sge-rhel6.patch deleted file mode 100644 index 1fa1d26..0000000 --- a/lustre/kernel_patches/patches/mpt-fusion-max-sge-rhel6.patch +++ /dev/null @@ -1,37 +0,0 @@ -Increase MAX_SGE for fusion mpt driver. - -Index: linux-2.6.32.i386/drivers/message/fusion/Kconfig -=================================================================== ---- linux-2.6.32.i386.orig/drivers/message/fusion/Kconfig 2009-12-03 09:21:21.000000000 +0530 -+++ linux-2.6.32.i386/drivers/message/fusion/Kconfig 2010-03-16 16:45:08.000000000 +0530 -@@ -61,9 +61,9 @@ - LSISAS1078 - - config FUSION_MAX_SGE -- int "Maximum number of scatter gather entries (16 - 128)" -- default "128" -- range 16 128 -+ int "Maximum number of scatter gather entries (16 - 256)" -+ default "256" -+ range 16 256 - help - This option allows you to specify the maximum number of scatter- - gather entries per I/O. The driver default is 128, which matches -Index: linux-2.6.32.i386/drivers/message/fusion/mptbase.h -=================================================================== ---- linux-2.6.32.i386.orig/drivers/message/fusion/mptbase.h 2009-12-03 09:21:21.000000000 +0530 -+++ linux-2.6.32.i386/drivers/message/fusion/mptbase.h 2010-03-16 16:46:54.000000000 +0530 -@@ -165,10 +165,10 @@ - * Set the MAX_SGE value based on user input. - */ - #ifdef CONFIG_FUSION_MAX_SGE --#if CONFIG_FUSION_MAX_SGE < 16 -+#if CONFIG_FUSION_MAX_SGE < 16 - #define MPT_SCSI_SG_DEPTH 16 --#elif CONFIG_FUSION_MAX_SGE > 128 --#define MPT_SCSI_SG_DEPTH 128 -+#elif CONFIG_FUSION_MAX_SGE > 256 -+#define MPT_SCSI_SG_DEPTH 256 - #else - #define MPT_SCSI_SG_DEPTH CONFIG_FUSION_MAX_SGE - #endif diff --git a/lustre/kernel_patches/patches/quota-avoid-dqget-calls.patch b/lustre/kernel_patches/patches/quota-avoid-dqget-calls.patch deleted file mode 100644 index bf5107c..0000000 --- a/lustre/kernel_patches/patches/quota-avoid-dqget-calls.patch +++ /dev/null @@ -1,62 +0,0 @@ -commit 1ea06bec78a128adc995ca32bd906a6c9bb9cf91 -Author: Niu Yawei -Date: Wed Jun 4 12:20:30 2014 +0800 - - quota: avoid unnecessary dqget()/dqput() calls - - Avoid unnecessary dqget()/dqput() calls in __dquot_initialize(), - that will introduce global lock contention otherwise. - - Signed-off-by: Lai Siyao - Signed-off-by: Niu Yawei - Signed-off-by: Jan Kara -Index: linux-2.6.32-431.5.1.el6/fs/quota/dquot.c -=================================================================== ---- linux-2.6.32-431.5.1.el6.orig/fs/quota/dquot.c -+++ linux-2.6.32-431.5.1.el6/fs/quota/dquot.c -@@ -1230,7 +1230,7 @@ static int info_bdq_free(struct dquot *d - int dquot_initialize(struct inode *inode, int type) - { - unsigned int id = 0; -- int cnt, ret = 0; -+ int cnt, ret = 0, init_needed = 0; - struct dquot *got[MAXQUOTAS] = { NULL, NULL }; - struct super_block *sb = inode->i_sb; - qsize_t rsv; -@@ -1244,6 +1244,15 @@ int dquot_initialize(struct inode *inode - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (type != -1 && cnt != type) - continue; -+ /* -+ * The i_dquot should have been initialized in most cases, -+ * we check it without locking here to avoid unnecessary -+ * dqget()/dqput() calls. -+ */ -+ if (inode->i_dquot[cnt]) -+ continue; -+ init_needed = 1; -+ - switch (cnt) { - case USRQUOTA: - id = inode->i_uid; -@@ -1255,6 +1264,10 @@ int dquot_initialize(struct inode *inode - got[cnt] = dqget(sb, id, cnt); - } - -+ /* All required i_dquot has been initialized */ -+ if (!init_needed) -+ return 0; -+ - spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) - goto out_err; -@@ -1264,6 +1277,9 @@ int dquot_initialize(struct inode *inode - /* Avoid races with quotaoff() */ - if (!sb_has_quota_active(sb, cnt)) - continue; -+ /* We could race with quotaon or dqget() could have failed */ -+ if (!got[cnt]) -+ continue; - if (!inode->i_dquot[cnt]) { - inode->i_dquot[cnt] = got[cnt]; - got[cnt] = NULL; diff --git a/lustre/kernel_patches/patches/quota-replace-dqptr-sem-el6.8.patch b/lustre/kernel_patches/patches/quota-replace-dqptr-sem-el6.8.patch deleted file mode 100644 index 24848df..0000000 --- a/lustre/kernel_patches/patches/quota-replace-dqptr-sem-el6.8.patch +++ /dev/null @@ -1,698 +0,0 @@ -Remove dqptr_sem (but kept in struct quota_info to keep kernel ABI -unchanged), and the functionality of this lock is implemented by -other locks: -* i_dquot is protected by i_lock, however only this pointer, the - content of this struct is by dq_data_lock. -* Q_GETFMT is now protected with dqonoff_mutex instead of dqptr_sem. - - fs/quota/dquot.c | 243 +++++++++++++++++++++++++++++------------------------ - fs/quota/quota.c | 6 - - fs/stat.c | 16 ++- - fs/super.c | 1 - include/linux/fs.h | 2 - 5 files changed, 154 insertions(+), 114 deletions(-) - -Index: linux-2.6.32-358.0.1.el6/fs/quota/dquot.c -=================================================================== ---- linux-2.6.32-358.0.1.el6.orig/fs/quota/dquot.c -+++ linux-2.6.32-358.0.1.el6/fs/quota/dquot.c -@@ -83,22 +83,17 @@ - /* - * There are three quota SMP locks. dq_list_lock protects all lists with quotas - * and quota formats, dqstats structure containing statistics about the lists -- * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures and -- * also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes. -- * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly -- * in inode_add_bytes() and inode_sub_bytes(). dq_state_lock protects -- * modifications of quota state (on quotaon and quotaoff) and readers who care -- * about latest values take it as well. -+ * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures. -+ * dq_state_lock protects modifications of quota state (on quotaon and quotaoff) -+ * and readers who care about latest values take it as well. - * -- * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock, -+ * The spinlock ordering is hence: i_lock > dq_data_lock > dq_list_lock, - * dq_list_lock > dq_state_lock - * - * Note that some things (eg. sb pointer, type, id) doesn't change during - * the life of the dquot structure and so needn't to be protected by a lock - * -- * Any operation working on dquots via inode pointers must hold dqptr_sem. If -- * operation is just reading pointers from inode (or not using them at all) the -- * read lock is enough. If pointers are altered function must hold write lock -+ * Any operation working on dquots via inode pointers must hold i_lock. - * (these locking rules also apply for S_NOQUOTA flag in the inode - note that - * for altering the flag i_mutex is also needed). - * -@@ -112,15 +107,8 @@ - * spinlock to internal buffers before writing. - * - * Lock ordering (including related VFS locks) is the following: -- * i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > -- * dqio_mutex -- * The lock ordering of dqptr_sem imposed by quota code is only dqonoff_sem > -- * dqptr_sem. But filesystem has to count with the fact that functions such as -- * dquot_alloc_space() acquire dqptr_sem and they usually have to be called -- * from inside a transaction to keep filesystem consistency after a crash. Also -- * filesystems usually want to do some IO on dquot from ->mark_dirty which is -- * called with dqptr_sem held. -- * i_mutex on quota files is special (it's below dqio_mutex) -+ * i_mutex > dqonoff_sem > journal_lock > dquot->dq_lock > dqio_mutex -+ * i_mutex on quota files is special (it's below dqio_mutex) - */ - - static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock); -@@ -868,7 +856,6 @@ static inline int dqput_blocks(struct dq - /* - * Remove references to dquots from inode and add dquot to list for freeing - * if we have the last referece to dquot -- * We can't race with anybody because we hold dqptr_sem for writing... - */ - static int remove_inode_dquot_ref(struct inode *inode, int type, - struct list_head *tofree_head) -@@ -926,10 +913,12 @@ static void remove_dquot_ref(struct supe - * We have to scan also I_NEW inodes because they can already - * have quota pointer initialized. Luckily, we need to touch - * only quota pointers and these have separate locking -- * (dqptr_sem). -+ * (i_lock). - */ -+ spin_lock(&inode->i_lock); - if (!IS_NOQUOTA(inode)) - remove_inode_dquot_ref(inode, type, tofree_head); -+ spin_unlock(&inode->i_lock); - } - spin_unlock(&inode_lock); - } -@@ -940,9 +929,7 @@ static void drop_dquot_ref(struct super_ - LIST_HEAD(tofree_head); - - if (sb->dq_op) { -- down_write(&sb_dqopt(sb)->dqptr_sem); - remove_dquot_ref(sb, type, &tofree_head); -- up_write(&sb_dqopt(sb)->dqptr_sem); - put_dquot_list(&tofree_head); - } - } -@@ -1239,8 +1226,6 @@ static int info_bdq_free(struct dquot *d - - /* - * Initialize quota pointers in inode -- * We do things in a bit complicated way but by that we avoid calling -- * dqget() and thus filesystem callbacks under dqptr_sem. - */ - int dquot_initialize(struct inode *inode, int type) - { -@@ -1270,8 +1255,7 @@ int dquot_initialize(struct inode *inode - got[cnt] = dqget(sb, id, cnt); - } - -- down_write(&sb_dqopt(sb)->dqptr_sem); -- /* Having dqptr_sem we know NOQUOTA flags can't be altered... */ -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) - goto out_err; - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -@@ -1288,12 +1272,16 @@ int dquot_initialize(struct inode *inode - * did a write before quota was turned on - */ - rsv = inode_get_rsv_space(inode); -- if (unlikely(rsv)) -+ if (unlikely(rsv)) { -+ spin_lock(&dq_data_lock); - dquot_resv_space(inode->i_dquot[cnt], rsv); -+ spin_unlock(&dq_data_lock); -+ } - } - } - out_err: -- up_write(&sb_dqopt(sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); -+ - /* Drop unused references */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - dqput(got[cnt]); -@@ -1309,12 +1297,12 @@ int dquot_drop(struct inode *inode) - int cnt; - struct dquot *put[MAXQUOTAS]; - -- down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_lock(&inode->i_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - put[cnt] = inode->i_dquot[cnt]; - inode->i_dquot[cnt] = NULL; - } -- up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - dqput(put[cnt]); -@@ -1357,27 +1345,42 @@ static qsize_t *inode_reserved_space(str - return inode->i_sb->dq_op->get_reserved_space(inode); - } - -+static inline void __inode_add_rsv_space(struct inode *inode, qsize_t number) -+{ -+ *inode_reserved_space(inode) += number; -+} -+ - void inode_add_rsv_space(struct inode *inode, qsize_t number) - { - spin_lock(&inode->i_lock); -- *inode_reserved_space(inode) += number; -+ __inode_add_rsv_space(inode, number); - spin_unlock(&inode->i_lock); - } - EXPORT_SYMBOL(inode_add_rsv_space); - --void inode_claim_rsv_space(struct inode *inode, qsize_t number) -+static inline void __inode_claim_rsv_space(struct inode *inode, qsize_t number) - { -- spin_lock(&inode->i_lock); - *inode_reserved_space(inode) -= number; - __inode_add_bytes(inode, number); -+} -+ -+void inode_claim_rsv_space(struct inode *inode, qsize_t number) -+{ -+ spin_lock(&inode->i_lock); -+ __inode_claim_rsv_space(inode, number); - spin_unlock(&inode->i_lock); - } - EXPORT_SYMBOL(inode_claim_rsv_space); - -+static inline void __inode_sub_rsv_space(struct inode *inode, qsize_t number) -+{ -+ *inode_reserved_space(inode) -= number; -+} -+ - void inode_sub_rsv_space(struct inode *inode, qsize_t number) - { - spin_lock(&inode->i_lock); -- *inode_reserved_space(inode) -= number; -+ __inode_sub_rsv_space(inode, number); - spin_unlock(&inode->i_lock); - } - EXPORT_SYMBOL(inode_sub_rsv_space); -@@ -1388,9 +1391,8 @@ static qsize_t inode_get_rsv_space(struc - - if (!inode->i_sb->dq_op->get_reserved_space) - return 0; -- spin_lock(&inode->i_lock); -+ - ret = *inode_reserved_space(inode); -- spin_unlock(&inode->i_lock); - return ret; - } - -@@ -1398,17 +1400,17 @@ static void inode_incr_space(struct inod - int reserve) - { - if (reserve) -- inode_add_rsv_space(inode, number); -+ __inode_add_rsv_space(inode, number); - else -- inode_add_bytes(inode, number); -+ __inode_add_bytes(inode, number); - } - - static void inode_decr_space(struct inode *inode, qsize_t number, int reserve) - { - if (reserve) -- inode_sub_rsv_space(inode, number); -+ __inode_sub_rsv_space(inode, number); - else -- inode_sub_bytes(inode, number); -+ __inode_sub_bytes(inode, number); - } - - /* -@@ -1430,6 +1432,7 @@ int __dquot_alloc_space(struct inode *in - struct dquot_warn warn[MAXQUOTAS]; - struct dquot **dquots = inode->i_dquot; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - int reserve = flags & DQUOT_SPACE_RESERVE; - - /* - * First test before acquiring mutex - solves deadlocks when we -@@ -1440,48 +1443,53 @@ int __dquot_alloc_space(struct inode *in - goto out; - } - -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) { - inode_incr_space(inode, number, reserve); -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - goto out; - } - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - warn[cnt].w_type = QUOTA_NL_NOWARN; - - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!dquots[cnt]) -+ dquot[cnt] = dquots[cnt]; -+ if (!dquot[cnt]) - continue; -- if (check_bdq(dquots[cnt], number, -+ atomic_inc(&dquot[cnt]->dq_count); -+ if (check_bdq(dquot[cnt], number, - (flags & DQUOT_SPACE_WARN), &warn[cnt]) - == NO_QUOTA && !(flags & DQUOT_SPACE_NOFAIL)) { - ret = NO_QUOTA; - spin_unlock(&dq_data_lock); -+ spin_unlock(&inode->i_lock); - goto out_flush_warn; - } - } - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!dquots[cnt]) -+ if (!dquot[cnt]) - continue; - if (reserve) -- dquot_resv_space(dquots[cnt], number); -+ dquot_resv_space(dquot[cnt], number); - else -- dquot_incr_space(dquots[cnt], number); -+ dquot_incr_space(dquot[cnt], number); - } - inode_incr_space(inode, number, reserve); - spin_unlock(&dq_data_lock); -+ spin_unlock(&inode->i_lock); - - if (reserve) - goto out_flush_warn; - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (dquots[cnt]) -- mark_dquot_dirty(dquots[cnt]); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); - out_flush_warn: -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- flush_warnings(warn); -+ flush_warnings(warn); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - out: - return ret; - } -@@ -1508,7 +1517,8 @@ int dquot_alloc_inode(const struct inode - { - int cnt, ret = NO_QUOTA; - struct dquot_warn warn[MAXQUOTAS]; - struct dquot * const *dquots = inode->i_dquot; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - /* First test before acquiring mutex - solves deadlocks when we - * re-enter the quota code and are already holding the mutex */ -@@ -1515,35 +1525,41 @@ int dquot_alloc_inode(const struct inode - return QUOTA_OK; - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - warn[cnt].w_type = QUOTA_NL_NOWARN; -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ -+ spin_lock(&((struct inode *)inode)->i_lock); - if (IS_NOQUOTA(inode)) { -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&((struct inode *)inode)->i_lock); - return QUOTA_OK; - } - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!dquots[cnt]) -+ dquot[cnt] = dquots[cnt]; -+ if (!dquot[cnt]) - continue; -- if (check_idq(dquots[cnt], number, &warn[cnt]) -+ atomic_inc(&dquot[cnt]->dq_count); -+ if (check_idq(dquot[cnt], number, &warn[cnt]) - == NO_QUOTA) - goto warn_put_all; - } - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!dquots[cnt]) -+ if (!dquot[cnt]) - continue; -- dquot_incr_inodes(dquots[cnt], number); -+ dquot_incr_inodes(dquot[cnt], number); - } - ret = QUOTA_OK; - warn_put_all: - spin_unlock(&dq_data_lock); -+ spin_unlock(&((struct inode *)inode)->i_lock); -+ - if (ret == QUOTA_OK) - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (dquots[cnt]) -- mark_dquot_dirty(dquots[cnt]); -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- flush_warnings(warn); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); -+ flush_warnings(warn); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - return ret; - } - EXPORT_SYMBOL(dquot_alloc_inode); -@@ -1552,34 +1568,40 @@ int dquot_claim_space(struct inode *inod - { - int cnt; - int ret = QUOTA_OK; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - if (IS_NOQUOTA(inode)) { - inode_claim_rsv_space(inode, number); - goto out; - } - -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) { -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- inode_claim_rsv_space(inode, number); -+ __inode_claim_rsv_space(inode, number); -+ spin_unlock(&inode->i_lock); - goto out; - } - - spin_lock(&dq_data_lock); - /* Claim reserved quotas to allocated quotas */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (inode->i_dquot[cnt]) -- dquot_claim_reserved_space(inode->i_dquot[cnt], -- number); -+ dquot[cnt] = inode->i_dquot[cnt]; -+ if (dquot[cnt]) { -+ atomic_inc(&dquot[cnt]->dq_count); -+ dquot_claim_reserved_space(dquot[cnt], number); -+ } - } - /* Update inode bytes */ -- inode_claim_rsv_space(inode, number); -+ __inode_claim_rsv_space(inode, number); - spin_unlock(&dq_data_lock); -+ spin_unlock(&inode->i_lock); -+ - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (inode->i_dquot[cnt]) -- mark_dquot_dirty(inode->i_dquot[cnt]); -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - out: - return ret; - } -@@ -1593,7 +1615,8 @@ int __dquot_free_space(struct inode *ino - unsigned int cnt; - struct dquot_warn warn[MAXQUOTAS]; - struct dquot **dquots = inode->i_dquot; - int reserve = flags & DQUOT_SPACE_RESERVE; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - /* First test before acquiring mutex - solves deadlocks when we - * re-enter the quota code and are already holding the mutex */ -@@ -1602,39 +1625,42 @@ out_sub: - return QUOTA_OK; - } - -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- /* Now recheck reliably when holding dqptr_sem */ -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) { -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - goto out_sub; - } - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - int wtype; - - warn[cnt].w_type = QUOTA_NL_NOWARN; -- if (!dquots[cnt]) -+ dquot[cnt] = dquots[cnt]; -+ if (!dquot[cnt]) - continue; -- wtype = info_bdq_free(dquots[cnt], number); -+ atomic_inc(&dquot[cnt]->dq_count); -+ wtype = info_bdq_free(dquot[cnt], number); - if (wtype != QUOTA_NL_NOWARN) -- prepare_warning(&warn[cnt], dquots[cnt], wtype); -+ prepare_warning(&warn[cnt], dquot[cnt], wtype); - if (reserve) -- dquot_free_reserved_space(dquots[cnt], number); -+ dquot_free_reserved_space(dquot[cnt], number); - else -- dquot_decr_space(dquots[cnt], number); -+ dquot_decr_space(dquot[cnt], number); - } - inode_decr_space(inode, number, reserve); - spin_unlock(&dq_data_lock); -+ spin_unlock(&inode->i_lock); - - if (reserve) -- goto out_unlock; -+ goto out; - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (dquots[cnt]) -- mark_dquot_dirty(dquots[cnt]); --out_unlock: -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- flush_warnings(warn); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); -+out: -+ flush_warnings(warn); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - return QUOTA_OK; - } - -@@ -1656,39 +1682,44 @@ int dquot_free_inode(const struct inode - { - unsigned int cnt; - struct dquot_warn warn[MAXQUOTAS]; - struct dquot * const *dquots = inode->i_dquot; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - /* First test before acquiring mutex - solves deadlocks when we - * re-enter the quota code and are already holding the mutex */ - if (IS_NOQUOTA(inode)) - return QUOTA_OK; - -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- /* Now recheck reliably when holding dqptr_sem */ -+ spin_lock(&((struct inode *)inode)->i_lock); - if (IS_NOQUOTA(inode)) { -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&((struct inode *)inode)->i_lock); - return QUOTA_OK; - } - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - int wtype; - - warn[cnt].w_type = QUOTA_NL_NOWARN; -- if (!dquots[cnt]) -+ dquot[cnt] = dquots[cnt]; -+ if (!dquot[cnt]) - continue; -- wtype = info_idq_free(dquots[cnt], number); -- if (wtype != QUOTA_NL_NOWARN) -- prepare_warning(&warn[cnt], dquots[cnt], wtype); -- dquot_decr_inodes(dquots[cnt], number); -+ atomic_inc(&dquot[cnt]->dq_count); -+ wtype = info_idq_free(dquot[cnt], number); -+ if (wtype != QUOTA_NL_NOWARN) -+ prepare_warning(&warn[cnt], dquot[cnt], wtype); -+ dquot_decr_inodes(dquot[cnt], number); - - } - spin_unlock(&dq_data_lock); -+ spin_unlock(&((struct inode *)inode)->i_lock); -+ - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (dquots[cnt]) -- mark_dquot_dirty(dquots[cnt]); -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- flush_warnings(warn); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); -+ flush_warnings(warn); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - return QUOTA_OK; - } - EXPORT_SYMBOL(dquot_free_inode); -@@ -1721,14 +1752,13 @@ int dquot_transfer(struct inode *inode, - transfer_to[GRPQUOTA] = dqget(inode->i_sb, iattr->ia_gid, - GRPQUOTA); - -- down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -- /* Now recheck reliably when holding dqptr_sem */ -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ -- up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - goto put_all; - } - spin_lock(&dq_data_lock); -- cur_space = inode_get_bytes(inode); -+ cur_space = __inode_get_bytes(inode); - rsv_space = inode_get_rsv_space(inode); - space = cur_space + rsv_space; - /* Build the transfer_from list and check the limits */ -@@ -1771,7 +1801,7 @@ int dquot_transfer(struct inode *inode, - inode->i_dquot[cnt] = transfer_to[cnt]; - } - spin_unlock(&dq_data_lock); -- up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -@@ -1795,7 +1825,7 @@ put_all: - return ret; - over_quota: - spin_unlock(&dq_data_lock); -- up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - /* Clear dquot pointers we don't want to dqput() */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - transfer_from[cnt] = NULL; -@@ -2047,13 +2077,13 @@ static int vfs_load_quota_inode(struct i - /* We don't want quota and atime on quota files (deadlocks - * possible) Also nobody should write to the file - we use - * special IO operations which ignore the immutable bit. */ -- down_write(&dqopt->dqptr_sem); - mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); -+ spin_lock(&inode->i_lock); - oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | - S_NOQUOTA); - inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; -+ spin_unlock(&inode->i_lock); - mutex_unlock(&inode->i_mutex); -- up_write(&dqopt->dqptr_sem); - sb->dq_op->drop(inode); - } - -@@ -2090,14 +2120,14 @@ out_file_init: - iput(inode); - out_lock: - if (oldflags != -1) { -- down_write(&dqopt->dqptr_sem); - mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); -+ spin_lock(&inode->i_lock); - /* Set the flags back (in the case of accidental quotaon() - * on a wrong file we don't want to mess up the flags) */ - inode->i_flags &= ~(S_NOATIME | S_NOQUOTA | S_IMMUTABLE); - inode->i_flags |= oldflags; -+ spin_unlock(&inode->i_lock); - mutex_unlock(&inode->i_mutex); -- up_write(&dqopt->dqptr_sem); - } - mutex_unlock(&dqopt->dqonoff_mutex); - out_fmt: -Index: linux-2.6.32-358.0.1.el6/fs/quota/quota.c -=================================================================== ---- linux-2.6.32-358.0.1.el6.orig/fs/quota/quota.c -+++ linux-2.6.32-358.0.1.el6/fs/quota/quota.c -@@ -257,13 +257,13 @@ static int do_quotactl(struct super_bloc - case Q_GETFMT: { - __u32 fmt; - -- down_read(&sb_dqopt(sb)->dqptr_sem); -+ mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); - if (!sb_has_quota_active(sb, type)) { -- up_read(&sb_dqopt(sb)->dqptr_sem); -+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); - return -ESRCH; - } - fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id; -- up_read(&sb_dqopt(sb)->dqptr_sem); -+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); - if (copy_to_user(addr, &fmt, sizeof(fmt))) - return -EFAULT; - return 0; -Index: linux-2.6.32-358.0.1.el6/fs/stat.c -=================================================================== ---- linux-2.6.32-358.0.1.el6.orig/fs/stat.c -+++ linux-2.6.32-358.0.1.el6/fs/stat.c -@@ -422,9 +422,8 @@ void inode_add_bytes(struct inode *inode - - EXPORT_SYMBOL(inode_add_bytes); - --void inode_sub_bytes(struct inode *inode, loff_t bytes) -+void __inode_sub_bytes(struct inode *inode, loff_t bytes) - { -- spin_lock(&inode->i_lock); - inode->i_blocks -= bytes >> 9; - bytes &= 511; - if (inode->i_bytes < bytes) { -@@ -432,17 +431,28 @@ void inode_sub_bytes(struct inode *inode - inode->i_bytes += 512; - } - inode->i_bytes -= bytes; -+} -+ -+void inode_sub_bytes(struct inode *inode, loff_t bytes) -+{ -+ spin_lock(&inode->i_lock); -+ __inode_sub_bytes(inode, bytes); - spin_unlock(&inode->i_lock); - } - - EXPORT_SYMBOL(inode_sub_bytes); - -+loff_t __inode_get_bytes(struct inode *inode) -+{ -+ return (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; -+} -+ - loff_t inode_get_bytes(struct inode *inode) - { - loff_t ret; - - spin_lock(&inode->i_lock); -- ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; -+ ret = __inode_get_bytes(inode); - spin_unlock(&inode->i_lock); - return ret; - } -Index: linux-2.6.32-358.0.1.el6/fs/super.c -=================================================================== ---- linux-2.6.32-358.0.1.el6.orig/fs/super.c -+++ linux-2.6.32-358.0.1.el6/fs/super.c -@@ -146,7 +146,6 @@ static struct super_block *alloc_super(s - mutex_init(&s->s_vfs_rename_mutex); - mutex_init(&s->s_dquot.dqio_mutex); - mutex_init(&s->s_dquot.dqonoff_mutex); -- init_rwsem(&s->s_dquot.dqptr_sem); - init_waitqueue_head(&s->s_wait_unfrozen); - s->s_maxbytes = MAX_NON_LFS; - s->dq_op = sb_dquot_ops; -Index: linux-2.6.32-358.0.1.el6/include/linux/fs.h -=================================================================== ---- linux-2.6.32-358.0.1.el6.orig/include/linux/fs.h -+++ linux-2.6.32-358.0.1.el6/include/linux/fs.h -@@ -2567,7 +2567,9 @@ extern void generic_fillattr(struct inod - extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); - void __inode_add_bytes(struct inode *inode, loff_t bytes); - void inode_add_bytes(struct inode *inode, loff_t bytes); -+void __inode_sub_bytes(struct inode *inode, loff_t bytes); - void inode_sub_bytes(struct inode *inode, loff_t bytes); -+loff_t __inode_get_bytes(struct inode *inode); - loff_t inode_get_bytes(struct inode *inode); - void inode_set_bytes(struct inode *inode, loff_t bytes); - diff --git a/lustre/kernel_patches/patches/quota-replace-dqptr-sem-sles11.patch b/lustre/kernel_patches/patches/quota-replace-dqptr-sem-sles11.patch deleted file mode 100644 index be8ea4c..0000000 --- a/lustre/kernel_patches/patches/quota-replace-dqptr-sem-sles11.patch +++ /dev/null @@ -1,663 +0,0 @@ -diff -urp linux-2.6.32-53.7.orig/fs/quota/dquot.c linux-2.6.32.46-0/fs/quota/dquot.c ---- linux-2.6.32-53.7.orig/fs/quota/dquot.c 2013-04-26 11:56:35.000000000 -0400 -+++ linux-2.6.32-53.7/fs/quota/dquot.c 2013-04-26 12:00:44.000000000 -0400 -@@ -89,22 +89,17 @@ - /* - * There are three quota SMP locks. dq_list_lock protects all lists with quotas - * and quota formats, dqstats structure containing statistics about the lists -- * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures and -- * also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes. -- * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly -- * in inode_add_bytes() and inode_sub_bytes(). dq_state_lock protects -- * modifications of quota state (on quotaon and quotaoff) and readers who care -- * about latest values take it as well. -+ * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures. -+ * dq_state_lock protects modifications of quota state (on quotaon and quotaoff) -+ * and readers who care about latest values take it as well. - * -- * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock, -+ * The spinlock ordering is hence: i_lock > dq_data_lock > dq_list_lock, - * dq_list_lock > dq_state_lock - * - * Note that some things (eg. sb pointer, type, id) doesn't change during - * the life of the dquot structure and so needn't to be protected by a lock - * -- * Any operation working on dquots via inode pointers must hold dqptr_sem. If -- * operation is just reading pointers from inode (or not using them at all) the -- * read lock is enough. If pointers are altered function must hold write lock -+ * Any operation working on dquots via inode pointers must hold i_lock. - * (these locking rules also apply for S_NOQUOTA flag in the inode - note that - * for altering the flag i_mutex is also needed). - * -@@ -118,15 +113,8 @@ - * spinlock to internal buffers before writing. - * - * Lock ordering (including related VFS locks) is the following: -- * i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > -- * dqio_mutex -- * The lock ordering of dqptr_sem imposed by quota code is only dqonoff_sem > -- * dqptr_sem. But filesystem has to count with the fact that functions such as -- * dquot_alloc_space() acquire dqptr_sem and they usually have to be called -- * from inside a transaction to keep filesystem consistency after a crash. Also -- * filesystems usually want to do some IO on dquot from ->mark_dirty which is -- * called with dqptr_sem held. -- * i_mutex on quota files is special (it's below dqio_mutex) -+ * i_mutex > dqonoff_sem > journal_lock > dquot->dq_lock > dqio_mutex -+ * i_mutex on quota files is special (it's below dqio_mutex) - */ - - static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock); -@@ -867,7 +855,6 @@ static inline int dqput_blocks(struct dq - /* - * Remove references to dquots from inode and add dquot to list for freeing - * if we have the last referece to dquot -- * We can't race with anybody because we hold dqptr_sem for writing... - */ - static int remove_inode_dquot_ref(struct inode *inode, int type, - struct list_head *tofree_head) -@@ -925,10 +912,12 @@ static void remove_dquot_ref(struct supe - * We have to scan also I_NEW inodes because they can already - * have quota pointer initialized. Luckily, we need to touch - * only quota pointers and these have separate locking -- * (dqptr_sem). -+ * (i_lock). - */ -+ spin_lock(&inode->i_lock); - if (!IS_NOQUOTA(inode)) - remove_inode_dquot_ref(inode, type, tofree_head); -+ spin_unlock(&inode->i_lock); - } - spin_unlock(&inode_lock); - } -@@ -939,9 +928,7 @@ static void drop_dquot_ref(struct super_ - LIST_HEAD(tofree_head); - - if (sb->dq_op) { -- down_write(&sb_dqopt(sb)->dqptr_sem); - remove_dquot_ref(sb, type, &tofree_head); -- up_write(&sb_dqopt(sb)->dqptr_sem); - put_dquot_list(&tofree_head); - } - } -@@ -1303,8 +1290,6 @@ static int info_bdq_free(struct dquot *d - - /* - * Initialize quota pointers in inode -- * We do things in a bit complicated way but by that we avoid calling -- * dqget() and thus filesystem callbacks under dqptr_sem. - */ - int dquot_initialize(struct inode *inode, int type) - { -@@ -1334,8 +1319,7 @@ int dquot_initialize(struct inode *inode - got[cnt] = dqget(sb, id, cnt); - } - -- down_write(&sb_dqopt(sb)->dqptr_sem); -- /* Having dqptr_sem we know NOQUOTA flags can't be altered... */ -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) - goto out_err; - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -@@ -1352,12 +1336,16 @@ int dquot_initialize(struct inode *inode - * did a write before quota was turned on - */ - rsv = inode_get_rsv_space(inode); -- if (unlikely(rsv)) -+ if (unlikely(rsv)) { -+ spin_lock(&dq_data_lock); - dquot_resv_space(inode->i_dquot[cnt], rsv); -+ spin_unlock(&dq_data_lock); -+ } - } - } - out_err: -- up_write(&sb_dqopt(sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); -+ - /* Drop unused references */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - dqput(got[cnt]); -@@ -1373,12 +1361,12 @@ int dquot_drop(struct inode *inode) - int cnt; - struct dquot *put[MAXQUOTAS]; - -- down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_lock(&inode->i_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - put[cnt] = inode->i_dquot[cnt]; - inode->i_dquot[cnt] = NULL; - } -- up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - dqput(put[cnt]); -@@ -1421,27 +1409,42 @@ static qsize_t *inode_reserved_space(str - return inode->i_sb->dq_op->get_reserved_space(inode); - } - -+static inline void __inode_add_rsv_space(struct inode *inode, qsize_t number) -+{ -+ *inode_reserved_space(inode) += number; -+} -+ - void inode_add_rsv_space(struct inode *inode, qsize_t number) - { - spin_lock(&inode->i_lock); -- *inode_reserved_space(inode) += number; -+ __inode_add_rsv_space(inode, number); - spin_unlock(&inode->i_lock); - } - EXPORT_SYMBOL(inode_add_rsv_space); - --void inode_claim_rsv_space(struct inode *inode, qsize_t number) -+static inline void __inode_claim_rsv_space(struct inode *inode, qsize_t number) - { -- spin_lock(&inode->i_lock); - *inode_reserved_space(inode) -= number; - __inode_add_bytes(inode, number); -+} -+ -+void inode_claim_rsv_space(struct inode *inode, qsize_t number) -+{ -+ spin_lock(&inode->i_lock); -+ __inode_claim_rsv_space(inode, number); - spin_unlock(&inode->i_lock); - } - EXPORT_SYMBOL(inode_claim_rsv_space); - -+static inline void __inode_sub_rsv_space(struct inode *inode, qsize_t number) -+{ -+ *inode_reserved_space(inode) -= number; -+} -+ - void inode_sub_rsv_space(struct inode *inode, qsize_t number) - { - spin_lock(&inode->i_lock); -- *inode_reserved_space(inode) -= number; -+ __inode_sub_rsv_space(inode, number); - spin_unlock(&inode->i_lock); - } - EXPORT_SYMBOL(inode_sub_rsv_space); -@@ -1452,9 +1455,8 @@ static qsize_t inode_get_rsv_space(struc - - if (!inode->i_sb->dq_op->get_reserved_space) - return 0; -- spin_lock(&inode->i_lock); -+ - ret = *inode_reserved_space(inode); -- spin_unlock(&inode->i_lock); - return ret; - } - -@@ -1462,17 +1464,17 @@ static void inode_incr_space(struct inod - int reserve) - { - if (reserve) -- inode_add_rsv_space(inode, number); -+ __inode_add_rsv_space(inode, number); - else -- inode_add_bytes(inode, number); -+ __inode_add_bytes(inode, number); - } - - static void inode_decr_space(struct inode *inode, qsize_t number, int reserve) - { - if (reserve) -- inode_sub_rsv_space(inode, number); -+ __inode_sub_rsv_space(inode, number); - else -- inode_sub_bytes(inode, number); -+ __inode_sub_bytes(inode, number); - } - - /* -@@ -1492,6 +1494,7 @@ int __dquot_alloc_space(struct inode *in - { - int cnt, ret = QUOTA_OK; - char warntype[MAXQUOTAS]; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - /* - * First test before acquiring mutex - solves deadlocks when we -@@ -1502,10 +1505,11 @@ int __dquot_alloc_space(struct inode *in - goto out; - } - -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) { - inode_incr_space(inode, number, reserve); -- goto out_unlock; -+ spin_unlock(&inode->i_lock); -+ goto out; - } - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -@@ -1523,36 +1529,40 @@ int __dquot_alloc_space(struct inode *int inode *in - - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!inode->i_dquot[cnt]) -+ dquot[cnt] = inode->i_dquot[cnt]; -+ if (!dquot[cnt]) - continue; -- if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt) -- == NO_QUOTA) { -+ atomic_inc(&dquot[cnt]->dq_count); -+ if (check_bdq(dquot[cnt], number, warn, warntype + cnt) == -+ NO_QUOTA) { - ret = NO_QUOTA; - spin_unlock(&dq_data_lock); -+ spin_unlock(&inode->i_lock); - goto out_flush_warn; - } - } - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!inode->i_dquot[cnt]) -+ if (!dquot[cnt]) - continue; - if (reserve) -- dquot_resv_space(inode->i_dquot[cnt], number); -+ dquot_resv_space(dquot[cnt], number); - else -- dquot_incr_space(inode->i_dquot[cnt], number); -+ dquot_incr_space(dquot[cnt], number); - } - inode_incr_space(inode, number, reserve); - spin_unlock(&dq_data_lock); -+ spin_unlock(&inode->i_lock); - - if (reserve) - goto out_flush_warn; - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (inode->i_dquot[cnt]) -- mark_dquot_dirty(inode->i_dquot[cnt]); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); - out_flush_warn: -- flush_warnings(inode->i_dquot, warntype); --out_unlock: -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ flush_warnings(dquot, warntype); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - out: - return ret; - } -@@ -1566,6 +1573,7 @@ int dquot_alloc_inode(const struct inode - { - int cnt, ret = NO_QUOTA; - char warntype[MAXQUOTAS]; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - /* First test before acquiring mutex - solves deadlocks when we - * re-enter the quota code and are already holding the mutex */ -@@ -1573,35 +1581,41 @@ int dquot_alloc_inode(const struct inode - return QUOTA_OK; - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - warntype[cnt] = QUOTA_NL_NOWARN; -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ -+ spin_lock(&((struct inode *)inode)->i_lock); - if (IS_NOQUOTA(inode)) { -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&((struct inode *)inode)->i_lock); - return QUOTA_OK; - } - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!inode->i_dquot[cnt]) -+ dquot[cnt] = inode->i_dquot[cnt]; -+ if (!dquot[cnt]) - continue; -- if (check_idq(inode->i_dquot[cnt], number, warntype+cnt) -+ atomic_inc(&dquot[cnt]->dq_count); -+ if (check_idq(dquot[cnt], number, warntype+cnt) - == NO_QUOTA) - goto warn_put_all; - } - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!inode->i_dquot[cnt]) -+ if (!dquot[cnt]) - continue; -- dquot_incr_inodes(inode->i_dquot[cnt], number); -+ dquot_incr_inodes(dquot[cnt], number); - } - ret = QUOTA_OK; - warn_put_all: - spin_unlock(&dq_data_lock); -+ spin_unlock(&((struct inode *)inode)->i_lock); -+ - if (ret == QUOTA_OK) - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (inode->i_dquot[cnt]) -- mark_dquot_dirty(inode->i_dquot[cnt]); -- flush_warnings(inode->i_dquot, warntype); -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); -+ flush_warnings(dquot, warntype); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - return ret; - } - EXPORT_SYMBOL(dquot_alloc_inode); -@@ -1610,34 +1624,40 @@ int dquot_claim_space(struct inode *inod - { - int cnt; - int ret = QUOTA_OK; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - if (IS_NOQUOTA(inode)) { - inode_claim_rsv_space(inode, number); - goto out; - } - -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) { -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- inode_claim_rsv_space(inode, number); -+ __inode_claim_rsv_space(inode, number); -+ spin_unlock(&inode->i_lock); - goto out; - } - - spin_lock(&dq_data_lock); - /* Claim reserved quotas to allocated quotas */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (inode->i_dquot[cnt]) -- dquot_claim_reserved_space(inode->i_dquot[cnt], -- number); -+ dquot[cnt] = inode->i_dquot[cnt]; -+ if (dquot[cnt]) { -+ atomic_inc(&dquot[cnt]->dq_count); -+ dquot_claim_reserved_space(dquot[cnt], number); -+ } - } - /* Update inode bytes */ -- inode_claim_rsv_space(inode, number); -+ __inode_claim_rsv_space(inode, number); - spin_unlock(&dq_data_lock); -+ spin_unlock(&inode->i_lock); -+ - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (inode->i_dquot[cnt]) -- mark_dquot_dirty(inode->i_dquot[cnt]); -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - out: - return ret; - } -@@ -1650,6 +1670,7 @@ int __dquot_free_space(struct inode *ino - { - unsigned int cnt; - char warntype[MAXQUOTAS]; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - /* First test before acquiring mutex - solves deadlocks when we - * re-enter the quota code and are already holding the mutex */ -@@ -1659,34 +1680,37 @@ out_sub: - return QUOTA_OK; - } - -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- /* Now recheck reliably when holding dqptr_sem */ -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) { -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - goto out_sub; - } - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!inode->i_dquot[cnt]) -+ dquot[cnt] = inode->i_dquot[cnt]; -+ if (!dquot[cnt]) - continue; -- warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number); -+ atomic_inc(&dquot[cnt]->dq_count); -+ warntype[cnt] = info_bdq_free(dquot[cnt], number); - if (reserve) -- dquot_free_reserved_space(inode->i_dquot[cnt], number); -+ dquot_free_reserved_space(dquot[cnt], number); - else -- dquot_decr_space(inode->i_dquot[cnt], number); -+ dquot_decr_space(dquot[cnt], number); - } - inode_decr_space(inode, number, reserve); - spin_unlock(&dq_data_lock); -+ spin_unlock(&inode->i_lock); - - if (reserve) -- goto out_unlock; -+ goto out; - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (inode->i_dquot[cnt]) -- mark_dquot_dirty(inode->i_dquot[cnt]); --out_unlock: -- flush_warnings(inode->i_dquot, warntype); -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); -+out: -+ flush_warnings(dquot, warntype); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - return QUOTA_OK; - } - -@@ -1713,32 +1737,37 @@ int dquot_free_inode(const struct inode - { - unsigned int cnt; - char warntype[MAXQUOTAS]; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - /* First test before acquiring mutex - solves deadlocks when we - * re-enter the quota code and are already holding the mutex */ - if (IS_NOQUOTA(inode)) - return QUOTA_OK; - -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- /* Now recheck reliably when holding dqptr_sem */ -+ spin_lock(&((struct inode *)inode)->i_lock); - if (IS_NOQUOTA(inode)) { -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&((struct inode *)inode)->i_lock); - return QUOTA_OK; - } - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!inode->i_dquot[cnt]) -+ dquot[cnt] = inode->i_dquot[cnt]; -+ if (!dquot[cnt]) - continue; -- warntype[cnt] = info_idq_free(inode->i_dquot[cnt], number); -- dquot_decr_inodes(inode->i_dquot[cnt], number); -+ atomic_inc(&dquot[cnt]->dq_count); -+ warntype[cnt] = info_idq_free(dquot[cnt], number); -+ dquot_decr_inodes(dquot[cnt], number); - } - spin_unlock(&dq_data_lock); -+ spin_unlock(&((struct inode *)inode)->i_lock); -+ - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (inode->i_dquot[cnt]) -- mark_dquot_dirty(inode->i_dquot[cnt]); -- flush_warnings(inode->i_dquot, warntype); -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); -+ flush_warnings(dquot, warntype); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - return QUOTA_OK; - } - EXPORT_SYMBOL(dquot_free_inode); -@@ -1778,14 +1807,13 @@ int dquot_transfer(struct inode *inode, - transfer_to[GRPQUOTA] = dqget(inode->i_sb, iattr->ia_gid, - GRPQUOTA); - -- down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -- /* Now recheck reliably when holding dqptr_sem */ -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ -- up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - goto put_all; - } - spin_lock(&dq_data_lock); -- cur_space = inode_get_bytes(inode); -+ cur_space = __inode_get_bytes(inode); - rsv_space = inode_get_rsv_space(inode); - space = cur_space + rsv_space; - /* Build the transfer_from list and check the limits */ -@@ -1828,7 +1856,7 @@ int dquot_transfer(struct inode *inode, - inode->i_dquot[cnt] = transfer_to[cnt]; - } - spin_unlock(&dq_data_lock); -- up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -@@ -1852,7 +1880,7 @@ put_all: - return ret; - over_quota: - spin_unlock(&dq_data_lock); -- up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - /* Clear dquot pointers we don't want to dqput() */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - transfer_from[cnt] = NULL; -@@ -2104,13 +2132,13 @@ static int vfs_load_quota_inode(struct i - /* We don't want quota and atime on quota files (deadlocks - * possible) Also nobody should write to the file - we use - * special IO operations which ignore the immutable bit. */ -- down_write(&dqopt->dqptr_sem); - mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); -+ spin_lock(&inode->i_lock); - oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | - S_NOQUOTA); - inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; -+ spin_unlock(&inode->i_lock); - mutex_unlock(&inode->i_mutex); -- up_write(&dqopt->dqptr_sem); - sb->dq_op->drop(inode); - } - -@@ -2147,14 +2175,14 @@ out_file_init: - iput(inode); - out_lock: - if (oldflags != -1) { -- down_write(&dqopt->dqptr_sem); - mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); -+ spin_lock(&inode->i_lock); - /* Set the flags back (in the case of accidental quotaon() - * on a wrong file we don't want to mess up the flags) */ - inode->i_flags &= ~(S_NOATIME | S_NOQUOTA | S_IMMUTABLE); - inode->i_flags |= oldflags; -+ spin_unlock(&inode->i_lock); - mutex_unlock(&inode->i_mutex); -- up_write(&dqopt->dqptr_sem); - } - mutex_unlock(&dqopt->dqonoff_mutex); - out_fmt: -diff -urp linux-2.6.32-53.7.orig/fs/quota/quota.c linux-2.6.32.46-0/fs/quota/quota.c ---- linux-2.6.32-53.7.orig/fs/quota/quota.c 2009-12-02 22:51:21.000000000 -0500 -+++ linux-2.6.32-53.7/fs/quota/quota.c 2013-04-26 11:59:22.000000000 -0400 -@@ -255,13 +255,13 @@ static int do_quotactl(struct super_bloc - case Q_GETFMT: { - __u32 fmt; - -- down_read(&sb_dqopt(sb)->dqptr_sem); -+ mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); - if (!sb_has_quota_active(sb, type)) { -- up_read(&sb_dqopt(sb)->dqptr_sem); -+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); - return -ESRCH; - } - fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id; -- up_read(&sb_dqopt(sb)->dqptr_sem); -+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); - if (copy_to_user(addr, &fmt, sizeof(fmt))) - return -EFAULT; - return 0; -diff -urp linux-2.6.32-53.7.orig/fs/stat.c linux-2.6.32.46-0/fs/stat.c ---- linux-2.6.32-53.7.orig/fs/stat.c 2013-04-26 11:56:28.000000000 -0400 -+++ linux-2.6.32-53.7/fs/stat.c 2013-04-26 11:59:22.000000000 -0400 -@@ -422,9 +422,8 @@ void inode_add_bytes(struct inode *inode - - EXPORT_SYMBOL(inode_add_bytes); - --void inode_sub_bytes(struct inode *inode, loff_t bytes) -+void __inode_sub_bytes(struct inode *inode, loff_t bytes) - { -- spin_lock(&inode->i_lock); - inode->i_blocks -= bytes >> 9; - bytes &= 511; - if (inode->i_bytes < bytes) { -@@ -432,17 +431,28 @@ void inode_sub_bytes(struct inode *inode - inode->i_bytes += 512; - } - inode->i_bytes -= bytes; -+} -+ -+void inode_sub_bytes(struct inode *inode, loff_t bytes) -+{ -+ spin_lock(&inode->i_lock); -+ __inode_sub_bytes(inode, bytes); - spin_unlock(&inode->i_lock); - } - - EXPORT_SYMBOL(inode_sub_bytes); - -+loff_t __inode_get_bytes(struct inode *inode) -+{ -+ return (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; -+} -+ - loff_t inode_get_bytes(struct inode *inode) - { - loff_t ret; - - spin_lock(&inode->i_lock); -- ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; -+ ret = __inode_get_bytes(inode); - spin_unlock(&inode->i_lock); - return ret; - } -diff -urp linux-2.6.32-53.7.orig/fs/super.c linux-2.6.32.46-0/fs/super.c ---- linux-2.6.32-53.7.orig/fs/super.c 2013-04-26 11:56:52.000000000 -0400 -+++ linux-2.6.32-53.7/fs/super.c 2013-04-26 11:59:22.000000000 -0400 -@@ -98,7 +98,6 @@ static struct super_block *alloc_super(s - mutex_init(&s->s_vfs_rename_mutex); - mutex_init(&s->s_dquot.dqio_mutex); - mutex_init(&s->s_dquot.dqonoff_mutex); -- init_rwsem(&s->s_dquot.dqptr_sem); - init_waitqueue_head(&s->s_wait_unfrozen); - s->s_maxbytes = MAX_NON_LFS; - s->dq_op = sb_dquot_ops; -diff -urp linux-2.6.32-53.7.orig/include/linux/fs.h linux-2.6.32.46-0/include/linux/fs.h ---- linux-2.6.32-53.7.orig/include/linux/fs.h 2013-04-26 11:56:52.000000000 -0400 -+++ linux-2.6.32-53.7/include/linux/fs.h 2013-04-26 11:59:22.000000000 -0400 -@@ -2356,7 +2356,9 @@ extern void generic_fillattr(struct inod - extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); - void __inode_add_bytes(struct inode *inode, loff_t bytes); - void inode_add_bytes(struct inode *inode, loff_t bytes); -+void __inode_sub_bytes(struct inode *inode, loff_t bytes); - void inode_sub_bytes(struct inode *inode, loff_t bytes); -+loff_t __inode_get_bytes(struct inode *inode); - loff_t inode_get_bytes(struct inode *inode); - void inode_set_bytes(struct inode *inode, loff_t bytes); - diff --git a/lustre/kernel_patches/patches/quota-replace-dqptr-sem.patch b/lustre/kernel_patches/patches/quota-replace-dqptr-sem.patch deleted file mode 100644 index 079d103..0000000 --- a/lustre/kernel_patches/patches/quota-replace-dqptr-sem.patch +++ /dev/null @@ -1,683 +0,0 @@ -Remove dqptr_sem (but kept in struct quota_info to keep kernel ABI -unchanged), and the functionality of this lock is implemented by -other locks: -* i_dquot is protected by i_lock, however only this pointer, the - content of this struct is by dq_data_lock. -* Q_GETFMT is now protected with dqonoff_mutex instead of dqptr_sem. - - fs/quota/dquot.c | 243 +++++++++++++++++++++++++++++------------------------ - fs/quota/quota.c | 6 - - fs/stat.c | 16 ++- - fs/super.c | 1 - include/linux/fs.h | 2 - 5 files changed, 154 insertions(+), 114 deletions(-) - -Index: linux-2.6.32-358.0.1.el6/fs/quota/dquot.c -=================================================================== ---- linux-2.6.32-358.0.1.el6.orig/fs/quota/dquot.c -+++ linux-2.6.32-358.0.1.el6/fs/quota/dquot.c -@@ -83,22 +83,17 @@ - /* - * There are three quota SMP locks. dq_list_lock protects all lists with quotas - * and quota formats, dqstats structure containing statistics about the lists -- * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures and -- * also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes. -- * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly -- * in inode_add_bytes() and inode_sub_bytes(). dq_state_lock protects -- * modifications of quota state (on quotaon and quotaoff) and readers who care -- * about latest values take it as well. -+ * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures. -+ * dq_state_lock protects modifications of quota state (on quotaon and quotaoff) -+ * and readers who care about latest values take it as well. - * -- * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock, -+ * The spinlock ordering is hence: i_lock > dq_data_lock > dq_list_lock, - * dq_list_lock > dq_state_lock - * - * Note that some things (eg. sb pointer, type, id) doesn't change during - * the life of the dquot structure and so needn't to be protected by a lock - * -- * Any operation working on dquots via inode pointers must hold dqptr_sem. If -- * operation is just reading pointers from inode (or not using them at all) the -- * read lock is enough. If pointers are altered function must hold write lock -+ * Any operation working on dquots via inode pointers must hold i_lock. - * (these locking rules also apply for S_NOQUOTA flag in the inode - note that - * for altering the flag i_mutex is also needed). - * -@@ -112,15 +107,8 @@ - * spinlock to internal buffers before writing. - * - * Lock ordering (including related VFS locks) is the following: -- * i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > -- * dqio_mutex -- * The lock ordering of dqptr_sem imposed by quota code is only dqonoff_sem > -- * dqptr_sem. But filesystem has to count with the fact that functions such as -- * dquot_alloc_space() acquire dqptr_sem and they usually have to be called -- * from inside a transaction to keep filesystem consistency after a crash. Also -- * filesystems usually want to do some IO on dquot from ->mark_dirty which is -- * called with dqptr_sem held. -- * i_mutex on quota files is special (it's below dqio_mutex) -+ * i_mutex > dqonoff_sem > journal_lock > dquot->dq_lock > dqio_mutex -+ * i_mutex on quota files is special (it's below dqio_mutex) - */ - - static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock); -@@ -868,7 +856,6 @@ static inline int dqput_blocks(struct dq - /* - * Remove references to dquots from inode and add dquot to list for freeing - * if we have the last referece to dquot -- * We can't race with anybody because we hold dqptr_sem for writing... - */ - static int remove_inode_dquot_ref(struct inode *inode, int type, - struct list_head *tofree_head) -@@ -926,10 +913,12 @@ static void remove_dquot_ref(struct supe - * We have to scan also I_NEW inodes because they can already - * have quota pointer initialized. Luckily, we need to touch - * only quota pointers and these have separate locking -- * (dqptr_sem). -+ * (i_lock). - */ -+ spin_lock(&inode->i_lock); - if (!IS_NOQUOTA(inode)) - remove_inode_dquot_ref(inode, type, tofree_head); -+ spin_unlock(&inode->i_lock); - } - spin_unlock(&inode_lock); - } -@@ -940,9 +929,7 @@ static void drop_dquot_ref(struct super_ - LIST_HEAD(tofree_head); - - if (sb->dq_op) { -- down_write(&sb_dqopt(sb)->dqptr_sem); - remove_dquot_ref(sb, type, &tofree_head); -- up_write(&sb_dqopt(sb)->dqptr_sem); - put_dquot_list(&tofree_head); - } - } -@@ -1239,8 +1226,6 @@ static int info_bdq_free(struct dquot *d - - /* - * Initialize quota pointers in inode -- * We do things in a bit complicated way but by that we avoid calling -- * dqget() and thus filesystem callbacks under dqptr_sem. - */ - int dquot_initialize(struct inode *inode, int type) - { -@@ -1270,8 +1255,7 @@ int dquot_initialize(struct inode *inode - got[cnt] = dqget(sb, id, cnt); - } - -- down_write(&sb_dqopt(sb)->dqptr_sem); -- /* Having dqptr_sem we know NOQUOTA flags can't be altered... */ -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) - goto out_err; - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -@@ -1288,12 +1272,16 @@ int dquot_initialize(struct inode *inode - * did a write before quota was turned on - */ - rsv = inode_get_rsv_space(inode); -- if (unlikely(rsv)) -+ if (unlikely(rsv)) { -+ spin_lock(&dq_data_lock); - dquot_resv_space(inode->i_dquot[cnt], rsv); -+ spin_unlock(&dq_data_lock); -+ } - } - } - out_err: -- up_write(&sb_dqopt(sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); -+ - /* Drop unused references */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - dqput(got[cnt]); -@@ -1309,12 +1297,12 @@ int dquot_drop(struct inode *inode) - int cnt; - struct dquot *put[MAXQUOTAS]; - -- down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_lock(&inode->i_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - put[cnt] = inode->i_dquot[cnt]; - inode->i_dquot[cnt] = NULL; - } -- up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - dqput(put[cnt]); -@@ -1357,27 +1345,42 @@ static qsize_t *inode_reserved_space(str - return inode->i_sb->dq_op->get_reserved_space(inode); - } - -+static inline void __inode_add_rsv_space(struct inode *inode, qsize_t number) -+{ -+ *inode_reserved_space(inode) += number; -+} -+ - void inode_add_rsv_space(struct inode *inode, qsize_t number) - { - spin_lock(&inode->i_lock); -- *inode_reserved_space(inode) += number; -+ __inode_add_rsv_space(inode, number); - spin_unlock(&inode->i_lock); - } - EXPORT_SYMBOL(inode_add_rsv_space); - --void inode_claim_rsv_space(struct inode *inode, qsize_t number) -+static inline void __inode_claim_rsv_space(struct inode *inode, qsize_t number) - { -- spin_lock(&inode->i_lock); - *inode_reserved_space(inode) -= number; - __inode_add_bytes(inode, number); -+} -+ -+void inode_claim_rsv_space(struct inode *inode, qsize_t number) -+{ -+ spin_lock(&inode->i_lock); -+ __inode_claim_rsv_space(inode, number); - spin_unlock(&inode->i_lock); - } - EXPORT_SYMBOL(inode_claim_rsv_space); - -+static inline void __inode_sub_rsv_space(struct inode *inode, qsize_t number) -+{ -+ *inode_reserved_space(inode) -= number; -+} -+ - void inode_sub_rsv_space(struct inode *inode, qsize_t number) - { - spin_lock(&inode->i_lock); -- *inode_reserved_space(inode) -= number; -+ __inode_sub_rsv_space(inode, number); - spin_unlock(&inode->i_lock); - } - EXPORT_SYMBOL(inode_sub_rsv_space); -@@ -1388,9 +1391,8 @@ static qsize_t inode_get_rsv_space(struc - - if (!inode->i_sb->dq_op->get_reserved_space) - return 0; -- spin_lock(&inode->i_lock); -+ - ret = *inode_reserved_space(inode); -- spin_unlock(&inode->i_lock); - return ret; - } - -@@ -1398,17 +1400,17 @@ static void inode_incr_space(struct inod - int reserve) - { - if (reserve) -- inode_add_rsv_space(inode, number); -+ __inode_add_rsv_space(inode, number); - else -- inode_add_bytes(inode, number); -+ __inode_add_bytes(inode, number); - } - - static void inode_decr_space(struct inode *inode, qsize_t number, int reserve) - { - if (reserve) -- inode_sub_rsv_space(inode, number); -+ __inode_sub_rsv_space(inode, number); - else -- inode_sub_bytes(inode, number); -+ __inode_sub_bytes(inode, number); - } - - /* -@@ -1430,6 +1432,7 @@ int __dquot_alloc_space(struct inode *in - int warn = flags & DQUOT_SPACE_WARN; - int reserve = flags & DQUOT_SPACE_RESERVE; - int nofail = flags & DQUOT_SPACE_NOFAIL; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - /* - * First test before acquiring mutex - solves deadlocks when we -@@ -1440,47 +1443,53 @@ int __dquot_alloc_space(struct inode *in - goto out; - } - -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) { - inode_incr_space(inode, number, reserve); -- goto out_unlock; -+ spin_unlock(&inode->i_lock); -+ goto out; - } - -- for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - warntype[cnt] = QUOTA_NL_NOWARN; -+ } - - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!inode->i_dquot[cnt]) -+ dquot[cnt] = inode->i_dquot[cnt]; -+ if (!dquot[cnt]) - continue; -- if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt) -+ atomic_inc(&dquot[cnt]->dq_count); -+ if (check_bdq(dquot[cnt], number, warn, warntype+cnt) - == NO_QUOTA && !nofail) { - ret = NO_QUOTA; - spin_unlock(&dq_data_lock); -+ spin_unlock(&inode->i_lock); - goto out_flush_warn; - } - } - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!inode->i_dquot[cnt]) -+ if (!dquot[cnt]) - continue; - if (reserve) -- dquot_resv_space(inode->i_dquot[cnt], number); -+ dquot_resv_space(dquot[cnt], number); - else -- dquot_incr_space(inode->i_dquot[cnt], number); -+ dquot_incr_space(dquot[cnt], number); - } - inode_incr_space(inode, number, reserve); - spin_unlock(&dq_data_lock); -+ spin_unlock(&inode->i_lock); - - if (reserve) - goto out_flush_warn; - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (inode->i_dquot[cnt]) -- mark_dquot_dirty(inode->i_dquot[cnt]); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); - out_flush_warn: -- flush_warnings(inode->i_dquot, warntype); --out_unlock: -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ flush_warnings(dquot, warntype); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - out: - return ret; - } -@@ -1508,6 +1517,7 @@ int dquot_alloc_inode(const struct inode - { - int cnt, ret = NO_QUOTA; - char warntype[MAXQUOTAS]; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - /* First test before acquiring mutex - solves deadlocks when we - * re-enter the quota code and are already holding the mutex */ -@@ -1515,35 +1525,41 @@ int dquot_alloc_inode(const struct inode - return QUOTA_OK; - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - warntype[cnt] = QUOTA_NL_NOWARN; -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ -+ spin_lock(&((struct inode *)inode)->i_lock); - if (IS_NOQUOTA(inode)) { -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&((struct inode *)inode)->i_lock); - return QUOTA_OK; - } - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!inode->i_dquot[cnt]) -+ dquot[cnt] = inode->i_dquot[cnt]; -+ if (!dquot[cnt]) - continue; -- if (check_idq(inode->i_dquot[cnt], number, warntype+cnt) -+ atomic_inc(&dquot[cnt]->dq_count); -+ if (check_idq(dquot[cnt], number, warntype+cnt) - == NO_QUOTA) - goto warn_put_all; - } - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!inode->i_dquot[cnt]) -+ if (!dquot[cnt]) - continue; -- dquot_incr_inodes(inode->i_dquot[cnt], number); -+ dquot_incr_inodes(dquot[cnt], number); - } - ret = QUOTA_OK; - warn_put_all: - spin_unlock(&dq_data_lock); -+ spin_unlock(&((struct inode *)inode)->i_lock); -+ - if (ret == QUOTA_OK) - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (inode->i_dquot[cnt]) -- mark_dquot_dirty(inode->i_dquot[cnt]); -- flush_warnings(inode->i_dquot, warntype); -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); -+ flush_warnings(dquot, warntype); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - return ret; - } - EXPORT_SYMBOL(dquot_alloc_inode); -@@ -1552,34 +1568,40 @@ int dquot_claim_space(struct inode *inod - { - int cnt; - int ret = QUOTA_OK; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - if (IS_NOQUOTA(inode)) { - inode_claim_rsv_space(inode, number); - goto out; - } - -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) { -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- inode_claim_rsv_space(inode, number); -+ __inode_claim_rsv_space(inode, number); -+ spin_unlock(&inode->i_lock); - goto out; - } - - spin_lock(&dq_data_lock); - /* Claim reserved quotas to allocated quotas */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (inode->i_dquot[cnt]) -- dquot_claim_reserved_space(inode->i_dquot[cnt], -- number); -+ dquot[cnt] = inode->i_dquot[cnt]; -+ if (dquot[cnt]) { -+ atomic_inc(&dquot[cnt]->dq_count); -+ dquot_claim_reserved_space(dquot[cnt], number); -+ } - } - /* Update inode bytes */ -- inode_claim_rsv_space(inode, number); -+ __inode_claim_rsv_space(inode, number); - spin_unlock(&dq_data_lock); -+ spin_unlock(&inode->i_lock); -+ - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (inode->i_dquot[cnt]) -- mark_dquot_dirty(inode->i_dquot[cnt]); -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - out: - return ret; - } -@@ -1593,6 +1615,7 @@ int __dquot_free_space(struct inode *ino - unsigned int cnt; - char warntype[MAXQUOTAS]; - int reserve = flags & DQUOT_SPACE_RESERVE; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - /* First test before acquiring mutex - solves deadlocks when we - * re-enter the quota code and are already holding the mutex */ -@@ -1602,34 +1625,37 @@ out_sub: - return QUOTA_OK; - } - -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- /* Now recheck reliably when holding dqptr_sem */ -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) { -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - goto out_sub; - } - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!inode->i_dquot[cnt]) -+ dquot[cnt] = inode->i_dquot[cnt]; -+ if (!dquot[cnt]) - continue; -- warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number); -+ atomic_inc(&dquot[cnt]->dq_count); -+ warntype[cnt] = info_bdq_free(dquot[cnt], number); - if (reserve) -- dquot_free_reserved_space(inode->i_dquot[cnt], number); -+ dquot_free_reserved_space(dquot[cnt], number); - else -- dquot_decr_space(inode->i_dquot[cnt], number); -+ dquot_decr_space(dquot[cnt], number); - } - inode_decr_space(inode, number, reserve); - spin_unlock(&dq_data_lock); -+ spin_unlock(&inode->i_lock); - - if (reserve) -- goto out_unlock; -+ goto out; - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (inode->i_dquot[cnt]) -- mark_dquot_dirty(inode->i_dquot[cnt]); --out_unlock: -- flush_warnings(inode->i_dquot, warntype); -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); -+out: -+ flush_warnings(dquot, warntype); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - return QUOTA_OK; - } - -@@ -1656,32 +1682,37 @@ int dquot_free_inode(const struct inode - { - unsigned int cnt; - char warntype[MAXQUOTAS]; -+ struct dquot *dquot[MAXQUOTAS] = { NULL }; - - /* First test before acquiring mutex - solves deadlocks when we - * re-enter the quota code and are already holding the mutex */ - if (IS_NOQUOTA(inode)) - return QUOTA_OK; - -- down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -- /* Now recheck reliably when holding dqptr_sem */ -+ spin_lock(&((struct inode *)inode)->i_lock); - if (IS_NOQUOTA(inode)) { -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&((struct inode *)inode)->i_lock); - return QUOTA_OK; - } - spin_lock(&dq_data_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -- if (!inode->i_dquot[cnt]) -+ dquot[cnt] = inode->i_dquot[cnt]; -+ if (!dquot[cnt]) - continue; -- warntype[cnt] = info_idq_free(inode->i_dquot[cnt], number); -- dquot_decr_inodes(inode->i_dquot[cnt], number); -+ atomic_inc(&dquot[cnt]->dq_count); -+ warntype[cnt] = info_idq_free(dquot[cnt], number); -+ dquot_decr_inodes(dquot[cnt], number); - } - spin_unlock(&dq_data_lock); -+ spin_unlock(&((struct inode *)inode)->i_lock); -+ - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) -- if (inode->i_dquot[cnt]) -- mark_dquot_dirty(inode->i_dquot[cnt]); -- flush_warnings(inode->i_dquot, warntype); -- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ if (dquot[cnt]) -+ mark_dquot_dirty(dquot[cnt]); -+ flush_warnings(dquot, warntype); -+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) -+ dqput(dquot[cnt]); - return QUOTA_OK; - } - EXPORT_SYMBOL(dquot_free_inode); -@@ -1721,14 +1752,13 @@ int dquot_transfer(struct inode *inode, - transfer_to[GRPQUOTA] = dqget(inode->i_sb, iattr->ia_gid, - GRPQUOTA); - -- down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -- /* Now recheck reliably when holding dqptr_sem */ -+ spin_lock(&inode->i_lock); - if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ -- up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - goto put_all; - } - spin_lock(&dq_data_lock); -- cur_space = inode_get_bytes(inode); -+ cur_space = __inode_get_bytes(inode); - rsv_space = inode_get_rsv_space(inode); - space = cur_space + rsv_space; - /* Build the transfer_from list and check the limits */ -@@ -1771,7 +1801,7 @@ int dquot_transfer(struct inode *inode, - inode->i_dquot[cnt] = transfer_to[cnt]; - } - spin_unlock(&dq_data_lock); -- up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - - /* Dirtify all the dquots - this can block when journalling */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { -@@ -1795,7 +1825,7 @@ put_all: - return ret; - over_quota: - spin_unlock(&dq_data_lock); -- up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); -+ spin_unlock(&inode->i_lock); - /* Clear dquot pointers we don't want to dqput() */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - transfer_from[cnt] = NULL; -@@ -2047,13 +2077,13 @@ static int vfs_load_quota_inode(struct i - /* We don't want quota and atime on quota files (deadlocks - * possible) Also nobody should write to the file - we use - * special IO operations which ignore the immutable bit. */ -- down_write(&dqopt->dqptr_sem); - mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); -+ spin_lock(&inode->i_lock); - oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | - S_NOQUOTA); - inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; -+ spin_unlock(&inode->i_lock); - mutex_unlock(&inode->i_mutex); -- up_write(&dqopt->dqptr_sem); - sb->dq_op->drop(inode); - } - -@@ -2090,14 +2120,14 @@ out_file_init: - iput(inode); - out_lock: - if (oldflags != -1) { -- down_write(&dqopt->dqptr_sem); - mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); -+ spin_lock(&inode->i_lock); - /* Set the flags back (in the case of accidental quotaon() - * on a wrong file we don't want to mess up the flags) */ - inode->i_flags &= ~(S_NOATIME | S_NOQUOTA | S_IMMUTABLE); - inode->i_flags |= oldflags; -+ spin_unlock(&inode->i_lock); - mutex_unlock(&inode->i_mutex); -- up_write(&dqopt->dqptr_sem); - } - mutex_unlock(&dqopt->dqonoff_mutex); - out_fmt: -Index: linux-2.6.32-358.0.1.el6/fs/quota/quota.c -=================================================================== ---- linux-2.6.32-358.0.1.el6.orig/fs/quota/quota.c -+++ linux-2.6.32-358.0.1.el6/fs/quota/quota.c -@@ -257,13 +257,13 @@ static int do_quotactl(struct super_bloc - case Q_GETFMT: { - __u32 fmt; - -- down_read(&sb_dqopt(sb)->dqptr_sem); -+ mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); - if (!sb_has_quota_active(sb, type)) { -- up_read(&sb_dqopt(sb)->dqptr_sem); -+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); - return -ESRCH; - } - fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id; -- up_read(&sb_dqopt(sb)->dqptr_sem); -+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); - if (copy_to_user(addr, &fmt, sizeof(fmt))) - return -EFAULT; - return 0; -Index: linux-2.6.32-358.0.1.el6/fs/stat.c -=================================================================== ---- linux-2.6.32-358.0.1.el6.orig/fs/stat.c -+++ linux-2.6.32-358.0.1.el6/fs/stat.c -@@ -422,9 +422,8 @@ void inode_add_bytes(struct inode *inode - - EXPORT_SYMBOL(inode_add_bytes); - --void inode_sub_bytes(struct inode *inode, loff_t bytes) -+void __inode_sub_bytes(struct inode *inode, loff_t bytes) - { -- spin_lock(&inode->i_lock); - inode->i_blocks -= bytes >> 9; - bytes &= 511; - if (inode->i_bytes < bytes) { -@@ -432,17 +431,28 @@ void inode_sub_bytes(struct inode *inode - inode->i_bytes += 512; - } - inode->i_bytes -= bytes; -+} -+ -+void inode_sub_bytes(struct inode *inode, loff_t bytes) -+{ -+ spin_lock(&inode->i_lock); -+ __inode_sub_bytes(inode, bytes); - spin_unlock(&inode->i_lock); - } - - EXPORT_SYMBOL(inode_sub_bytes); - -+loff_t __inode_get_bytes(struct inode *inode) -+{ -+ return (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; -+} -+ - loff_t inode_get_bytes(struct inode *inode) - { - loff_t ret; - - spin_lock(&inode->i_lock); -- ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; -+ ret = __inode_get_bytes(inode); - spin_unlock(&inode->i_lock); - return ret; - } -Index: linux-2.6.32-358.0.1.el6/fs/super.c -=================================================================== ---- linux-2.6.32-358.0.1.el6.orig/fs/super.c -+++ linux-2.6.32-358.0.1.el6/fs/super.c -@@ -146,7 +146,6 @@ static struct super_block *alloc_super(s - mutex_init(&s->s_vfs_rename_mutex); - mutex_init(&s->s_dquot.dqio_mutex); - mutex_init(&s->s_dquot.dqonoff_mutex); -- init_rwsem(&s->s_dquot.dqptr_sem); - init_waitqueue_head(&s->s_wait_unfrozen); - s->s_maxbytes = MAX_NON_LFS; - s->dq_op = sb_dquot_ops; -Index: linux-2.6.32-358.0.1.el6/include/linux/fs.h -=================================================================== ---- linux-2.6.32-358.0.1.el6.orig/include/linux/fs.h -+++ linux-2.6.32-358.0.1.el6/include/linux/fs.h -@@ -2567,7 +2567,9 @@ extern void generic_fillattr(struct inod - extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); - void __inode_add_bytes(struct inode *inode, loff_t bytes); - void inode_add_bytes(struct inode *inode, loff_t bytes); -+void __inode_sub_bytes(struct inode *inode, loff_t bytes); - void inode_sub_bytes(struct inode *inode, loff_t bytes); -+loff_t __inode_get_bytes(struct inode *inode); - loff_t inode_get_bytes(struct inode *inode); - void inode_set_bytes(struct inode *inode, loff_t bytes); - diff --git a/lustre/kernel_patches/patches/raid5-mmp-unplug-dev-rhel6.patch b/lustre/kernel_patches/patches/raid5-mmp-unplug-dev-rhel6.patch deleted file mode 100644 index 54ca60e..0000000 --- a/lustre/kernel_patches/patches/raid5-mmp-unplug-dev-rhel6.patch +++ /dev/null @@ -1,28 +0,0 @@ -Force MD devices to pass SYNC reads directly to the disk -instead of handling from cache. This is needed for MMP -on MD RAID devices, and in theory could be accepted in -the upstream kernel. Not needed for DMU. - -Index: linux-2.6.32-131.0.15.el6.x86_64/drivers/md/raid5.c -=================================================================== ---- linux-2.6.32-131.0.15.el6.x86_64.orig/drivers/md/raid5.c 2011-05-10 21:38:35.000000000 +0300 -+++ linux-2.6.32-131.0.15.el6.x86_64/drivers/md/raid5.c 2011-05-20 08:26:04.000000000 +0300 -@@ -2177,6 +2177,8 @@ static int add_stripe_bio(struct stripe_ - bi->bi_next = *bip; - *bip = bi; - raid5_inc_bi_active_stripes(bi); -+ if (bio_rw_flagged(bi, BIO_RW_SYNCIO) && !forwrite) -+ clear_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); /* force to read from disk. */ - - if (forwrite) { - /* check if page is covered */ -@@ -4132,6 +4134,9 @@ static int make_request(mddev_t *mddev, - bio_endio(bi, 0); - } - -+ if (bio_rw_flagged(bi, BIO_RW_SYNCIO)) -+ md_raid5_unplug_device(conf); -+ - return 0; - } - diff --git a/lustre/kernel_patches/patches/raid5-mmp-unplug-dev-sles11sp1.patch b/lustre/kernel_patches/patches/raid5-mmp-unplug-dev-sles11sp1.patch deleted file mode 100644 index ea5378b..0000000 --- a/lustre/kernel_patches/patches/raid5-mmp-unplug-dev-sles11sp1.patch +++ /dev/null @@ -1,30 +0,0 @@ -Force MD devices to pass SYNC reads directly to the disk -instead of handling from cache. This is needed for MMP -on MD RAID devices, and in theory could be accepted in -the upstream kernel. Not needed for DMU. - -Index: linux-2.6.32/drivers/md/raid5.c -=================================================================== ---- linux-2.6.32.orig/drivers/md/raid5.c 2012-06-22 06:09:49.000000000 -0400 -+++ linux-2.6.32/drivers/md/raid5.c 2013-01-25 10:11:10.076431000 -0500 -@@ -2169,6 +2169,9 @@ static int add_stripe_bio(struct stripe_ - bi->bi_next = *bip; - *bip = bi; - bi->bi_phys_segments++; -+ /* force to read from disk. */ -+ if ((bi->bi_rw & REQ_RW_SYNC) && !forwrite) -+ clear_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); - spin_unlock_irq(&conf->device_lock); - spin_unlock(&sh->lock); - -@@ -4008,6 +4008,10 @@ static int make_request(mddev_t *mddev, - - bio_endio(bi, 0); - } -+ -+ if (bi->bi_rw & REQ_RW_SYNC) -+ md_wakeup_thread(mddev->thread); -+ - return 0; - } - -- 1.8.3.1