From 591f16526a7510dc0600e1e105b5642e316fe111 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:09:42 -0500 Subject: [PATCH] Import 1.1.58 --- CREDITS | 1 + Makefile | 2 +- drivers/block/ramdisk.c | 43 +++++++++++++++++++--- drivers/char/ChangeLog | 19 ++++++++++ drivers/char/n_tty.c | 8 ++++ drivers/char/serial.c | 4 ++ drivers/char/tty_io.c | 6 +++ fs/ChangeLog | 10 +++++ fs/ext2/CHANGES | 4 ++ fs/ext2/balloc.c | 18 ++++----- fs/ext2/file.c | 19 +++++++--- fs/ext2/ialloc.c | 17 +++++---- fs/ext2/inode.c | 4 +- fs/ext2/ioctl.c | 7 ++-- fs/ext2/super.c | 5 +++ fs/fcntl.c | 47 ++++++++++++++++++------ fs/isofs/namei.c | 2 +- fs/umsdos/file.c | 2 +- fs/umsdos/namei.c | 8 +++- include/asm-alpha/bitops.h | 75 +++++++++++++++++++++++++++++++++++++- include/linux/ext2_fs.h | 2 +- net/inet/README | 5 +++ net/inet/af_inet.c | 6 ++- net/inet/tcp.c | 15 ++++++++ 24 files changed, 277 insertions(+), 52 deletions(-) create mode 100644 fs/ChangeLog diff --git a/CREDITS b/CREDITS index a0252feb21b0..e5cd99ad4abc 100644 --- a/CREDITS +++ b/CREDITS @@ -97,6 +97,7 @@ S: United Kingdom N: Remy Card E: Remy.Card@masi.ibp.fr +E: Remy.Card@linux.org D: Extended file system designer and developer D: Second extended file system designer and developer S: Institut Blaise Pascal diff --git a/Makefile b/Makefile index 97bdbc975892..292a9e97d26d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 1 -SUBLEVEL = 57 +SUBLEVEL = 58 ARCH = i386 diff --git a/drivers/block/ramdisk.c b/drivers/block/ramdisk.c index 871def2c9eb9..bddf8a6f40f6 100644 --- a/drivers/block/ramdisk.c +++ b/drivers/block/ramdisk.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -98,7 +99,17 @@ long rd_init(long mem_start, int length) static void do_load(void) { struct buffer_head *bh; - struct minix_super_block s; + struct super_block { + union + { + char minix [sizeof (struct minix_super_block)]; + char ext2 [sizeof (struct ext2_super_block)]; + } record; + } sb; + struct minix_super_block *minixsb = + (struct minix_super_block *)&sb; + struct ext2_super_block *ext2sb = + (struct ext2_super_block *)&sb; int block, tries; int i = 1; int nblocks; @@ -121,12 +132,32 @@ static void do_load(void) } /* This is silly- why do we require it to be a MINIX FS? */ - *((struct minix_super_block *) &s) = - *((struct minix_super_block *) bh->b_data); + *((struct super_block *) &sb) = + *((struct super_block *) bh->b_data); brelse(bh); - nblocks = s.s_nzones << s.s_log_zone_size; - if (s.s_magic != MINIX_SUPER_MAGIC && - s.s_magic != MINIX_SUPER_MAGIC2) { + + + /* Try Minix */ + nblocks = -1; + if (minixsb->s_magic == MINIX_SUPER_MAGIC || + minixsb->s_magic == MINIX_SUPER_MAGIC2) { + printk("RAMDISK: Minix filesystem found at block %d\n", + block); + nblocks = minixsb->s_nzones << minixsb->s_log_zone_size; + } + + /* Try ext2 */ + if (nblocks == -1 && (ext2sb->s_magic == + EXT2_PRE_02B_MAGIC || + ext2sb->s_magic == EXT2_SUPER_MAGIC)) + { + printk("RAMDISK: Ext2 filesystem found at block %d\n", + block); + nblocks = ext2sb->s_blocks_count; + } + + if (nblocks == -1) + { printk("RAMDISK: trying old-style RAM image.\n"); continue; } diff --git a/drivers/char/ChangeLog b/drivers/char/ChangeLog index de3f15da0d5e..5f6c75a81898 100644 --- a/drivers/char/ChangeLog +++ b/drivers/char/ChangeLog @@ -1,3 +1,22 @@ +Mon Oct 24 23:36:21 1994 Theodore Y. Ts'o (tytso@rt-11) + + * serial.c (rs_close): Add a timeout to the transmitter flush + loop; this is just a sanity check in case we have flakey + (or non-existent-but-configured-by-the-user) hardware. + +Fri Oct 21 09:37:23 1994 Theodore Y. Ts'o (tytso@rt-11) + + * tty_io.c (tty_fasync): When asyncronous I/O is enabled, if the + process or process group has not be specified yet, set it + to be the tty's process group, or if that is not yet set, + to the current process's pid. + +Thu Oct 20 23:17:28 1994 Theodore Y. Ts'o (tytso@rt-11) + + * n_tty.c (n_tty_receive_room): If we are doing input + canonicalization, let as many characters through as + possible, so that the excess characters can be "beeped". + Tue Oct 18 10:02:43 1994 Theodore Y. Ts'o (tytso@rt-11) * serial.c (rs_start): Removed an incorrect '!' that was diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 11cb0f05c140..9f9f1e0a69af 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -584,6 +584,14 @@ static int n_tty_receive_room(struct tty_struct *tty) { int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; + /* + * If we are doing input canonicalization, let as many + * characters through as possible, so that the excess + * characters can be "beeped". + */ + if (L_ICANON(tty)) + return N_TTY_BUF_SIZE; + if (left > 0) return left; return 0; diff --git a/drivers/char/serial.c b/drivers/char/serial.c index 2ec01782efca..10cc7e31ce2c 100644 --- a/drivers/char/serial.c +++ b/drivers/char/serial.c @@ -1735,6 +1735,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) { struct async_struct * info = (struct async_struct *)tty->driver_data; unsigned long flags; + unsigned long timeout; if (!info || serial_paranoia_check(info, tty->device, "rs_close")) return; @@ -1786,10 +1787,13 @@ static void rs_close(struct tty_struct *tty, struct file * filp) * has completely drained; this is especially * important if there is a transmit FIFO! */ + timeout = jiffies+HZ; while (!(serial_inp(info, UART_LSR) & UART_LSR_TEMT)) { current->state = TASK_INTERRUPTIBLE; current->timeout = jiffies + info->timeout; schedule(); + if (jiffies > timeout) + break; } } shutdown(info); diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index d79e45124938..7f8dfe0a7409 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -1175,6 +1175,12 @@ static int tty_fasync(struct inode * inode, struct file * filp, int on) tty->fasync = fa; if (!tty->read_wait) tty->minimum_to_wake = 1; + if (filp->f_owner == 0) { + if (tty->pgrp) + filp->f_owner = -tty->pgrp; + else + filp->f_owner = current->pid; + } } else { if (!fa) return 0; diff --git a/fs/ChangeLog b/fs/ChangeLog new file mode 100644 index 000000000000..056d07a8637e --- /dev/null +++ b/fs/ChangeLog @@ -0,0 +1,10 @@ +Mon Oct 24 23:27:42 1994 Theodore Y. Ts'o (tytso@rt-11) + + * fcntl.c (sys_fcntl): Liberalize security checks which Alan Cox + put in. + +Thu Oct 20 23:44:22 1994 Theodore Y. Ts'o (tytso@rt-11) + + * fcntl.c (sys_fcntl): Add more of a security check to the + F_SETOWN fcntl(). + diff --git a/fs/ext2/CHANGES b/fs/ext2/CHANGES index f324090af617..b1ed67b41954 100644 --- a/fs/ext2/CHANGES +++ b/fs/ext2/CHANGES @@ -1,5 +1,9 @@ Changes from version 0.5 to version 0.5a ======================================== + - Some cleanups in the error messages (some versions of syslog contain + a bug which truncates an error message if it contains '\n'). + - Check that no data can be written to a file past the 2GB limit. + - The famous readdir() bug has been fixed by Stephen Tweedie. - Added a revision level in the superblock. - Full support for O_SYNC flag of the open system call. - New mount options: `bsddf' and `minixdf'. `bsddf' causes ext2fs diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 0b09426af102..f1746d7b76a5 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -44,7 +44,7 @@ static struct ext2_group_desc * get_group_desc (struct super_block * sb, if (block_group >= sb->u.ext2_sb.s_groups_count) ext2_panic (sb, "get_group_desc", - "block_group >= groups_count\n" + "block_group >= groups_count - " "block_group = %d, groups_count = %lu", block_group, sb->u.ext2_sb.s_groups_count); @@ -52,7 +52,7 @@ static struct ext2_group_desc * get_group_desc (struct super_block * sb, desc = block_group % EXT2_DESC_PER_BLOCK(sb); if (!sb->u.ext2_sb.s_group_desc[group_desc]) ext2_panic (sb, "get_group_desc", - "Group descriptor not loaded\n" + "Group descriptor not loaded - " "block_group = %d, group_desc = %lu, desc = %lu", block_group, group_desc, desc); gdp = (struct ext2_group_desc *) @@ -73,7 +73,7 @@ static void read_block_bitmap (struct super_block * sb, bh = bread (sb->s_dev, gdp->bg_block_bitmap, sb->s_blocksize); if (!bh) ext2_panic (sb, "read_block_bitmap", - "Cannot read block bitmap\n" + "Cannot read block bitmap - " "block_group = %d, block_bitmap = %lu", block_group, gdp->bg_block_bitmap); sb->u.ext2_sb.s_block_bitmap_number[bitmap_nr] = block_group; @@ -100,7 +100,7 @@ static int load__block_bitmap (struct super_block * sb, if (block_group >= sb->u.ext2_sb.s_groups_count) ext2_panic (sb, "load_block_bitmap", - "block_group >= groups_count\n" + "block_group >= groups_count - " "block_group = %d, groups_count = %lu", block_group, sb->u.ext2_sb.s_groups_count); @@ -185,7 +185,7 @@ void ext2_free_blocks (struct super_block * sb, unsigned long block, if (block < es->s_first_data_block || (block + count) > es->s_blocks_count) { ext2_error (sb, "ext2_free_blocks", - "Freeing blocks not in datazone\n" + "Freeing blocks not in datazone - " "block = %lu, count = %lu", block, count); unlock_super (sb); return; @@ -198,7 +198,7 @@ void ext2_free_blocks (struct super_block * sb, unsigned long block, bit = (block - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb); if (bit + count > EXT2_BLOCKS_PER_GROUP(sb)) ext2_panic (sb, "ext2_free_blocks", - "Freeing blocks across group boundary\n" + "Freeing blocks across group boundary - " "Block = %lu, count = %lu", block, count); bitmap_nr = load_block_bitmap (sb, block_group); @@ -213,7 +213,7 @@ void ext2_free_blocks (struct super_block * sb, unsigned long block, in_range (block + count - 1, gdp->bg_inode_table, sb->u.ext2_sb.s_itb_per_group))) ext2_panic (sb, "ext2_free_blocks", - "Freeing blocks in system zones\n" + "Freeing blocks in system zones - " "Block = %lu, count = %lu", block, count); @@ -404,7 +404,7 @@ got_block: tmp == gdp->bg_inode_bitmap || in_range (tmp, gdp->bg_inode_table, sb->u.ext2_sb.s_itb_per_group))) ext2_panic (sb, "ext2_new_block", - "Allocating block in system zone\n" + "Allocating block in system zone - " "block = %u", tmp); if (set_bit (j, bh->b_data)) { @@ -445,7 +445,7 @@ got_block: if (j >= es->s_blocks_count) { ext2_error (sb, "ext2_new_block", - "block >= blocks count\n" + "block >= blocks count - " "block_group = %d, block=%d", i, j); unlock_super (sb); return 0; diff --git a/fs/ext2/file.c b/fs/ext2/file.c index b615c585a31e..20628b349b08 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -230,7 +230,9 @@ static int ext2_file_read (struct inode * inode, struct file * filp, static int ext2_file_write (struct inode * inode, struct file * filp, char * buf, int count) { - off_t pos; + const loff_t two_gb = 2147483647; + loff_t pos; + off_t pos2; int written, c; struct buffer_head * bh, *bufferlist[NBUF]; char * p; @@ -251,7 +253,7 @@ static int ext2_file_write (struct inode * inode, struct file * filp, return -ENOSPC; if (!S_ISREG(inode->i_mode)) { - ext2_warning (sb, "ext2_file_write", "mode = %07o\n", + ext2_warning (sb, "ext2_file_write", "mode = %07o", inode->i_mode); return -EINVAL; } @@ -260,6 +262,7 @@ static int ext2_file_write (struct inode * inode, struct file * filp, pos = inode->i_size; else pos = filp->f_pos; + pos2 = (off_t) pos; /* * If a file has been opened in synchronous mode, we have to ensure * that meta-data will also be written synchronously. Thus, we @@ -270,13 +273,18 @@ static int ext2_file_write (struct inode * inode, struct file * filp, inode->u.ext2_i.i_osync++; written = 0; while (written < count) { - bh = ext2_getblk (inode, pos / sb->s_blocksize, 1, &err); + if (pos > two_gb) { + if (!written) + written = -EFBIG; + break; + } + bh = ext2_getblk (inode, pos2 / sb->s_blocksize, 1, &err); if (!bh) { if (!written) written = err; break; } - c = sb->s_blocksize - (pos % sb->s_blocksize); + c = sb->s_blocksize - (pos2 % sb->s_blocksize); if (c > count-written) c = count - written; if (c != sb->s_blocksize && !bh->b_uptodate) { @@ -289,7 +297,8 @@ static int ext2_file_write (struct inode * inode, struct file * filp, break; } } - p = (pos % sb->s_blocksize) + bh->b_data; + p = (pos2 % sb->s_blocksize) + bh->b_data; + pos2 += c; pos += c; written += c; memcpy_fromfs (p, buf, c); diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 65cb77284356..69c9e22240b1 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -43,7 +43,7 @@ static struct ext2_group_desc * get_group_desc (struct super_block * sb, if (block_group >= sb->u.ext2_sb.s_groups_count) ext2_panic (sb, "get_group_desc", - "block_group >= groups_count\n" + "block_group >= groups_count - " "block_group = %d, groups_count = %lu", block_group, sb->u.ext2_sb.s_groups_count); @@ -51,7 +51,7 @@ static struct ext2_group_desc * get_group_desc (struct super_block * sb, desc = block_group % EXT2_DESC_PER_BLOCK(sb); if (!sb->u.ext2_sb.s_group_desc[group_desc]) ext2_panic (sb, "get_group_desc", - "Group descriptor not loaded\n" + "Group descriptor not loaded - " "block_group = %d, group_desc = %lu, desc = %lu", block_group, group_desc, desc); gdp = (struct ext2_group_desc *) @@ -71,7 +71,8 @@ static void read_inode_bitmap (struct super_block * sb, gdp = get_group_desc (sb, block_group, NULL); bh = bread (sb->s_dev, gdp->bg_inode_bitmap, sb->s_blocksize); if (!bh) - ext2_panic (sb, "read_inode_bitmap", "Cannot read inode bitmap\n" + ext2_panic (sb, "read_inode_bitmap", + "Cannot read inode bitmap - " "block_group = %lu, inode_bitmap = %lu", block_group, gdp->bg_inode_bitmap); sb->u.ext2_sb.s_inode_bitmap_number[bitmap_nr] = block_group; @@ -98,7 +99,7 @@ static int load_inode_bitmap (struct super_block * sb, if (block_group >= sb->u.ext2_sb.s_groups_count) ext2_panic (sb, "load_inode_bitmap", - "block_group >= groups_count\n" + "block_group >= groups_count - " "block_group = %d, groups_count = %lu", block_group, sb->u.ext2_sb.s_groups_count); if (sb->u.ext2_sb.s_loaded_inode_bitmaps > 0 && @@ -167,7 +168,7 @@ static void set_inode_dtime (struct inode * inode, bh = bread (inode->i_sb->s_dev, inode_block, inode->i_sb->s_blocksize); if (!bh) ext2_panic (inode->i_sb, "set_inode_dtime", - "Cannot load inode table block\n" + "Cannot load inode table block - " "inode=%lu, inode_block=%lu", inode->i_ino, inode_block); raw_inode = ((struct ext2_inode *) bh->b_data) + @@ -275,7 +276,7 @@ static void inc_inode_version (struct inode * inode, bh = bread (inode->i_sb->s_dev, inode_block, inode->i_sb->s_blocksize); if (!bh) { ext2_error (inode->i_sb, "inc_inode_version", - "Cannot load inode table block" + "Cannot load inode table block - " "inode=%lu, inode_block=%lu\n", inode->i_ino, inode_block); inode->u.ext2_i.i_version = 1; @@ -431,7 +432,7 @@ repeat: j += i * EXT2_INODES_PER_GROUP(sb) + 1; if (j < EXT2_FIRST_INO || j > es->s_inodes_count) { ext2_error (sb, "ext2_new_inode", - "reserved inode or inode > inodes count\n" + "reserved inode or inode > inodes count - " "block_group = %d,inode=%d", i, j); unlock_super (sb); iput (inode); @@ -464,6 +465,8 @@ repeat: inode->i_blocks = 0; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->u.ext2_i.i_flags = dir->u.ext2_i.i_flags; + if (S_ISLNK(mode)) + inode->u.ext2_i.i_flags &= ~(EXT2_IMMUTABLE_FL | EXT2_APPEND_FL); inode->u.ext2_i.i_faddr = 0; inode->u.ext2_i.i_frag_no = 0; inode->u.ext2_i.i_frag_size = 0; diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index d71d86a6c67d..633c33e4f043 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -515,7 +515,7 @@ void ext2_read_inode (struct inode * inode) / EXT2_INODES_PER_BLOCK(inode->i_sb)); if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize))) ext2_panic (inode->i_sb, "ext2_read_inode", - "unable to read i-node block\n" + "unable to read i-node block - " "inode=%lu, block=%lu", inode->i_ino, block); raw_inode = ((struct ext2_inode *) bh->b_data) + (inode->i_ino - 1) % EXT2_INODES_PER_BLOCK(inode->i_sb); @@ -606,7 +606,7 @@ static struct buffer_head * ext2_update_inode (struct inode * inode) / EXT2_INODES_PER_BLOCK(inode->i_sb)); if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize))) ext2_panic (inode->i_sb, "ext2_write_inode", - "unable to read i-node block\n" + "unable to read i-node block - " "inode=%lu, block=%lu", inode->i_ino, block); raw_inode = ((struct ext2_inode *)bh->b_data) + (inode->i_ino - 1) % EXT2_INODES_PER_BLOCK(inode->i_sb); diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 188b29daaba5..447968ef074a 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c @@ -33,10 +33,9 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, /* * Only the super-user can change the IMMUTABLE flag */ - if (((flags & EXT2_IMMUTABLE_FL) && - !(inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL)) || - (!(flags & EXT2_IMMUTABLE_FL) && - (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL))) { + if ((flags & EXT2_IMMUTABLE_FL) ^ + (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL)) { + /* This test looks nicer. Thanks to Pauline Middelink */ if (!fsuser()) return -EPERM; } else diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 003eef185fa9..987499115e32 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -271,6 +271,11 @@ static int parse_options (char * options, unsigned long * sb_block, static void ext2_setup_super (struct super_block * sb, struct ext2_super_block * es) { + if (es->s_rev_level > EXT2_CURRENT_REV) { + printk ("EXT2-fs warning: revision level too high, " + "forcing read/only mode\n"); + sb->s_flags |= MS_RDONLY; + } if (!(sb->s_flags & MS_RDONLY)) { if (!(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS)) printk ("EXT2-fs warning: mounting unchecked fs, " diff --git a/fs/fcntl.c b/fs/fcntl.c index 0a64992a3f12..06e04f7c0620 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -66,6 +66,8 @@ asmlinkage int sys_dup(unsigned int fildes) asmlinkage int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) { struct file * filp; + struct task_struct *p; + int task_found = 0; if (fd >= NR_OPEN || !(filp = current->files->fd[fd])) return -EBADF; @@ -116,22 +118,45 @@ asmlinkage int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) return filp->f_owner; case F_SETOWN: /* - * Add the security checks - AC. Without this there is a massive - * Linux security hole here - consider what happens if you do - * something like + * Add the security checks - AC. Without + * this there is a massive Linux security + * hole here - consider what happens if + * you do something like + * * fcntl(0,F_SETOWN,some_root_process); * getchar(); + * * and input a line! + * + * BTW: Don't try this for fun. Several Unix + * systems I tried this on fall for the + * trick! + * + * I had to fix this botch job as Linux + * kill_fasync asserts priv making it a + * free all user process killer! * - * BTW: Don't try this for fun. Several Unix systems I tried this on - * fall for the trick! - * - * I had to fix this botch job as Linux kill_fasync asserts - * priv making it a free all user process killer! + * Changed to make the security checks more + * liberal. -- TYT */ - if(!suser() && current->pgrp != -arg && - current->pid != arg) - return -EPERM; + if (current->pgrp == -arg || current->pid != arg) + goto fasync_ok; + + for_each_task(p) { + if ((p->pid == arg) || (p->pid == -arg) || + (p->pgrp == -arg)) { + task_found++; + if ((p->session != current->session) && + (p->uid != current->uid) && + (p->euid != current->euid) && + !suser()) + return -EPERM; + break; + } + } + if ((task_found == 0) && !suser()) + return -EINVAL; + fasync_ok: filp->f_owner = arg; if (S_ISSOCK (filp->f_inode->i_mode)) sock_fcntl (filp, F_SETOWN, arg); diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c index 8ff7728eea20..7f13ac8aaa03 100644 --- a/fs/isofs/namei.c +++ b/fs/isofs/namei.c @@ -32,7 +32,7 @@ static int isofs_match(int len,const char * name, char * compare, int dlen) /* check special "." and ".." files */ if (dlen == 1) { /* "." */ - if (compare[0] = 0) { + if (compare[0] == 0) { if (!len) return 1; compare = "."; diff --git a/fs/umsdos/file.c b/fs/umsdos/file.c index 8d97bd6884db..69b027c95202 100644 --- a/fs/umsdos/file.c +++ b/fs/umsdos/file.c @@ -78,7 +78,7 @@ struct file_operations umsdos_file_operations = { msdos_mmap, /* mmap */ NULL, /* no special open is needed */ NULL, /* release */ - NULL /* fsync */ + file_fsync /* fsync */ }; struct inode_operations umsdos_file_inode_operations = { diff --git a/fs/umsdos/namei.c b/fs/umsdos/namei.c index 2c2f55f059ac..f03e60cf3806 100644 --- a/fs/umsdos/namei.c +++ b/fs/umsdos/namei.c @@ -617,8 +617,10 @@ int UMSDOS_link ( iput (olddir); } if (ret == 0){ + struct iattr newattrs; oldinode->i_nlink++; - ret = UMSDOS_notify_change (0,NULL,oldinode); + newattrs.ia_valid = 0; + ret = UMSDOS_notify_change(oldinode, &newattrs); } iput (oldinode); iput (dir); @@ -923,7 +925,9 @@ int UMSDOS_unlink ( iput (hdir); } }else{ - ret = UMSDOS_notify_change (0,NULL,inode); + struct iattr newattrs; + newattrs.ia_valid = 0; + ret = UMSDOS_notify_change (inode, &newattrs); } iput (inode); } diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h index fa436058e8d4..8fb3fb095fad 100644 --- a/include/asm-alpha/bitops.h +++ b/include/asm-alpha/bitops.h @@ -79,7 +79,80 @@ extern __inline__ unsigned long change_bit(unsigned long nr, void * addr) extern __inline__ unsigned long test_bit(int nr, void * addr) { - return (1UL << (nr & 63)) & ((unsigned long *) addr)[nr >> 6]; + return 1UL & (((unsigned long *) addr)[nr >> 6] >> (nr & 63)); } +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check agains ~0UL first.. + * + * This uses the cmpbge insn to check which byte contains the zero. + * I don't know if that's actually a good idea, but it's fun and the + * resulting LBS tests should be natural on the alpha.. Besides, I'm + * just teaching myself the asm of the alpha anyway. + */ +extern inline unsigned long ffz(unsigned long word) +{ + unsigned long result = 0; + unsigned long tmp; + + __asm__("cmpbge %1,%0,%0" + :"=r" (tmp) + :"r" (word), "0" (~0UL)); + while (tmp & 1) { + word >>= 8; + tmp >>= 1; + result += 8; + } + while (word & 1) { + result++; + word >>= 1; + } + return result; +} + +/* + * Find next zero bit in a bitmap reasonably efficiently.. + */ +extern inline unsigned long find_next_zero_bit(void * addr, unsigned long size, unsigned long offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 6); + unsigned long result = offset & ~63UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 63UL; + if (offset) { + tmp = *(p++); + tmp |= ~0UL >> (64-offset); + if (size < 64) + goto found_first; + if (~tmp) + goto found_middle; + size -= 64; + result += 64; + } + while (size & ~63UL) { + if (~(tmp = *(p++))) + goto found_middle; + result += 64; + size -= 64; + } + if (!size) + return result; + tmp = *p; +found_first: + tmp |= ~0UL << size; +found_middle: + return result + ffz(tmp); +} + +/* + * The optimizer actually does good code for this case.. + */ +#define find_first_zero_bit(addr, size) \ + find_next_zero_bit((addr), (size), 0) + #endif /* _ALPHA_BITOPS_H */ diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h index 982b666452c7..09cedb036bf3 100644 --- a/include/linux/ext2_fs.h +++ b/include/linux/ext2_fs.h @@ -47,7 +47,7 @@ /* * The second extended file system version */ -#define EXT2FS_DATE "94/08/24" +#define EXT2FS_DATE "94/10/23" #define EXT2FS_VERSION "0.5a" /* diff --git a/net/inet/README b/net/inet/README index 202ec88a9ac5..005795df038a 100644 --- a/net/inet/README +++ b/net/inet/README @@ -14,3 +14,8 @@ o Removed some surplus uncommented code from tcp.c o Fixed protocol violation during closedown in tcp.c [Still not got the window < MSS bug fix included] +Fixes for 1.1.58 + +o non blocking connect fail gets the error code right. +o select() not reporting read ok after an urgent read fixed. + diff --git a/net/inet/af_inet.c b/net/inet/af_inet.c index deee463fa77e..7638ec9e44c7 100644 --- a/net/inet/af_inet.c +++ b/net/inet/af_inet.c @@ -888,7 +888,11 @@ static int inet_connect(struct socket *sock, struct sockaddr * uaddr, if (sk->state > TCP_FIN_WAIT2 && sock->state==SS_CONNECTING) { sock->state=SS_UNCONNECTED; - return -ETIMEDOUT; + cli(); + err=sk->err; + sk->err=0; + sti(); + return -err; } if (sk->state != TCP_ESTABLISHED &&(flags & O_NONBLOCK)) diff --git a/net/inet/tcp.c b/net/inet/tcp.c index 1ff1f3c9fcdb..87a5cb50b2c8 100644 --- a/net/inet/tcp.c +++ b/net/inet/tcp.c @@ -85,6 +85,7 @@ * Alan Cox : BSD accept semantics. * Alan Cox : Reset on closedown bug. * Peter De Schrijver : ENOTCONN check missing in tcp_sendto(). + * Michael Pall : Handle select() after URG properly in all cases. * * * To Fix: @@ -1410,15 +1411,29 @@ static int tcp_read_urg(struct sock * sk, int nonblock, { if (sk->urginline || !sk->urg_data || sk->urg_data == URG_READ) return -EINVAL; + sk->inuse=1; if (sk->urg_data & URG_VALID) { char c = sk->urg_data; if (!(flags & MSG_PEEK)) + { + /* Skip over urgent data, so tcp_readable() returns + something again. This in turn makes tcp_select() + happy. Mike */ + if (sk->copied_seq + 1 == sk->urg_seq) + { + wake_up_interruptible(sk->sleep); + sk->copied_seq++; + } sk->urg_data = URG_READ; + } put_fs_byte(c, to); + release_sock(sk); return 1; } + release_sock(sk); + if (sk->err) { int tmp = -sk->err; -- 2.39.5