From 00b909610b4bb19aa9d02ac5fb440acc0ab606ba Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:16:27 -0500 Subject: [PATCH] Import 2.1.119pre1 --- CREDITS | 8 +- Makefile | 2 +- arch/i386/kernel/irq.c | 4 +- arch/i386/kernel/smp.c | 14 +- drivers/block/ide.c | 3 +- drivers/char/joystick.c | 1 + fs/hfs/super.c | 19 ++- fs/isofs/inode.c | 293 ++++++++++++++++++++++++++++++++----- fs/isofs/joliet.c | 16 +- fs/isofs/namei.c | 53 +++---- fs/nfs/mount_clnt.c | 1 + fs/romfs/inode.c | 13 +- include/asm-i386/hardirq.h | 2 +- include/asm-i386/softirq.h | 2 +- include/linux/iso_fs_sb.h | 1 - include/net/sock.h | 32 +--- kernel/sched.c | 3 - mm/swapfile.c | 6 +- net/ipv4/raw.c | 4 +- net/ipv4/tcp.c | 4 +- net/ipv4/tcp_ipv4.c | 8 +- net/ipv4/tcp_timer.c | 6 +- net/ipv4/timer.c | 2 +- net/ipv4/udp.c | 4 +- net/ipv6/raw.c | 2 +- net/ipv6/tcp_ipv6.c | 6 +- net/ipv6/udp.c | 2 +- net/unix/af_unix.c | 12 +- 28 files changed, 356 insertions(+), 167 deletions(-) diff --git a/CREDITS b/CREDITS index c563579b70ee..c6c7c7f87522 100644 --- a/CREDITS +++ b/CREDITS @@ -288,8 +288,8 @@ N: Gordon Chaffee E: chaffee@cs.berkeley.edu W: http://bmrc.berkeley.edu/people/chaffee/ D: vfat, fat32, joliet, native language support -S: 3674 Oakwood Terrace #201 -S: Fremont, California 94536 +S: 3700 Warwick Road +S: Fremont, California 94555 S: USA N: Chih-Jen Chang @@ -708,8 +708,8 @@ N: Richard Henderson E: rth@cygnus.com E: richard@gnu.org D: Alpha/ELF, gcc, binutils, and glibc -S: 50 E. Middlefield #10 -S: Mountain View, California 94043-3822 +S: 5450 Mayme #25 +S: San Jose, California 95129 S: USA N: Sebastian Hetze diff --git a/Makefile b/Makefile index 4fa20439d046..ff40e2075c9b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 118 +SUBLEVEL = 119 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index ed086f5be3c9..b322f9f214ea 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -450,12 +450,12 @@ static inline void wait_on_irq(int cpu) * no other CPU is executing any bottom half handler. * * Don't wait if we're already running in an interrupt - * context or are inside a bh handler. + * context or are inside a bh handler. */ void synchronize_bh(void) { if (atomic_read(&global_bh_count) && !in_interrupt()) - wait_on_bh(); + wait_on_bh(); } /* diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index d230574ed6a8..e8d5ec7d1963 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -245,7 +245,7 @@ __initfunc(static int smp_read_mpc(struct mp_config_table *mpc)) { char str[16]; int count=sizeof(*mpc); - int apics=0; + int ioapics = 0; unsigned char *mpt=((unsigned char *)mpc)+count; if(memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) @@ -364,11 +364,15 @@ __initfunc(static int smp_read_mpc(struct mp_config_table *mpc)) (struct mpc_config_ioapic *)mpt; if(m->mpc_flags&MPC_APIC_USABLE) { - apics++; + ioapics++; printk("I/O APIC #%d Version %d at 0x%lX.\n", m->mpc_apicid,m->mpc_apicver, m->mpc_apicaddr); - mp_ioapic_addr = m->mpc_apicaddr; + /* + * we use the first one only currently + */ + if (!ioapics) + mp_ioapic_addr = m->mpc_apicaddr; } mpt+=sizeof(*m); count+=sizeof(*m); @@ -400,8 +404,8 @@ __initfunc(static int smp_read_mpc(struct mp_config_table *mpc)) } } } - if(apics>1) - printk("Warning: Multiple APICs not supported.\n"); + if (ioapics > 1) + printk("Warning: Multiple IO-APICs not yet supported.\n"); return num_processors; } diff --git a/drivers/block/ide.c b/drivers/block/ide.c index 07463389a1eb..ca7f01352e30 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -1104,8 +1104,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, unsigned long *hwgroup_flags if (sleep) { if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep)) sleep = jiffies + WAIT_MIN_SLEEP; - hwgroup->timer.expires = sleep; - add_timer(&hwgroup->timer); + mod_timer(&hwgroup->timer, sleep); } else { /* Ugly, but how can we sleep for the lock otherwise? perhaps from tq_scheduler? */ ide_release_lock(&ide_lock); /* for atari only */ diff --git a/drivers/char/joystick.c b/drivers/char/joystick.c index 25a7c2b47d5d..4f940f4d5081 100644 --- a/drivers/char/joystick.c +++ b/drivers/char/joystick.c @@ -771,6 +771,7 @@ static struct file_operations js_fops = js_ioctl, /* js_ioctl */ NULL, /* js_mmap */ js_open, /* js_open */ + NULL, /* js_flush */ js_release, /* js_release */ NULL /* js_sync */ }; diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 166d69cd5661..381969d34545 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -396,9 +396,7 @@ struct super_block *hfs_read_super(struct super_block *s, void *data, struct hfs_mdb *mdb; struct hfs_cat_key key; kdev_t dev = s->s_dev; -#ifndef CONFIG_MAC_PARTITION hfs_s32 part_size, part_start; -#endif struct inode *root_inode; int part; @@ -415,16 +413,25 @@ struct super_block *hfs_read_super(struct super_block *s, void *data, /* set the device driver to 512-byte blocks */ set_blocksize(dev, HFS_SECTOR_SIZE); - /* look for a partition table and find the correct partition */ -#ifndef CONFIG_MAC_PARTITION +#ifdef CONFIG_MAC_PARTITION + /* check to see if we're in a partition */ + mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, 0); + + /* erk. try parsing the partition table ourselves */ + if (!mdb) { + if (hfs_part_find(s, part, silent, &part_size, &part_start)) { + goto bail2; + } + mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, part_start); + } +#else if (hfs_part_find(s, part, silent, &part_size, &part_start)) { goto bail2; } mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, part_start); -#else - mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, 0); #endif + if (!mdb) { if (!silent) { printk("VFS: Can't find a HFS filesystem on dev %s.\n", diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 62557f29c7a1..aea72a76ec0d 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,18 @@ static int check_malloc = 0; static int check_bread = 0; #endif +static int isofs_hashi(struct dentry *parent, struct qstr *qstr); +static int isofs_hash(struct dentry *parent, struct qstr *qstr); +static int isofs_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b); +static int isofs_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b); + +#ifdef CONFIG_JOLIET +static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr); +static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr); +static int isofs_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b); +static int isofs_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b); +#endif + void isofs_put_super(struct super_block *sb) { #ifdef CONFIG_JOLIET @@ -71,21 +84,213 @@ static struct super_operations isofs_sops = { NULL }; +static struct dentry_operations isofs_dentry_ops[] = { + { + NULL, /* d_revalidate */ + isofs_hash, + isofs_cmp, + NULL /* d_delete */ + }, + { + NULL, /* d_revalidate */ + isofs_hashi, + isofs_cmpi, + NULL /* d_delete */ + }, +#ifdef CONFIG_JOLIET + { + NULL, /* d_revalidate */ + isofs_hash_ms, + isofs_cmp_ms, + NULL /* d_delete */ + }, + { + NULL, /* d_revalidate */ + isofs_hashi_ms, + isofs_cmpi_ms, + NULL /* d_delete */ + } +#endif +}; + struct iso9660_options{ - char map; - char rock; - char joliet; - char cruft; - char unhide; - unsigned char check; - unsigned int blocksize; - mode_t mode; - gid_t gid; - uid_t uid; - char *iocharset; - unsigned char utf8; + char map; + char rock; + char joliet; + char cruft; + char unhide; + unsigned char check; + unsigned int blocksize; + mode_t mode; + gid_t gid; + uid_t uid; + char *iocharset; + unsigned char utf8; }; +static int strnicmp(const char *s1, const char *s2, int len) +{ + int n = 0; + while (*s1 && *s2 && (tolower(*s1) == tolower(*s2))) { + s1++; s2++; n++; + if (n == len) return 0; + } + if (*s1 == 0 && *s2 == 0) return 0; + if (*s1 && *s2) { + if (*s1 > *s2) return 1; + return -1; + } + if (*s1) return 1; + return -1; +} + +/* + * Compute the hash for the isofs name corresponding to the dentry. + */ +static int +isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms) +{ + const char *name; + int len; + + len = qstr->len; + name = qstr->name; + if (ms) { + while (len && name[len-1] == '.') + len--; + } + + qstr->hash = full_name_hash(name, len); + + return 0; +} + +/* + * Compute the hash for the isofs name corresponding to the dentry. + */ +static int +isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms) +{ + const char *name; + int len; + char c; + unsigned long hash; + + len = qstr->len; + name = qstr->name; + if (ms) { + while (len && name[len-1] == '.') + len--; + } + + hash = init_name_hash(); + while (len--) { + c = tolower(*name++); + hash = partial_name_hash(tolower(c), hash); + } + qstr->hash = end_name_hash(hash); + + return 0; +} + +/* + * Case insensitive compare of two isofs names. + */ +static int +isofs_cmpi_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int ms) +{ + int alen, blen; + + /* A filename cannot end in '.' or we treat it like it has none */ + alen = a->len; + blen = b->len; + if (ms) { + while (alen && a->name[alen-1] == '.') + alen--; + while (blen && b->name[blen-1] == '.') + blen--; + } + if (alen == blen) { + if (strnicmp(a->name, b->name, alen) == 0) + return 0; + } + return 1; +} + +/* + * Case sensitive compare of two isofs names. + */ +static int +isofs_cmp_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int ms) +{ + int alen, blen; + + /* A filename cannot end in '.' or we treat it like it has none */ + alen = a->len; + blen = b->len; + if (ms) { + while (alen && a->name[alen-1] == '.') + alen--; + while (blen && b->name[blen-1] == '.') + blen--; + } + if (alen == blen) { + if (strncmp(a->name, b->name, alen) == 0) + return 0; + } + return 1; +} + +static int +isofs_hash(struct dentry *dentry, struct qstr *qstr) +{ + return isofs_hash_common(dentry, qstr, 0); +} + +static int +isofs_hashi(struct dentry *dentry, struct qstr *qstr) +{ + return isofs_hashi_common(dentry, qstr, 0); +} + +static int +isofs_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b) +{ + return isofs_cmp_common(dentry, a, b, 0); +} + +static int +isofs_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b) +{ + return isofs_cmpi_common(dentry, a, b, 0); +} + +#ifdef CONFIG_JOLIET +static int +isofs_hash_ms(struct dentry *dentry, struct qstr *qstr) +{ + return isofs_hash_common(dentry, qstr, 1); +} + +static int +isofs_hashi_ms(struct dentry *dentry, struct qstr *qstr) +{ + return isofs_hashi_common(dentry, qstr, 1); +} + +static int +isofs_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b) +{ + return isofs_cmp_common(dentry, a, b, 1); +} + +static int +isofs_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b) +{ + return isofs_cmpi_common(dentry, a, b, 1); +} +#endif + static int parse_options(char *options, struct iso9660_options * popt) { char *this_char,*value; @@ -95,7 +300,7 @@ static int parse_options(char *options, struct iso9660_options * popt) popt->joliet = 'y'; popt->cruft = 'n'; popt->unhide = 'n'; - popt->check = 's'; /* default: strict */ + popt->check = 'u'; /* unset */ popt->blocksize = 1024; popt->mode = S_IRUGO | S_IXUGO; /* r-x for all. The disc could be shared with DOS machines so @@ -274,6 +479,7 @@ struct super_block *isofs_read_super(struct super_block *s, void *data, unsigned int vol_desc_start; struct inode * inode; struct iso9660_options opt; + int table; MOD_INC_USE_COUNT; /* lock before any blocking operations */ @@ -374,7 +580,7 @@ struct super_block *isofs_read_super(struct super_block *s, void *data, } else if (sec->escape[2] == 0x45) { joliet_level = 3; } - printk("ISO 9660 Extensions: Microsoft Joliet Level %d\n", + printk(KERN_DEBUG"ISO 9660 Extensions: Microsoft Joliet Level %d\n", joliet_level); } goto root_found; @@ -532,7 +738,6 @@ root_found: s->s_op = &isofs_sops; s->u.isofs_sb.s_mapping = opt.map; s->u.isofs_sb.s_rock = (opt.rock == 'y' ? 2 : 0); - s->u.isofs_sb.s_name_check = opt.check; s->u.isofs_sb.s_cruft = opt.cruft; s->u.isofs_sb.s_unhide = opt.unhide; s->u.isofs_sb.s_uid = opt.uid; @@ -555,7 +760,10 @@ root_found: * CD with Unicode names. Until someone sees such a beast, it * will not be supported. */ - if (joliet_level && opt.rock == 'y' && s->u.isofs_sb.s_rock != 1) { + if (opt.rock == 'y' && s->u.isofs_sb.s_rock == 1) { + joliet_level = 0; + } + if (joliet_level) { iput(inode); pri = (struct iso_primary_descriptor *) sec; rootp = (struct iso_directory_record *) @@ -566,11 +774,22 @@ root_found: << s -> u.isofs_sb.s_log_zone_size); inode = iget(s, s->u.isofs_sb.s_firstdatazone); s->u.isofs_sb.s_rock = 0; + opt.rock = 'n'; + } + + if (opt.check == 'u') { + /* Only Joliet is case insensitive by default */ + if (joliet_level) opt.check = 'r'; + else opt.check = 's'; } s->s_root = d_alloc_root(inode, NULL); if (!(s->s_root)) goto out_no_root; + table = 0; + if (joliet_level) table += 2; + if (opt.check == 'r') table++; + s->s_root->d_op = &isofs_dentry_ops[table]; if(!check_disk_change(dev)) { brelse(bh); @@ -694,34 +913,36 @@ int isofs_bmap(struct inode * inode,int block) size = inode->u.isofs_i.i_section_size; nextino = inode->u.isofs_i.i_next_section_ino; #ifdef DEBUG - printk("first inode: inode=%lu nextino=%lu firstext=%u size=%lu\n", + printk("first inode: inode=%x nextino=%x firstext=%u size=%lu\n", inode->i_ino, nextino, firstext, size); #endif i = 0; - while(b_off >= offset + size) { - offset += size; - - if(nextino == 0) return 0; - ino = iget(inode->i_sb, nextino); - if(!ino) return 0; - firstext = ino->u.isofs_i.i_first_extent; - size = ino->u.isofs_i.i_section_size; + if (nextino) { + while(b_off >= offset + size) { + offset += size; + + if(nextino == 0) return 0; + ino = iget(inode->i_sb, nextino); + if(!ino) return 0; + firstext = ino->u.isofs_i.i_first_extent; + size = ino->u.isofs_i.i_section_size; #ifdef DEBUG - printk("read inode: inode=%lu ino=%lu nextino=%lu firstext=%u size=%lu\n", - inode->i_ino, nextino, ino->u.isofs_i.i_next_section_ino, firstext, size); + printk("read inode: inode=%lu ino=%lu nextino=%lu firstext=%u size=%lu\n", + inode->i_ino, nextino, ino->u.isofs_i.i_next_section_ino, firstext, size); #endif - nextino = ino->u.isofs_i.i_next_section_ino; - iput(ino); + nextino = ino->u.isofs_i.i_next_section_ino; + iput(ino); - if(++i > 100) { - printk("isofs_bmap: More than 100 file sections ?!?, aborting...\n"); - printk("isofs_bmap: ino=%lu block=%d firstext=%u size=%u nextino=%lu\n", - inode->i_ino, block, firstext, (unsigned)size, nextino); - return 0; + if(++i > 100) { + printk("isofs_bmap: More than 100 file sections ?!?, aborting...\n"); + printk("isofs_bmap: ino=%lu block=%d firstext=%u size=%u nextino=%lu\n", + inode->i_ino, block, firstext, (unsigned)size, nextino); + return 0; + } } } #ifdef DEBUG - printk("isofs_bmap: mapped inode:block %lu:%d to block %lu\n", + printk("isofs_bmap: mapped inode:block %x:%d to block %lu\n", inode->i_ino, block, (b_off - offset + firstext) >> ISOFS_BUFFER_BITS(inode)); #endif return (b_off - offset + firstext) >> ISOFS_BUFFER_BITS(inode); @@ -905,7 +1126,7 @@ void isofs_read_inode(struct inode * inode) #endif #ifdef DEBUG - printk("Get inode %d: %d %d: %d\n",inode->i_ino, block, + printk("Get inode %x: %d %d: %d\n",inode->i_ino, block, ((int)pnt) & 0x3ff, inode->i_size); #endif diff --git a/fs/isofs/joliet.c b/fs/isofs/joliet.c index b620e4144d73..3da5bd04c1d4 100644 --- a/fs/isofs/joliet.c +++ b/fs/isofs/joliet.c @@ -79,8 +79,6 @@ get_joliet_filename(struct iso_directory_record * de, struct inode * inode, unsigned char utf8; struct nls_table *nls; unsigned char len = 0; - int i; - char c; utf8 = inode->i_sb->u.isofs_sb.s_utf8; nls = inode->i_sb->u.isofs_sb.s_nls_iocharset; @@ -96,14 +94,12 @@ get_joliet_filename(struct iso_directory_record * de, struct inode * inode, len -= 2; } - if (inode->i_sb->u.isofs_sb.s_name_check == 'r') { - for (i = 0; i < len; i++) { - c = outname[i]; - /* lower case */ - if (c >= 'A' && c <= 'Z') c |= 0x20; - if (c == ';') c = '.'; - outname[i] = c; - } + /* + * Windows doesn't like periods at the end of a name, + * so neither do we + */ + while (len >= 2 && (outname[len-1] == '.')) { + len--; } return len; diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c index a59f15ad8f96..ee0634da212e 100644 --- a/fs/isofs/namei.c +++ b/fs/isofs/namei.c @@ -22,33 +22,31 @@ * ok, we cannot use strncmp, as the name is not in our data space. * Thus we'll have to use isofs_match. No big problem. Match also makes * some sanity tests. - * - * NOTE! unlike strncmp, isofs_match returns 1 for success, 0 for failure. */ -static int isofs_match(int len,const char * name, const char * compare, int dlen) +static int +isofs_cmp(struct dentry * dentry, const char * compare, int dlen) { + struct qstr qstr; + if (!compare) - return 0; + return 1; /* check special "." and ".." files */ if (dlen == 1) { /* "." */ if (compare[0] == 0) { - if (!len) - return 1; + if (!dentry->d_name.len) + return 0; compare = "."; } else if (compare[0] == 1) { compare = ".."; dlen = 2; } } -#if 0 - if (len <= 2) printk("Match: %d %d %s %d %d \n",len,dlen,compare,de->name[0], dlen); -#endif - - if (dlen != len) - return 0; - return !memcmp(name, compare, len); + + qstr.name = compare; + qstr.len = dlen; + return dentry->d_op->d_compare(dentry, &dentry->d_name, &qstr); } /* @@ -59,8 +57,8 @@ static int isofs_match(int len,const char * name, const char * compare, int dlen * itself (as an inode number). It does NOT read the inode of the * entry - you'll have to do that yourself if you want to. */ -static struct buffer_head * isofs_find_entry(struct inode * dir, - const char * name, int namelen, unsigned long * ino) +static struct buffer_head * +isofs_find_entry(struct inode *dir, struct dentry *dentry, unsigned long *ino) { unsigned long bufsize = ISOFS_BUFFER_SIZE(dir); unsigned char bufbits = ISOFS_BUFFER_BITS(dir); @@ -195,7 +193,7 @@ static struct buffer_head * isofs_find_entry(struct inode * dir, } /* This allows us to match with and without * a trailing period. */ - if(dpnt[dlen-1] == '.' && namelen == dlen-1) + if(dpnt[dlen-1] == '.' && dentry->d_name.len == dlen-1) dlen--; } /* @@ -205,7 +203,7 @@ static struct buffer_head * isofs_find_entry(struct inode * dir, if( !(de->flags[-dir->i_sb->u.isofs_sb.s_high_sierra] & 5) || dir->i_sb->u.isofs_sb.s_unhide == 'y' ) { - match = isofs_match(namelen,name,dpnt,dlen); + match = (isofs_cmp(dentry,dpnt,dlen) == 0); } if (match) { if(inode_number == -1) { @@ -231,11 +229,10 @@ int isofs_lookup(struct inode * dir, struct dentry * dentry) { unsigned long ino; struct buffer_head * bh; - char *lcname; struct inode *inode; #ifdef DEBUG - printk("lookup: %x %d\n",dir->i_ino, dentry->d_name.len); + printk("lookup: %x %s\n",dir->i_ino, dentry->d_name.name); #endif if (!dir) return -ENOENT; @@ -243,23 +240,9 @@ int isofs_lookup(struct inode * dir, struct dentry * dentry) if (!S_ISDIR(dir->i_mode)) return -ENOENT; - /* If mounted with check=relaxed (and most likely norock), - * then first convert this name to lower case. - */ - if (dir->i_sb->u.isofs_sb.s_name_check == 'r' && - (lcname = kmalloc(dentry->d_name.len, GFP_KERNEL)) != NULL) { - int i; - char c; + dentry->d_op = dir->i_sb->s_root->d_op; - for (i=0; id_name.len; i++) { - c = dentry->d_name.name[i]; - if (c >= 'A' && c <= 'Z') c |= 0x20; - lcname[i] = c; - } - bh = isofs_find_entry(dir, lcname, dentry->d_name.len, &ino); - kfree(lcname); - } else - bh = isofs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &ino); + bh = isofs_find_entry(dir, dentry, &ino); inode = NULL; if (bh) { diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index 81da8f9968dd..3ecb9bfa630e 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c @@ -78,6 +78,7 @@ mnt_create(char *hostname, struct sockaddr_in *srvaddr) clnt->cl_softrtry = 1; clnt->cl_chatty = 1; clnt->cl_oneshot = 1; + clnt->cl_intr = 1; } return clnt; } diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index 86c9208ad4d6..aa361336a376 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c @@ -30,17 +30,18 @@ * correct namelen for statfs * spotted by Bill Hawes: * readlink shouldn't iput() + * Jun 1998 2.1.106 from Avery Pennarun: glibc scandir() + * exposed a problem in readdir + * 2.1.107 code-freeze spellchecker run + * Aug 1998 2.1.118+ VFS changes */ /* todo: * - see Documentation/filesystems/romfs.txt - * - use malloced memory for file names? - * - quicklist routines from fs/namei.c, get_page is possibly not - * intended to be used now + * - use allocated, not stack memory for file names? * - considering write access... * - network (tftp) files? - * - in the ancient times something leaked to made umounts - * impossible, but I've not seen it in the last months + * - merge back some _op tables */ /* @@ -492,6 +493,7 @@ static struct file_operations romfs_file_operations = { NULL, /* ioctl */ generic_file_mmap, /* mmap */ NULL, /* open */ + NULL, /* flush */ NULL, /* release */ NULL, /* fsync */ NULL, /* fasync */ @@ -529,6 +531,7 @@ static struct file_operations romfs_dir_operations = { NULL, /* ioctl */ NULL, /* mmap */ NULL, /* open */ + NULL, /* flush */ NULL, /* release */ NULL, /* fsync */ NULL, /* fasync */ diff --git a/include/asm-i386/hardirq.h b/include/asm-i386/hardirq.h index bfc535137b92..533961343360 100644 --- a/include/asm-i386/hardirq.h +++ b/include/asm-i386/hardirq.h @@ -20,7 +20,7 @@ extern unsigned int local_irq_count[NR_CPUS]; #define hardirq_enter(cpu) (local_irq_count[cpu]++) #define hardirq_exit(cpu) (local_irq_count[cpu]--) -#define synchronize_irq() do { } while (0) +#define synchronize_irq() barrier() #else diff --git a/include/asm-i386/softirq.h b/include/asm-i386/softirq.h index f77cce80a743..c96481626326 100644 --- a/include/asm-i386/softirq.h +++ b/include/asm-i386/softirq.h @@ -86,7 +86,7 @@ extern inline void end_bh_atomic(void) /* These are for the irq's testing the lock */ #define softirq_trylock(cpu) (local_bh_count[cpu] ? 0 : (local_bh_count[cpu]=1)) #define softirq_endlock(cpu) (local_bh_count[cpu] = 0) -#define synchronize_bh() do { } while (0) +#define synchronize_bh() barrier() #endif /* SMP */ diff --git a/include/linux/iso_fs_sb.h b/include/linux/iso_fs_sb.h index 879f8faf3e14..7bb55a504ce5 100644 --- a/include/linux/iso_fs_sb.h +++ b/include/linux/iso_fs_sb.h @@ -16,7 +16,6 @@ struct isofs_sb_info { unsigned char s_rock; unsigned char s_joliet_level; unsigned char s_utf8; - unsigned char s_name_check; /* r = relaxed, s = strict */ unsigned char s_cruft; /* Broken disks with high byte of length containing junk */ diff --git a/include/net/sock.h b/include/net/sock.h index ed05e12bea37..d8389f6330d3 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -350,7 +350,7 @@ struct sock { unsigned char reuse, /* SO_REUSEADDR setting */ nonagle; /* Disable Nagle algorithm? */ - int sock_readers; /* User count */ + atomic_t sock_readers; /* User count */ int rcvbuf; /* Size of receive buffer in bytes */ struct wait_queue **sleep; /* Sock wait queue */ @@ -643,42 +643,20 @@ static inline void lock_sock(struct sock *sk) #if 0 /* debugging code: the test isn't even 100% correct, but it can catch bugs */ /* Note that a double lock is ok in theory - it's just _usually_ a bug */ - if (sk->sock_readers) { + if (atomic_read(&sk->sock_readers)) { __label__ here; printk("double lock on socket at %p\n", &&here); here: } #endif -#ifdef __SMP__ - /* - * This is a very broken bottom half synchronization mechanism. - * You don't want to know.. - */ - { unsigned long flags; - save_flags(flags); - cli(); - sk->sock_readers++; - restore_flags(flags); - } -#else - sk->sock_readers++; - barrier(); -#endif + atomic_inc(&sk->sock_readers); + synchronize_bh(); } static inline void release_sock(struct sock *sk) { barrier(); -#if 0 -/* debugging code: remove me when ok */ - if (sk->sock_readers == 0) { - __label__ here; - sk->sock_readers = 1; - printk("trying to unlock unlocked socket at %p\n", &&here); -here: - } -#endif - if ((sk->sock_readers = sk->sock_readers-1) == 0) + if (atomic_dec_and_test(&sk->sock_readers)) __release_sock(sk); } diff --git a/kernel/sched.c b/kernel/sched.c index 228a397eb324..abb4ba695cb9 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -430,9 +430,6 @@ int del_timer(struct timer_list * timer) ret = detach_timer(timer); timer->next = timer->prev = 0; spin_unlock_irqrestore(&timerlist_lock, flags); - - /* Make sure the timer isn't running in parallell.. */ - synchronize_bh(); return ret; } diff --git a/mm/swapfile.c b/mm/swapfile.c index b644b06800a1..65c4b9463257 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -489,7 +489,7 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags) int swap_header_version; int lock_map_size = PAGE_SIZE; int nr_good_pages = 0; - char tmp_lock_map = 0; + unsigned long tmp_lock_map = 0; lock_kernel(); if (!capable(CAP_SYS_ADMIN)) @@ -558,9 +558,9 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags) goto bad_swap; } - p->swap_lockmap = &tmp_lock_map; + p->swap_lockmap = (char *) &tmp_lock_map; rw_swap_page_nocache(READ, SWP_ENTRY(type,0), (char *) swap_header); - p->swap_lockmap = 0; + p->swap_lockmap = NULL; if (!memcmp("SWAP-SPACE",swap_header->magic.magic,10)) swap_header_version = 1; diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 8d8bdab9753e..272f922cf33a 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -152,7 +152,7 @@ void raw_err (struct sock *sk, struct sk_buff *skb) int type = skb->h.icmph->type; int code = skb->h.icmph->code; - if (sk->ip_recverr && !sk->sock_readers) { + if (sk->ip_recverr && !atomic_read(&sk->sock_readers)) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2 && sock_queue_err_skb(sk, skb2)) kfree_skb(skb); @@ -194,7 +194,7 @@ int raw_rcv(struct sock *sk, struct sk_buff *skb) skb->h.raw = skb->nh.raw; - if (sk->sock_readers) { + if (atomic_read(&sk->sock_readers)) { __skb_queue_tail(&sk->back_log, skb); return 0; } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 3d6f188e7eff..c62dd193a9c4 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -707,7 +707,7 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags) int copied = 0; /* Verify that the socket is locked */ - if (!sk->sock_readers) + if (!atomic_read(&sk->sock_readers)) printk("tcp_do_sendmsg: socket not locked!\n"); /* Wait for a connection to finish. */ @@ -1389,7 +1389,7 @@ void tcp_close(struct sock *sk, unsigned long timeout) * Check whether the socket is locked ... supposedly * it's impossible to tcp_close() a locked socket. */ - if (sk->sock_readers) + if (atomic_read(&sk->sock_readers)) printk("tcp_close: socket already locked!\n"); /* We need to grab some memory, and put together a FIN, diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index e0ecdbfa5f1a..0255948300dd 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -720,7 +720,7 @@ static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *ip) * dropped. This is the new "fast" path mtu * discovery. */ - if (!sk->sock_readers) { + if (!atomic_read(&sk->sock_readers)) { lock_sock(sk); tcp_simple_retransmit(sk); release_sock(sk); @@ -813,7 +813,7 @@ void tcp_v4_err(struct sk_buff *skb, unsigned char *dp, int len) /* Prevent race conditions with accept() - * ICMP is unreliable. */ - if (sk->sock_readers) { + if (atomic_read(&sk->sock_readers)) { /* XXX: add a counter here to profile this. * If too many ICMPs get dropped on busy * servers this needs to be solved differently. @@ -1175,7 +1175,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, /* Clone the TCP header template */ newsk->dport = req->rmt_port; - newsk->sock_readers = 0; + atomic_set(&newsk->sock_readers, 0); atomic_set(&newsk->rmem_alloc, 0); skb_queue_head_init(&newsk->receive_queue); atomic_set(&newsk->wmem_alloc, 0); @@ -1543,7 +1543,7 @@ int tcp_v4_rcv(struct sk_buff *skb, unsigned short len) if (sk->state == TCP_TIME_WAIT) goto do_time_wait; - if (!sk->sock_readers) + if (!atomic_read(&sk->sock_readers)) return tcp_v4_do_rcv(sk, skb); __skb_queue_tail(&sk->back_log, skb); diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 665a448bb50c..94275718b481 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -182,7 +182,7 @@ void tcp_probe_timer(unsigned long data) if(sk->zapped) return; - if (sk->sock_readers) { + if (atomic_read(&sk->sock_readers)) { /* Try again in second. */ tcp_reset_xmit_timer(sk, TIME_PROBE0, HZ); return; @@ -432,7 +432,7 @@ void tcp_retransmit_timer(unsigned long data) return; } - if (sk->sock_readers) { + if (atomic_read(&sk->sock_readers)) { /* Try again in a second. */ tcp_reset_xmit_timer(sk, TIME_RETRANS, HZ); return; @@ -518,7 +518,7 @@ static void tcp_syn_recv_timer(unsigned long data) struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; /* TCP_LISTEN is implied. */ - if (!sk->sock_readers && tp->syn_wait_queue) { + if (!atomic_read(&sk->sock_readers) && tp->syn_wait_queue) { struct open_request *prev = (struct open_request *)(&tp->syn_wait_queue); struct open_request *req = tp->syn_wait_queue; do { diff --git a/net/ipv4/timer.c b/net/ipv4/timer.c index a0501bd1909a..d5f6d3eb5b9c 100644 --- a/net/ipv4/timer.c +++ b/net/ipv4/timer.c @@ -73,7 +73,7 @@ void net_timer (unsigned long data) int why = sk->timeout; /* Only process if socket is not in use. */ - if (sk->sock_readers) { + if (atomic_read(&sk->sock_readers)) { sk->timer.expires = jiffies+HZ; add_timer(&sk->timer); return; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 7e2c7bfa63d7..ea6419fbcb12 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -493,7 +493,7 @@ void udp_err(struct sk_buff *skb, unsigned char *dp, int len) return; /* No socket for error */ } - if (sk->ip_recverr && !sk->sock_readers) { + if (sk->ip_recverr && !atomic_read(&sk->sock_readers)) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2 && sock_queue_err_skb(sk, skb2)) kfree_skb(skb2); @@ -1026,7 +1026,7 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) static inline void udp_deliver(struct sock *sk, struct sk_buff *skb) { - if (sk->sock_readers) { + if (atomic_read(&sk->sock_readers)) { __skb_queue_tail(&sk->back_log, skb); return; } diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 659ec59ccf1b..e8e83488552d 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -220,7 +220,7 @@ int rawv6_rcv(struct sk_buff *skb, struct device *dev, if (sk->ip_hdrincl) skb->h.raw = skb->nh.raw; - if (sk->sock_readers) { + if (atomic_read(&sk->sock_readers)) { __skb_queue_tail(&sk->back_log, skb); return 0; } diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5fa45dce559b..c4cd19766b66 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -617,7 +617,7 @@ void tcp_v6_err(struct sk_buff *skb, int type, int code, unsigned char *header, */ sk->mtu = sk->dst_cache->pmtu; } - if (sk->sock_readers) { /* remove later */ + if (atomic_read(&sk->sock_readers)) { /* remove later */ printk(KERN_DEBUG "tcp_v6_err: pmtu disc: socket locked.\n"); return; } @@ -631,7 +631,7 @@ void tcp_v6_err(struct sk_buff *skb, int type, int code, unsigned char *header, struct open_request *req, *prev; struct ipv6hdr hd; case TCP_LISTEN: - if (sk->sock_readers) + if (atomic_read(&sk->sock_readers)) return; /* Grrrr - fix this later. */ @@ -1178,7 +1178,7 @@ int tcp_v6_rcv(struct sk_buff *skb, struct device *dev, if(sk->state == TCP_TIME_WAIT) goto do_time_wait; - if (!sk->sock_readers) + if (!atomic_read(&sk->sock_readers)) return tcp_v6_do_rcv(sk, skb); __skb_queue_tail(&sk->back_log, skb); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 2dac0570f654..971e9669cd5c 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -569,7 +569,7 @@ int udpv6_rcv(struct sk_buff *skb, struct device *dev, /* deliver */ - if (sk->sock_readers) + if (atomic_read(&sk->sock_readers)) __skb_queue_tail(&sk->back_log, skb); else udpv6_queue_rcv_skb(sk, skb); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 961516de6700..528e2a37a2b0 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -125,17 +125,17 @@ extern __inline__ int unix_may_send(unix_socket *sk, unix_socket *osk) extern __inline__ void unix_lock(unix_socket *sk) { - sk->sock_readers++; + atomic_inc(&sk->sock_readers); } extern __inline__ int unix_unlock(unix_socket *sk) { - return --sk->sock_readers; + return atomic_dec_and_test(&sk->sock_readers); } extern __inline__ int unix_locked(unix_socket *sk) { - return sk->sock_readers; + return atomic_read(&sk->sock_readers); } extern __inline__ void unix_release_addr(struct unix_address *addr) @@ -338,7 +338,7 @@ static void unix_destroy_socket(unix_socket *sk) sk->protinfo.af_unix.dentry=NULL; } - if(!unix_unlock(sk) && atomic_read(&sk->wmem_alloc) == 0) + if(unix_unlock(sk) && atomic_read(&sk->wmem_alloc) == 0) { sk_free(sk); unix_remove_socket(sk); @@ -418,7 +418,7 @@ static int unix_create1(struct socket *sock, struct sock **skp, int protocol) sk->destruct = unix_destruct_addr; sk->protinfo.af_unix.family=PF_UNIX; sk->protinfo.af_unix.dentry=NULL; - sk->sock_readers=1; /* Us */ + atomic_set(&sk->sock_readers, 1); /* Us */ sk->protinfo.af_unix.readsem=MUTEX; /* single task reading lock */ sk->mtu=4096; sk->protinfo.af_unix.list=&unix_sockets_unbound; @@ -1411,7 +1411,7 @@ static int unix_read_proc(char *buffer, char **start, off_t offset, { len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X %5ld", s, - s->sock_readers, + atomic_read(&s->sock_readers), 0, s->socket ? s->socket->flags : 0, s->type, -- 2.39.5