Commit 00b90961 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.119pre1

parent 792ee2cd
......@@ -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
......
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/)
......
......@@ -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();
}
/*
......
......@@ -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;
}
......
......@@ -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 */
......
......@@ -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 */
};
......
......@@ -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",
......
......@@ -25,6 +25,7 @@
#include <linux/cdrom.h>
#include <linux/init.h>
#include <linux/nls.h>
#include <linux/ctype.h>
#include <asm/system.h>
#include <asm/uaccess.h>
......@@ -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 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
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 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
* 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 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
<< 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
......
......@@ -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;
......
......@@ -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; i<dentry->d_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) {
......
......@@ -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;
}
......
......@@ -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 */
......
......@@ -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
......
......@@ -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 */
......
......@@ -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 */
......
......@@ -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);
}
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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,
......
......@@ -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);
......
......@@ -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 {
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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);
......
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment