From 0c20a351a4f8508ba80e8f5b674034791e13d8e8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 4 Feb 2002 20:33:56 -0800 Subject: [PATCH] v2.4.14.9 -> v2.4.15 - Jan Kara: fix quota SMP races with BKL --- Documentation/Configure.help | 12 ++++++-- Makefile | 2 +- arch/alpha/vmlinux.lds.in | 2 +- arch/arm/mach-epxa10db/dma.c | 2 +- drivers/s390/s390io.c | 2 +- drivers/scsi/sym53c8xx_2/sym_glue.h | 2 +- fs/dquot.c | 44 +++++++++++------------------ fs/inode.c | 5 ++-- include/linux/quota.h | 1 + 9 files changed, 35 insertions(+), 37 deletions(-) diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 48a44d045475..75c381288232 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -887,9 +887,15 @@ CONFIG_IDEDMA_PCI_AUTO IGNORE word93 Validation BITS CONFIG_IDEDMA_IVB - Since various rules were applied and created ... et al. as it - relates the detection of valid cable signals. This is a result of - unclear terms in ATA-4 and ATA-5 standards. + There are unclear terms is ATA-4 and ATA-5 standards how certain + hardware (an 80c ribbon) should be detected. Different interpretations + of the standards have been released in hardware. This causes problems: + for example, a host with Ultra Mode 4 (or higher) will not run + in that mode with an 80c ribbon. + + If you are experiencing compatibility or performance problems, you + MAY try to answering Y here. However, it does not necessarily solve + any of your problems, it could even cause more of them. It is normally safe to answer Y; however, the default is N. diff --git a/Makefile b/Makefile index c1f98a7cf45c..f1cd6489304c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 15 -EXTRAVERSION =-pre9 +EXTRAVERSION =-greased-turkey KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff --git a/arch/alpha/vmlinux.lds.in b/arch/alpha/vmlinux.lds.in index da193ba5aa66..ba7ad8f9f776 100644 --- a/arch/alpha/vmlinux.lds.in +++ b/arch/alpha/vmlinux.lds.in @@ -92,5 +92,5 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } - /DISCARD/ : { *(.text.exit) *(.data.exit) } + /DISCARD/ : { *(.text.exit) *(.data.exit) *(.exitcall.exit) } } diff --git a/arch/arm/mach-epxa10db/dma.c b/arch/arm/mach-epxa10db/dma.c index 490f2a6162b1..2edf62a11fe0 100644 --- a/arch/arm/mach-epxa10db/dma.c +++ b/arch/arm/mach-epxa10db/dma.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include +#include #include #include diff --git a/drivers/s390/s390io.c b/drivers/s390/s390io.c index a8c1543c8762..f06ffdfd2d9b 100644 --- a/drivers/s390/s390io.c +++ b/drivers/s390/s390io.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h index 8de496992087..49d6d32f9641 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.h +++ b/drivers/scsi/sym53c8xx_2/sym_glue.h @@ -77,7 +77,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/fs/dquot.c b/fs/dquot.c index 02ee28f72911..0f41e8eeb001 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -189,11 +189,8 @@ static inline void move_dquot_head(struct dquot *dquot) static inline void remove_free_dquot(struct dquot *dquot) { - /* sanity check */ - if (list_empty(&dquot->dq_free)) { - printk("remove_free_dquot: dquot not on the free list??\n"); - return; /* J.K. Just don't do anything */ - } + if (list_empty(&dquot->dq_free)) + return; list_del(&dquot->dq_free); INIT_LIST_HEAD(&dquot->dq_free); nr_free_dquots--; @@ -330,24 +327,6 @@ out_lock: unlock_dquot(dquot); } -/* - * Unhash and selectively clear the dquot structure, - * but preserve the use count, list pointers, and - * wait queue. - */ -void clear_dquot(struct dquot *dquot) -{ - /* unhash it first */ - remove_dquot_hash(dquot); - dquot->dq_sb = NULL; - dquot->dq_id = 0; - dquot->dq_dev = NODEV; - dquot->dq_type = -1; - dquot->dq_flags = 0; - dquot->dq_referenced = 0; - memset(&dquot->dq_dqb, 0, sizeof(struct dqblk)); -} - /* Invalidate all dquots on the list, wait for all users. Note that this function is called * after quota is disabled so no new quota might be created. As we only insert to the end of * inuse list, we don't have to restart searching... */ @@ -363,6 +342,7 @@ restart: continue; if (dquot->dq_type != type) continue; + dquot->dq_flags |= DQ_INVAL; if (dquot->dq_count) /* * Wait for any users of quota. As we have already cleared the flags in @@ -384,6 +364,7 @@ int sync_dquots(kdev_t dev, short type) struct list_head *head; struct dquot *dquot; + lock_kernel(); restart: for (head = inuse_list.next; head != &inuse_list; head = head->next) { dquot = list_entry(head, struct dquot, dq_inuse); @@ -405,6 +386,7 @@ restart: goto restart; } dqstats.syncs++; + unlock_kernel(); return 0; } @@ -428,7 +410,9 @@ static void prune_dqcache(int count) int shrink_dqcache_memory(int priority, unsigned int gfp_mask) { + lock_kernel(); prune_dqcache(nr_free_dquots / (priority + 1)); + unlock_kernel(); kmem_cache_shrink(dquot_cachep); return 0; } @@ -465,12 +449,13 @@ we_slept: return; } dquot->dq_count--; - /* Place at end of LRU free queue */ - put_dquot_last(dquot); + /* If dquot is going to be invalidated invalidate_dquots() is going to free it so */ + if (!(dquot->dq_flags & DQ_INVAL)) + put_dquot_last(dquot); /* Place at end of LRU free queue */ wake_up(&dquot->dq_wait_free); } -struct dquot *get_empty_dquot(void) +static struct dquot *get_empty_dquot(void) { struct dquot *dquot; @@ -633,9 +618,11 @@ put_it: /* Free list of dquots - called from inode.c */ void put_dquot_list(struct list_head *tofree_head) { - struct list_head *act_head = tofree_head->next; + struct list_head *act_head; struct dquot *dquot; + lock_kernel(); + act_head = tofree_head->next; /* So now we have dquots on the list... Just free them */ while (act_head != tofree_head) { dquot = list_entry(act_head, struct dquot, dq_free); @@ -644,6 +631,7 @@ void put_dquot_list(struct list_head *tofree_head) INIT_LIST_HEAD(&dquot->dq_free); dqput(dquot); } + unlock_kernel(); } static inline void dquot_incr_inodes(struct dquot *dquot, unsigned long number) @@ -1289,6 +1277,7 @@ int quota_off(struct super_block *sb, short type) short cnt; struct quota_mount_options *dqopt = sb_dqopt(sb); + lock_kernel(); if (!sb) goto out; @@ -1313,6 +1302,7 @@ int quota_off(struct super_block *sb, short type) } up(&dqopt->dqoff_sem); out: + unlock_kernel(); return 0; } diff --git a/fs/inode.c b/fs/inode.c index 42d13e7afcf0..7d073ab51e1a 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1209,9 +1209,9 @@ void remove_dquot_ref(struct super_block *sb, short type) if (!sb->dq_op) return; /* nothing to do */ - /* We have to be protected against other CPUs */ - spin_lock(&inode_lock); + lock_kernel(); /* This lock is for quota code */ + spin_lock(&inode_lock); /* This lock is for inodes code */ list_for_each(act_head, &inode_in_use) { inode = list_entry(act_head, struct inode, i_list); @@ -1234,6 +1234,7 @@ void remove_dquot_ref(struct super_block *sb, short type) remove_inode_dquot_ref(inode, type, &tofree_head); } spin_unlock(&inode_lock); + unlock_kernel(); put_dquot_list(&tofree_head); } diff --git a/include/linux/quota.h b/include/linux/quota.h index 3f69eb96e551..3ab244576240 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -154,6 +154,7 @@ extern int dquot_root_squash; #define DQ_BLKS 0x10 /* uid/gid has been warned about blk limit */ #define DQ_INODES 0x20 /* uid/gid has been warned about inode limit */ #define DQ_FAKE 0x40 /* no limits only usage */ +#define DQ_INVAL 0x80 /* dquot is going to be invalidated */ struct dquot { struct list_head dq_hash; /* Hash list in memory */ -- 2.39.5