diff -u --recursive --new-file v1.1.56/linux/Makefile linux/Makefile --- v1.1.56/linux/Makefile Sun Oct 23 13:30:11 1994 +++ linux/Makefile Sat Oct 22 15:17:25 1994 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 1 -SUBLEVEL = 56 +SUBLEVEL = 57 ARCH = i386 diff -u --recursive --new-file v1.1.56/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v1.1.56/linux/drivers/block/floppy.c Fri Oct 21 10:15:03 1994 +++ linux/drivers/block/floppy.c Sun Oct 23 13:04:29 1994 @@ -314,17 +314,17 @@ { 2988,18,2,83,0,0x25,0x00,0xDF,0x02,"h1494" }, /* 18 1.49MB 5.25" */ { 3486,21,2,83,0,0x25,0x00,0xDF,0x0C,"H1743" }, /* 19 1.74 MB 3.5" */ - { 1760,11,2,80,0,0x1C,0x09,0xCF,0x6C,"h880" }, /* 20 880KB 5.25" */ - { 2080,13,2,80,0,0x1C,0x01,0xCF,0x6C,"D1040" }, /* 21 1.04MB 3.5" */ - { 2240,14,2,80,0,0x1C,0x19,0xCF,0x6C,"D1120" }, /* 22 1.12MB 3.5" */ + { 1760,11,2,80,0,0x1C,0x09,0xCF,0x00,"h880" }, /* 20 880KB 5.25" */ + { 2080,13,2,80,0,0x1C,0x01,0xCF,0x00,"D1040" }, /* 21 1.04MB 3.5" */ + { 2240,14,2,80,0,0x1C,0x19,0xCF,0x00,"D1120" }, /* 22 1.12MB 3.5" */ { 3200,20,2,80,0,0x1C,0x20,0xCF,0x2C,"h1600" }, /* 23 1.6MB 5.25" */ { 3520,22,2,80,0,0x1C,0x08,0xCF,0x2e,"H1760" }, /* 24 1.76MB 3.5" */ - { 3840,24,2,80,0,0x1C,0x20,0xCF,0x6C,"H1920" }, /* 25 1.92MB 3.5" */ - { 6400,40,2,80,0,0x25,0x5B,0xCF,0x6C,"E3200" }, /* 26 3.20MB 3.5" */ - { 7040,44,2,80,0,0x25,0x5B,0xCF,0x6C,"E3520" }, /* 27 3.52MB 3.5" */ - { 7680,48,2,80,0,0x25,0x63,0xCF,0x6C,"E3840" }, /* 28 3.84MB 3.5" */ + { 3840,24,2,80,0,0x1C,0x20,0xCF,0x00,"H1920" }, /* 25 1.92MB 3.5" */ + { 6400,40,2,80,0,0x25,0x5B,0xCF,0x00,"E3200" }, /* 26 3.20MB 3.5" */ + { 7040,44,2,80,0,0x25,0x5B,0xCF,0x00,"E3520" }, /* 27 3.52MB 3.5" */ + { 7680,48,2,80,0,0x25,0x63,0xCF,0x00,"E3840" }, /* 28 3.84MB 3.5" */ - { 3680,23,2,80,0,0x1C,0x10,0xCF,0x6C,"H1840" }, /* 29 1.84MB 3.5" */ + { 3680,23,2,80,0,0x1C,0x10,0xCF,0x00,"H1840" }, /* 29 1.84MB 3.5" */ { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800" }, /* 30 800KB 3.5" */ { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5" */ }; @@ -499,6 +499,9 @@ static int disk_change(int drive) { + if(jiffies < DP->select_delay + DRS->select_date) + udelay(20000); + if(inb_p(FD_DIR) & 0x80){ UDRS->flags |= FD_VERIFY; /* verify write protection */ @@ -526,12 +529,12 @@ } } - +static int locked=0; static int set_dor(int fdc, char mask, char data) { register unsigned char drive, unit, newdor,olddor; - cli(); + locked=1; olddor = FDCS->dor; newdor = (olddor & mask) | data; if ( newdor != olddor ){ @@ -542,7 +545,7 @@ FDCS->dor = newdor; outb_p( newdor, FD_DOR); } - sti(); + locked=0; return olddor; } @@ -636,7 +639,10 @@ { unsigned char mask = ~(0x10 << UNIT(nr)); - set_dor( FDC(nr), mask, 0 ); + if(locked) + floppy_off(nr); + else + set_dor( FDC(nr), mask, 0 ); } static struct timer_list motor_off_timer[N_DRIVE] = { @@ -657,6 +663,10 @@ static void floppy_off(unsigned int nr) { unsigned long volatile delta; + register int fdc=FDC(nr); + + if( !(FDCS->dor & ( 0x10 << UNIT(nr)))) + return; del_timer(motor_off_timer+nr); @@ -1175,6 +1185,7 @@ ) DRS->flags &= ~FD_DISK_NEWCHANGE; /* effective seek */ DRS->track = ST1; + DRS->select_date = jiffies; seek_floppy(); } @@ -1466,7 +1477,8 @@ mask = 0xfc; data = UNIT(current_drive); - if ( (FDCS->dor & 0x03) != UNIT(current_drive) ) + if ( (FDCS->dor & 0x03) != UNIT(current_drive) || + !(FDCS->dor & ( 0x10 << UNIT(current_drive) ) )) /* notes select time if floppy is not yet selected */ DRS->select_date = jiffies; @@ -1489,9 +1501,7 @@ if( raw_cmd.flags & FD_RAW_NO_MOTOR) return; - if(disk_change(current_drive)) - twaddle(); /* this clears the dcl on certain drive/controller - * combinations */ + disk_change(current_drive); return; } @@ -1929,17 +1939,12 @@ size = CURRENT->current_nr_sectors << 9; bh = CURRENT->bh; -#ifdef SANITY - if ( !bh ){ - DPRINT("null request in buffer_chain_size\n"); - return size >> 9; - } -#endif - - bh = bh->b_reqnext; - while ( bh && bh->b_data == base + size ){ - size += bh->b_size; + if(bh){ bh = bh->b_reqnext; + while ( bh && bh->b_data == base + size ){ + size += bh->b_size; + bh = bh->b_reqnext; + } } return size >> 9; } @@ -2008,10 +2013,6 @@ if ( size > remaining ) size = remaining; #ifdef SANITY - if (!bh){ - DPRINT("bh=null in copy buffer before copy\n"); - break; - } if (dma_buffer + size > floppy_track_buffer + (max_buffer_sectors << 10) || dma_buffer < floppy_track_buffer ){ @@ -2355,8 +2356,6 @@ continue; } - if ( DRS->flags & FD_NEED_TWADDLE ) - twaddle(); floppy_tq.routine = (void *)(void *) floppy_start; queue_task(&floppy_tq, &tq_timer); #ifdef DEBUGT @@ -2506,7 +2505,7 @@ current_addr = floppy_track_buffer; cont = &raw_cmd_cont; CALL(ret=wait_til_done(floppy_start,1)); - if( inb_p(FD_DIR) & 0x80 ) + if( disk_change(current_drive) ) raw_cmd.flags |= FD_RAW_DISK_CHANGE; else raw_cmd.flags &= ~FD_RAW_DISK_CHANGE; @@ -3123,12 +3122,21 @@ static int floppy_grab_irq_and_dma(void) { + int i; cli(); if (usage_count++){ sti(); return 0; } sti(); + + for(i=0; i< N_FDC; i++){ + fdc = i; + reset_fdc_info(1); + outb_p( FDCS->dor, FD_DOR); + } + set_dor(0, ~0, 8); /* avoid immediate interrupt */ + if (request_irq(FLOPPY_IRQ, floppy_interrupt, SA_INTERRUPT, "floppy")) { DPRINT1("Unable to grab IRQ%d for the floppy driver\n", FLOPPY_IRQ); @@ -3146,6 +3154,7 @@ static void floppy_release_irq_and_dma(void) { + int i; cli(); if (--usage_count){ sti(); @@ -3156,10 +3165,7 @@ free_dma(FLOPPY_DMA); disable_irq(FLOPPY_IRQ); free_irq(FLOPPY_IRQ); -#ifdef HAVE_2_CONTROLLERS - /* switch on first controller. - * This saves us trouble on the next reboot. */ - set_dor(0, ~0, 8 ); - set_dor(1, ~8, 0 ); -#endif + /* switch off dma gates */ + for(i=0; i< N_FDC; i++) + set_dor(i, ~8, 0); } diff -u --recursive --new-file v1.1.56/linux/drivers/block/hd.c linux/drivers/block/hd.c --- v1.1.56/linux/drivers/block/hd.c Fri Oct 21 10:15:03 1994 +++ linux/drivers/block/hd.c Mon Oct 24 08:39:01 1994 @@ -305,7 +305,8 @@ if (unmask_intr[dev]) sti(); if (stat & (BUSY_STAT|ERR_STAT)) { - printk (" hd%c: non-IDE device, CHS=%d/%d/%d\n", dev+'a', + printk (" hd%c: non-IDE device, %dMB, CHS=%d/%d/%d\n", dev+'a', + hd_info[dev].cyl*hd_info[dev].head*hd_info[dev].sect / 2048, hd_info[dev].cyl, hd_info[dev].head, hd_info[dev].sect); if (id != NULL) { hd_ident_info[dev] = NULL; @@ -796,6 +797,7 @@ { struct hd_geometry *loc = (struct hd_geometry *) arg; int dev, err; + unsigned long flags; if ((!inode) || (!inode->i_rdev)) return -EINVAL; @@ -845,17 +847,22 @@ case BLKRRPART: /* Re-read partition tables */ return revalidate_hddisk(inode->i_rdev, 1); - case HDIO_SETUNMASKINTR: - if (!suser()) return -EACCES; + case HDIO_SETUNMASKINTR: /* obsolete */ + printk("hd: obsolete syscall: HDIO_SETUNMASKINTR\n"); if (!arg) return -EINVAL; - if (MINOR(inode->i_rdev) & 0x3F) return -EINVAL; err = verify_area(VERIFY_READ, (long *) arg, sizeof(long)); if (err) return err; - unmask_intr[dev] = get_fs_long((long *) arg); + arg = get_fs_long((long *) arg); + /* drop into HDIO_SET_UNMASKINTR */ + case HDIO_SET_UNMASKINTR: + if (!suser()) return -EACCES; + if ((arg > 1) || (MINOR(inode->i_rdev) & 0x3F)) + return -EINVAL; + unmask_intr[dev] = arg; return 0; - case HDIO_GETUNMASKINTR: + case HDIO_GET_UNMASKINTR: if (!arg) return -EINVAL; err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long)); if (err) @@ -863,7 +870,7 @@ put_fs_long(unmask_intr[dev], (long *) arg); return 0; - case HDIO_GETMULTCOUNT: + case HDIO_GET_MULTCOUNT: if (!arg) return -EINVAL; err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long)); if (err) @@ -871,16 +878,17 @@ put_fs_long(mult_count[dev], (long *) arg); return 0; - case HDIO_SETMULTCOUNT: - { - unsigned long flags; - if (!suser()) return -EACCES; + case HDIO_SETMULTCOUNT: /* obsolete */ + printk("hd: obsolete syscall: HDIO_SETMULTCOUNT\n"); if (!arg) return -EINVAL; - if (MINOR(inode->i_rdev) & 0x3F) return -EINVAL; err = verify_area(VERIFY_READ, (long *) arg, sizeof(long)); if (err) return err; arg = get_fs_long((long *) arg); + /* drop into HDIO_SET_MULTCOUNT */ + case HDIO_SET_MULTCOUNT: + if (!suser()) return -EACCES; + if (MINOR(inode->i_rdev) & 0x3F) return -EINVAL; save_flags(flags); cli(); /* a prior request might still be in progress */ if (arg > max_mult[dev]) @@ -895,8 +903,8 @@ } restore_flags(flags); return err; - } - case HDIO_GETIDENTITY: + + case HDIO_GET_IDENTITY: if (!arg) return -EINVAL; if (MINOR(inode->i_rdev) & 0x3F) return -EINVAL; if (hd_ident_info[dev] == NULL) return -ENOMSG; diff -u --recursive --new-file v1.1.56/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v1.1.56/linux/drivers/block/ll_rw_blk.c Sun Oct 23 13:30:11 1994 +++ linux/drivers/block/ll_rw_blk.c Sun Oct 23 13:04:29 1994 @@ -126,7 +126,6 @@ major = MAJOR(dev); minor = MINOR(dev); - if ( major == FLOPPY_MAJOR && floppy_is_wp( minor) ) return 1; if (major < 0 || major >= MAX_BLKDEV) return 0; return ro_bits[major][minor >> 5] & (1 << (minor & 31)); } diff -u --recursive --new-file v1.1.56/linux/fs/buffer.c linux/fs/buffer.c --- v1.1.56/linux/fs/buffer.c Sun Oct 9 12:00:25 1994 +++ linux/fs/buffer.c Sat Oct 22 16:06:53 1994 @@ -1106,11 +1106,6 @@ return try_to_load_aligned(address, dev, b, size); } -#define COPYBLK(size,from,to) \ -__asm__ __volatile__("rep ; movsl": \ - :"c" (((unsigned long) size) >> 2),"S" (from),"D" (to) \ - :"cx","di","si") - /* * bread_page reads four buffers into memory at the desired address. It's * a function of its own, as there is some speed to be got by reading them @@ -1140,7 +1135,7 @@ for (i=0, j=0; jb_uptodate) - COPYBLK(size, (unsigned long) bh[i]->b_data, where); + memcpy((void *) where, bh[i]->b_data, size); brelse(bh[i]); } } diff -u --recursive --new-file v1.1.56/linux/fs/ext/freelists.c linux/fs/ext/freelists.c --- v1.1.56/linux/fs/ext/freelists.c Sun Aug 21 17:48:35 1994 +++ linux/fs/ext/freelists.c Sat Oct 22 16:38:32 1994 @@ -37,13 +37,6 @@ #include #include -#define clear_block(addr) \ -__asm__("cld\n\t" \ - "rep\n\t" \ - "stosl" \ - : \ - :"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di") - void ext_free_block(struct super_block * sb, int block) { struct buffer_head * bh; @@ -133,7 +126,7 @@ printk("new_block: cannot get block"); return 0; } - clear_block(bh->b_data); + memset(bh->b_data, 0, BLOCK_SIZE); bh->b_uptodate = 1; mark_buffer_dirty(bh, 1); brelse(bh); diff -u --recursive --new-file v1.1.56/linux/fs/ext/namei.c linux/fs/ext/namei.c --- v1.1.56/linux/fs/ext/namei.c Sun Aug 21 17:48:35 1994 +++ linux/fs/ext/namei.c Sat Oct 22 16:41:35 1994 @@ -55,23 +55,14 @@ */ static int ext_match(int len,const char * name,struct ext_dir_entry * de) { - register int same; - if (!de || !de->inode || len > EXT_NAME_LEN) return 0; /* "" means "." ---> so paths like "/usr/lib//libc.a" work */ if (!len && (de->name[0]=='.') && (de->name[1]=='\0')) return 1; - if (len < EXT_NAME_LEN && len != de->name_len) + if (len != de->name_len) return 0; - __asm__ __volatile__( - "cld\n\t" - "repe ; cmpsb\n\t" - "setz %%al" - :"=a" (same) - :"0" (0),"S" ((long) name),"D" ((long) de->name),"c" (len) - :"cx","di","si"); - return same; + return !memcmp(name, de->name, len); } /* diff -u --recursive --new-file v1.1.56/linux/fs/inode.c linux/fs/inode.c --- v1.1.56/linux/fs/inode.c Wed Aug 31 10:14:11 1994 +++ linux/fs/inode.c Sun Oct 23 19:21:36 1994 @@ -233,6 +233,59 @@ unlock_inode(inode); } +/* POSIX UID/GID verification for setting inode attributes */ +int inode_change_ok(struct inode *inode, struct iattr *attr) +{ + /* Make sure a caller can chown */ + if ((attr->ia_valid & ATTR_UID) && + (current->fsuid != inode->i_uid || + attr->ia_uid != inode->i_uid) && !fsuser()) + return -EPERM; + + /* Make sure caller can chgrp */ + if ((attr->ia_valid & ATTR_GID) && + (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid) && + !fsuser()) + return -EPERM; + + /* Make sure a caller can chmod */ + if (attr->ia_valid & ATTR_MODE) { + if ((current->fsuid != inode->i_uid) && !fsuser()) + return -EPERM; + /* Also check the setgid bit! */ + if (!fsuser() && !in_group_p((attr->ia_valid & ATTR_GID) ? attr->ia_gid : + inode->i_gid)) + attr->ia_mode &= ~S_ISGID; + } + + return 0; +} + +/* + * Set the appropriate attributes from an attribute structure into + * the inode structure. + */ +void inode_setattr(struct inode *inode, struct iattr *attr) +{ + if (attr->ia_valid & ATTR_UID) + inode->i_uid = attr->ia_uid; + if (attr->ia_valid & ATTR_GID) + inode->i_gid = attr->ia_gid; + if (attr->ia_valid & ATTR_SIZE) + inode->i_size = attr->ia_size; + if (attr->ia_valid & ATTR_ATIME) + inode->i_atime = attr->ia_atime; + if (attr->ia_valid & ATTR_MTIME) + inode->i_mtime = attr->ia_mtime; + if (attr->ia_valid & ATTR_CTIME) + inode->i_ctime = attr->ia_ctime; + if (attr->ia_valid & ATTR_MODE) { + inode->i_mode = attr->ia_mode; + if (!fsuser() && !in_group_p(inode->i_gid)) + inode->i_mode &= ~S_ISGID; + } +} + /* * notify_change is called for inode-changing operations such as * chown, chmod, utime, and truncate. It is guaranteed (unlike @@ -241,11 +294,18 @@ * NFS uses this to get the authentication correct. -- jrs */ -int notify_change(int flags, struct inode * inode) +int notify_change(struct inode * inode, struct iattr *attr) { + int retval; + if (inode->i_sb && inode->i_sb->s_op && - inode->i_sb->s_op->notify_change) - return inode->i_sb->s_op->notify_change(flags, inode); + inode->i_sb->s_op->notify_change) + return inode->i_sb->s_op->notify_change(inode, attr); + + if ((retval = inode_change_ok(inode, attr)) != 0) + return retval; + + inode_setattr(inode, attr); return 0; } diff -u --recursive --new-file v1.1.56/linux/fs/isofs/namei.c linux/fs/isofs/namei.c --- v1.1.56/linux/fs/isofs/namei.c Tue Aug 9 17:20:33 1994 +++ linux/fs/isofs/namei.c Sat Oct 22 16:46:58 1994 @@ -26,33 +26,28 @@ */ static int isofs_match(int len,const char * name, char * compare, int dlen) { - register int same; - - if (!compare) return 0; - /* "" means "." ---> so paths like "/usr/lib//libc.a" work */ - if (!len && (compare[0]==0) && (dlen==1)) - return 1; - - if (compare[0]==0 && dlen==1 && len == 1) - compare = "."; - if (compare[0]==1 && dlen==1 && len == 2) { - compare = ".."; - dlen = 2; - }; + if (!compare) + return 0; + + /* check special "." and ".." files */ + if (dlen == 1) { + /* "." */ + if (compare[0] = 0) { + if (!len) + return 1; + 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; - __asm__ __volatile__( - "cld\n\t" - "repe ; cmpsb\n\t" - "setz %%al" - :"=a" (same) - :"0" (0),"S" ((long) name),"D" ((long) compare),"c" (len) - :"cx","di","si"); - return same; + return !memcmp(name, compare, len); } /* diff -u --recursive --new-file v1.1.56/linux/fs/minix/bitmap.c linux/fs/minix/bitmap.c --- v1.1.56/linux/fs/minix/bitmap.c Mon Aug 15 11:47:10 1994 +++ linux/fs/minix/bitmap.c Sun Oct 23 13:13:17 1994 @@ -14,28 +14,6 @@ #include -#define clear_block(addr) \ -__asm__("cld\n\t" \ - "rep\n\t" \ - "stosl" \ - : \ - :"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di") - -#define find_first_zero(addr) ({ \ -int __res; \ -__asm__("cld\n" \ - "1:\tlodsl\n\t" \ - "notl %%eax\n\t" \ - "bsfl %%eax,%%edx\n\t" \ - "jne 2f\n\t" \ - "addl $32,%%ecx\n\t" \ - "cmpl $8192,%%ecx\n\t" \ - "jl 1b\n\t" \ - "xorl %%edx,%%edx\n" \ - "2:\taddl %%edx,%%ecx" \ - :"=c" (__res):"0" (0),"S" (addr):"ax","dx","si"); \ -__res;}) - static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 }; static unsigned long count_used(struct buffer_head *map[], unsigned numblocks, @@ -110,7 +88,7 @@ j = 8192; for (i=0 ; i<8 ; i++) if ((bh=sb->u.minix_sb.s_zmap[i]) != NULL) - if ((j=find_first_zero(bh->b_data))<8192) + if ((j=find_first_zero_bit(bh->b_data, 8192)) < 8192) break; if (i>=8 || !bh || j>=8192) return 0; @@ -127,7 +105,7 @@ printk("new_block: cannot get block"); return 0; } - clear_block(bh->b_data); + memset(bh->b_data, 0, BLOCK_SIZE); bh->b_uptodate = 1; mark_buffer_dirty(bh, 1); brelse(bh); @@ -193,7 +171,7 @@ j = 8192; for (i=0 ; i<8 ; i++) if ((bh = inode->i_sb->u.minix_sb.s_imap[i]) != NULL) - if ((j=find_first_zero(bh->b_data))<8192) + if ((j=find_first_zero_bit(bh->b_data, 8192)) < 8192) break; if (!bh || j >= 8192) { iput(inode); diff -u --recursive --new-file v1.1.56/linux/fs/minix/dir.c linux/fs/minix/dir.c --- v1.1.56/linux/fs/minix/dir.c Fri Oct 21 10:15:05 1994 +++ linux/fs/minix/dir.c Mon Oct 24 09:12:28 1994 @@ -86,13 +86,13 @@ filp->f_pos += info->s_dirsize; retry: if (de->inode) { + version = inode->i_version; for (i = 0; i < info->s_namelen; i++) if ((c = de->name[i]) != 0) put_fs_byte(c,i+dirent->d_name); else break; if (i) { - version = inode->i_version; put_fs_long(de->inode,&dirent->d_ino); put_fs_byte(0,i+dirent->d_name); put_fs_word(i,&dirent->d_reclen); diff -u --recursive --new-file v1.1.56/linux/fs/minix/namei.c linux/fs/minix/namei.c --- v1.1.56/linux/fs/minix/namei.c Fri Oct 21 10:15:05 1994 +++ linux/fs/minix/namei.c Sat Oct 22 16:37:14 1994 @@ -23,15 +23,11 @@ static inline int namecompare(int len, int maxlen, const char * name, const char * buffer) { - if (len >= maxlen || !buffer[len]) { - unsigned char same; - __asm__("repe ; cmpsb ; setz %0" - :"=q" (same) - :"S" ((long) name),"D" ((long) buffer),"c" (len) - :"cx","di","si"); - return same; - } - return 0; + if (len > maxlen) + return 0; + if (len < maxlen && buffer[len]) + return 0; + return !memcmp(name, buffer, len); } /* diff -u --recursive --new-file v1.1.56/linux/fs/msdos/inode.c linux/fs/msdos/inode.c --- v1.1.56/linux/fs/msdos/inode.c Sat May 7 14:54:08 1994 +++ linux/fs/msdos/inode.c Mon Oct 24 07:43:10 1994 @@ -420,28 +420,34 @@ } -int msdos_notify_change(int flags,struct inode *inode) +int msdos_notify_change(struct inode * inode,struct iattr * attr) { int error; - error = 0; - if ((flags & NOTIFY_UIDGID) && (inode->i_uid != MSDOS_SB(inode->i_sb)-> - fs_uid || inode->i_gid != MSDOS_SB(inode->i_sb)->fs_gid)) { - inode->i_uid = MSDOS_SB(inode->i_sb)->fs_uid; - inode->i_gid = MSDOS_SB(inode->i_sb)->fs_gid; + error = inode_change_ok(inode, attr); + if (error) + return error; + + if (((attr->ia_valid & ATTR_UID) && + (attr->ia_uid != MSDOS_SB(inode->i_sb)->fs_uid)) || + ((attr->ia_valid & ATTR_GID) && + (attr->ia_gid != MSDOS_SB(inode->i_sb)->fs_gid)) || + ((attr->ia_valid & ATTR_MODE) && + (attr->ia_mode & ~MSDOS_VALID_MODE))) error = -EPERM; - } - if (!(flags & NOTIFY_MODE)) + + if (error) return MSDOS_SB(inode->i_sb)->quiet ? 0 : error; - if (inode->i_mode & ~MSDOS_VALID_MODE) { - inode->i_mode &= MSDOS_VALID_MODE; - error = -EPERM; - } + + inode_setattr(inode, attr); + if (IS_NOEXEC(inode) && !S_ISDIR(inode->i_mode)) inode->i_mode &= S_IFMT | S_IRUGO | S_IWUGO; - else inode->i_mode |= S_IXUGO; + else + inode->i_mode |= S_IXUGO; + inode->i_mode = ((inode->i_mode & S_IFMT) | ((((inode->i_mode & S_IRWXU & ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IRUSR) >> 6)*S_IXUGO)) & ~MSDOS_SB(inode->i_sb)->fs_umask; - return MSDOS_SB(inode->i_sb)->quiet ? 0 : error; + return 0; } diff -u --recursive --new-file v1.1.56/linux/fs/namei.c linux/fs/namei.c --- v1.1.56/linux/fs/namei.c Sun Aug 21 17:48:37 1994 +++ linux/fs/namei.c Sun Oct 23 20:55:40 1994 @@ -373,6 +373,7 @@ iput(inode); return -EACCES; } + flag &= ~O_TRUNC; } else { if (IS_RDONLY(inode) && (flag & 2)) { iput(inode); @@ -404,14 +405,18 @@ return -EPERM; } if (flag & O_TRUNC) { - inode->i_size = 0; - if (inode->i_op && inode->i_op->truncate) - inode->i_op->truncate(inode); - if ((error = notify_change(NOTIFY_SIZE, inode))) { - iput(inode); - return error; - } - inode->i_dirt = 1; + struct iattr newattrs; + + newattrs.ia_size = 0; + newattrs.ia_valid = ATTR_SIZE; + if ((error = notify_change(inode, &newattrs))) { + iput(inode); + return error; + } + inode->i_size = 0; + if (inode->i_op && inode->i_op->truncate) + inode->i_op->truncate(inode); + inode->i_dirt = 1; } *res_inode = inode; return 0; diff -u --recursive --new-file v1.1.56/linux/fs/nfs/inode.c linux/fs/nfs/inode.c --- v1.1.56/linux/fs/nfs/inode.c Sat May 7 14:54:08 1994 +++ linux/fs/nfs/inode.c Sun Oct 23 19:35:37 1994 @@ -20,7 +20,7 @@ extern int close_fp(struct file *filp, unsigned int fd); -static int nfs_notify_change(int, struct inode *); +static int nfs_notify_change(struct inode *, struct iattr *); static void nfs_put_inode(struct inode *); static void nfs_put_super(struct super_block *); static void nfs_statfs(struct super_block *, struct statfs *); @@ -193,36 +193,44 @@ return inode; } -int nfs_notify_change(int flags, struct inode *inode) +int nfs_notify_change(struct inode *inode, struct iattr *attr) { struct nfs_sattr sattr; struct nfs_fattr fattr; int error; - if (flags & NOTIFY_MODE) - sattr.mode = inode->i_mode; + if (attr->ia_valid & ATTR_MODE) + sattr.mode = attr->ia_mode; else sattr.mode = (unsigned) -1; - if (flags & NOTIFY_UIDGID) { - sattr.uid = inode->i_uid; - sattr.gid = inode->i_gid; - } + + if (attr->ia_valid & ATTR_UID) + sattr.uid = attr->ia_uid; + else + sattr.uid = (unsigned) -1; + + if (attr->ia_valid & ATTR_GID) + sattr.gid = attr->ia_gid; else - sattr.uid = sattr.gid = (unsigned) -1; - if (flags & NOTIFY_SIZE) - sattr.size = S_ISREG(inode->i_mode) ? inode->i_size : -1; + sattr.gid = (unsigned) -1; + + if (attr->ia_valid & ATTR_SIZE) + sattr.size = S_ISREG(inode->i_mode) ? attr->ia_size : -1; else sattr.size = (unsigned) -1; - if (flags & NOTIFY_TIME) { - sattr.mtime.seconds = inode->i_mtime; + + if (attr->ia_valid & ATTR_MTIME) { + sattr.mtime.seconds = attr->ia_mtime; sattr.mtime.useconds = 0; - sattr.atime.seconds = inode->i_atime; - sattr.atime.useconds = 0; - } - else { + } else sattr.mtime.seconds = sattr.mtime.useconds = (unsigned) -1; + + if (attr->ia_valid & ATTR_ATIME) { + sattr.atime.seconds = attr->ia_atime; + sattr.atime.useconds = 0; + } else sattr.atime.seconds = sattr.atime.useconds = (unsigned) -1; - } + error = nfs_proc_setattr(NFS_SERVER(inode), NFS_FH(inode), &sattr, &fattr); if (!error) @@ -230,4 +238,3 @@ inode->i_dirt = 0; return error; } - diff -u --recursive --new-file v1.1.56/linux/fs/open.c linux/fs/open.c --- v1.1.56/linux/fs/open.c Sun Aug 21 17:48:37 1994 +++ linux/fs/open.c Sun Oct 23 19:19:08 1994 @@ -69,6 +69,7 @@ { struct inode * inode; int error; + struct iattr newattrs; error = namei(path,&inode); if (error) @@ -85,12 +86,13 @@ iput(inode); return -EPERM; } - inode->i_size = length; + inode->i_size = newattrs.ia_size = length; if (inode->i_op && inode->i_op->truncate) inode->i_op->truncate(inode); - inode->i_ctime = inode->i_mtime = CURRENT_TIME; + newattrs.ia_ctime = newattrs.ia_mtime = CURRENT_TIME; + newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME | ATTR_MTIME; inode->i_dirt = 1; - error = notify_change(NOTIFY_SIZE, inode); + error = notify_change(inode, &newattrs); iput(inode); return error; } @@ -99,6 +101,7 @@ { struct inode * inode; struct file * file; + struct iattr newattrs; if (fd >= NR_OPEN || !(file = current->files->fd[fd])) return -EBADF; @@ -108,12 +111,13 @@ return -EACCES; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EPERM; - inode->i_size = length; + inode->i_size = newattrs.ia_size = length; if (inode->i_op && inode->i_op->truncate) inode->i_op->truncate(inode); - inode->i_ctime = inode->i_mtime = CURRENT_TIME; + newattrs.ia_ctime = newattrs.ia_mtime = CURRENT_TIME; + newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME | ATTR_MTIME; inode->i_dirt = 1; - return notify_change(NOTIFY_SIZE, inode); + return notify_change(inode, &newattrs); } /* If times==NULL, set access and modification to current time, @@ -125,6 +129,7 @@ struct inode * inode; long actime,modtime; int error; + struct iattr newattrs; error = namei(filename,&inode); if (error) @@ -140,19 +145,20 @@ } actime = get_fs_long((unsigned long *) ×->actime); modtime = get_fs_long((unsigned long *) ×->modtime); - inode->i_ctime = CURRENT_TIME; + newattrs.ia_ctime = CURRENT_TIME; } else { if ((current->fsuid != inode->i_uid) && !permission(inode,MAY_WRITE)) { iput(inode); return -EACCES; } - actime = modtime = inode->i_ctime = CURRENT_TIME; + actime = modtime = newattrs.ia_ctime = CURRENT_TIME; } - inode->i_atime = actime; - inode->i_mtime = modtime; + newattrs.ia_atime = actime; + newattrs.ia_mtime = modtime; + newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; inode->i_dirt = 1; - error = notify_change(NOTIFY_TIME, inode); + error = notify_change(inode, &newattrs); iput(inode); return error; } @@ -249,49 +255,43 @@ { struct inode * inode; struct file * file; + struct iattr newattrs; if (fd >= NR_OPEN || !(file = current->files->fd[fd])) return -EBADF; if (!(inode = file->f_inode)) return -ENOENT; - if ((current->fsuid != inode->i_uid) && !fsuser()) - return -EPERM; if (IS_RDONLY(inode)) return -EROFS; if (mode == (mode_t) -1) mode = inode->i_mode; - inode->i_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - if (!fsuser() && !in_group_p(inode->i_gid)) - inode->i_mode &= ~S_ISGID; - inode->i_ctime = CURRENT_TIME; + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); + newattrs.ia_ctime = CURRENT_TIME; + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; inode->i_dirt = 1; - return notify_change(NOTIFY_MODE, inode); + return notify_change(inode, &newattrs); } asmlinkage int sys_chmod(const char * filename, mode_t mode) { struct inode * inode; int error; + struct iattr newattrs; error = namei(filename,&inode); if (error) return error; - if ((current->fsuid != inode->i_uid) && !fsuser()) { - iput(inode); - return -EPERM; - } if (IS_RDONLY(inode)) { iput(inode); return -EROFS; } if (mode == (mode_t) -1) mode = inode->i_mode; - inode->i_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - if (!fsuser() && !in_group_p(inode->i_gid)) - inode->i_mode &= ~S_ISGID; - inode->i_ctime = CURRENT_TIME; + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); + newattrs.ia_ctime = CURRENT_TIME; + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; inode->i_dirt = 1; - error = notify_change(NOTIFY_MODE, inode); + error = notify_change(inode, &newattrs); iput(inode); return error; } @@ -300,9 +300,7 @@ { struct inode * inode; struct file * file; - uid_t old_user; - gid_t old_group; - int notify_flag = 0; + struct iattr newattrs; if (fd >= NR_OPEN || !(file = current->files->fd[fd])) return -EBADF; @@ -310,45 +308,37 @@ return -ENOENT; if (IS_RDONLY(inode)) return -EROFS; - old_user = inode->i_uid; - old_group = inode->i_gid; if (user == (uid_t) -1) user = inode->i_uid; if (group == (gid_t) -1) group = inode->i_gid; - if ((current->fsuid == inode->i_uid && user == inode->i_uid && - (in_group_p(group) || group == inode->i_gid)) || - fsuser()) { - inode->i_uid = user; - inode->i_gid = group; - /* - * If the owner has been changed, remove the setuid bit - */ - if (old_user != inode->i_uid && inode->i_mode & S_ISUID) { - inode->i_mode &= ~S_ISUID; - notify_flag = NOTIFY_MODE; - } - /* - * If the group has been changed, remove the setgid bit - */ - if (old_group != inode->i_gid && inode->i_mode & S_ISGID) { - inode->i_mode &= ~S_ISGID; - notify_flag = NOTIFY_MODE; - } - inode->i_ctime = CURRENT_TIME; - inode->i_dirt = 1; - return notify_change(notify_flag | NOTIFY_UIDGID, inode); + newattrs.ia_uid = user; + newattrs.ia_gid = group; + newattrs.ia_ctime = CURRENT_TIME; + newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME; + /* + * If the owner has been changed, remove the setuid bit + */ + if (user != inode->i_uid && inode->i_mode & S_ISUID) { + newattrs.ia_mode = inode->i_mode & ~S_ISUID; + newattrs.ia_valid |= ATTR_MODE; + } + /* + * If the group has been changed, remove the setgid bit + */ + if (group != inode->i_gid && inode->i_mode & S_ISGID) { + newattrs.ia_mode = inode->i_mode & ~S_ISGID; + newattrs.ia_valid |= ATTR_MODE; } - return -EPERM; + inode->i_dirt = 1; + return notify_change(inode, &newattrs); } asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group) { struct inode * inode; int error; - uid_t old_user; - gid_t old_group; - int notify_flag = 0; + struct iattr newattrs; error = lnamei(filename,&inode); if (error) @@ -357,39 +347,32 @@ iput(inode); return -EROFS; } - old_user = inode->i_uid; - old_group = inode->i_uid; if (user == (uid_t) -1) user = inode->i_uid; if (group == (gid_t) -1) group = inode->i_gid; - if ((current->fsuid == inode->i_uid && user == inode->i_uid && - (in_group_p(group) || group == inode->i_gid)) || - fsuser()) { - inode->i_uid = user; - inode->i_gid = group; - /* - * If the owner has been changed, remove the setuid bit - */ - if (old_user != inode->i_uid && inode->i_mode & S_ISUID) { - inode->i_mode &= ~S_ISUID; - notify_flag = NOTIFY_MODE; - } - /* - * If the group has been changed, remove the setgid bit - */ - if (old_group != inode->i_gid && inode->i_mode & S_ISGID) { - inode->i_mode &= ~S_ISGID; - notify_flag = NOTIFY_MODE; - } - inode->i_ctime = CURRENT_TIME; - inode->i_dirt = 1; - error = notify_change(notify_flag | NOTIFY_UIDGID, inode); - iput(inode); - return error; + newattrs.ia_uid = user; + newattrs.ia_gid = group; + newattrs.ia_ctime = CURRENT_TIME; + newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME; + /* + * If the owner has been changed, remove the setuid bit + */ + if (user != inode->i_uid && inode->i_mode & S_ISUID) { + newattrs.ia_mode = inode->i_mode & ~S_ISUID; + newattrs.ia_valid |= ATTR_MODE; + } + /* + * If the group has been changed, remove the setgid bit + */ + if (group != inode->i_gid && inode->i_mode & S_ISGID) { + newattrs.ia_mode = inode->i_mode & ~S_ISGID; + newattrs.ia_valid |= ATTR_MODE; } + inode->i_dirt = 1; + error = notify_change(inode, &newattrs); iput(inode); - return -EPERM; + return(error); } /* diff -u --recursive --new-file v1.1.56/linux/fs/proc/base.c linux/fs/proc/base.c --- v1.1.56/linux/fs/proc/base.c Thu Aug 11 20:43:27 1994 +++ linux/fs/proc/base.c Sat Oct 22 16:41:18 1994 @@ -69,8 +69,6 @@ int proc_match(int len,const char * name,struct proc_dir_entry * de) { - register int same; - if (!de || !de->low_ino) return 0; /* "" means "." ---> so paths like "/usr/lib//libc.a" work */ @@ -78,14 +76,7 @@ return 1; if (de->namelen != len) return 0; - __asm__ __volatile__( - "cld\n\t" - "repe ; cmpsb\n\t" - "setz %%al" - :"=a" (same) - :"0" (0),"S" ((long) name),"D" ((long) de->name),"c" (len) - :"cx","di","si"); - return same; + return !memcmp(name, de->name, len); } static int proc_lookupbase(struct inode * dir,const char * name, int len, diff -u --recursive --new-file v1.1.56/linux/fs/read_write.c linux/fs/read_write.c --- v1.1.56/linux/fs/read_write.c Sun Oct 23 13:30:12 1994 +++ linux/fs/read_write.c Sun Oct 23 19:20:36 1994 @@ -159,8 +159,10 @@ * the setgid bits */ if (written > 0 && !suser() && (inode->i_mode & (S_ISUID | S_ISGID))) { - inode->i_mode &= ~(S_ISUID | S_ISGID); - notify_change (NOTIFY_MODE, inode); + struct iattr newattrs; + newattrs.ia_mode = inode->i_mode & ~(S_ISUID | S_ISGID); + newattrs.ia_valid = ATTR_MODE; + notify_change(inode, &newattrs); } return written; } diff -u --recursive --new-file v1.1.56/linux/fs/sysv/balloc.c linux/fs/sysv/balloc.c --- v1.1.56/linux/fs/sysv/balloc.c Tue Apr 19 10:53:25 1994 +++ linux/fs/sysv/balloc.c Sat Oct 22 16:50:31 1994 @@ -29,16 +29,6 @@ sb->sv_sbd->s_tfree = *sb->sv_sb_total_free_blocks but we nevertheless keep it up to date. */ -extern inline void memzero (void * s, size_t count) -{ -__asm__("cld\n\t" - "rep\n\t" - "stosl" - : - :"a" (0),"D" (s),"c" (count/4) - :"cx","di","memory"); -} - void sysv_free_block(struct super_block * sb, unsigned int block) { struct buffer_head * bh; @@ -115,7 +105,7 @@ return; } bh_data = bh->b_data + ((block & sb->sv_block_size_ratio_1) << sb->sv_block_size_bits); - memzero(bh_data, sb->sv_block_size); + memset(bh_data, 0, sb->sv_block_size); /* this implies ((struct ..._freelist_chunk *) bh_data)->flc_count = 0; */ mark_buffer_dirty(bh, 1); bh->b_uptodate = 1; @@ -228,7 +218,7 @@ unlock_super(sb); return 0; } - memzero(bh_data,sb->sv_block_size); + memset(bh_data, 0, sb->sv_block_size); mark_buffer_dirty(bh, 1); bh->b_uptodate = 1; brelse(bh); diff -u --recursive --new-file v1.1.56/linux/fs/sysv/inode.c linux/fs/sysv/inode.c --- v1.1.56/linux/fs/sysv/inode.c Sun Oct 9 12:00:27 1994 +++ linux/fs/sysv/inode.c Sun Oct 23 19:37:01 1994 @@ -715,9 +715,16 @@ } /* To avoid inconsistencies between inodes in memory and inodes on disk. */ -extern int sysv_notify_change(int flags, struct inode *inode) +extern int sysv_notify_change(struct inode *inode, struct iattr *attr) { - if (flags & NOTIFY_MODE) + int error; + + if ((error = inode_change_ok(inode, attr)) != 0) + return error; + + inode_setattr(inode, attr); + + if (attr->ia_valid & ATTR_MODE) if (inode->i_sb->sv_kludge_symlinks) if (inode->i_mode == COH_KLUDGE_SYMLINK_MODE) { inode->i_mode = COH_KLUDGE_NOT_SYMLINK; diff -u --recursive --new-file v1.1.56/linux/fs/sysv/namei.c linux/fs/sysv/namei.c --- v1.1.56/linux/fs/sysv/namei.c Mon Aug 15 11:47:11 1994 +++ linux/fs/sysv/namei.c Sat Oct 22 16:49:27 1994 @@ -25,16 +25,11 @@ static inline int namecompare(int len, int maxlen, const char * name, const char * buffer) { - if (len >= maxlen || !buffer[len]) { - unsigned char same; - __asm__("repe ; cmpsb ; setz %0" - :"=q" (same) - :"S" ((long) name),"D" ((long) buffer),"c" (len) - :"cx","di","si"); - return same; - } - /* if (len maxlen) + return 0; + if (len < maxlen && buffer[len]) + return 0; + return !memcmp(name, buffer, len); } /* diff -u --recursive --new-file v1.1.56/linux/fs/umsdos/inode.c linux/fs/umsdos/inode.c --- v1.1.56/linux/fs/umsdos/inode.c Thu Aug 11 20:43:28 1994 +++ linux/fs/umsdos/inode.c Sun Oct 23 19:39:59 1994 @@ -257,13 +257,24 @@ */ void UMSDOS_write_inode(struct inode *inode) { + struct iattr newattrs; + PRINTK (("UMSDOS_write_inode emd %d\n",inode->u.umsdos_i.i_emd_owner)); msdos_write_inode(inode); - UMSDOS_notify_change (NOTIFY_TIME,inode); + newattrs.ia_mtime = inode->i_mtime; + newattrs.ia_atime = inode->i_atime; + newattrs.ia_ctime = inode->i_ctime; + newattrs.ia_valid = ATTR_MTIME | ATTR_ATIME | ATTR_CTIME; + UMSDOS_notify_change (inode, &newattrs); } -int UMSDOS_notify_change (int flags, struct inode *inode) + +int UMSDOS_notify_change(struct inode *inode, struct iattr *attr) { int ret = 0; + + if ((ret = inode_change_ok(inode, attr)) != 0) + return ret; + if (inode->i_nlink > 0){ /* #Specification: notify_change / i_nlink > 0 notify change is only done for inode with nlink > 0. An inode @@ -306,25 +317,24 @@ ret = umsdos_emd_dir_read (emd_owner,&filp,(char*)&entry ,UMSDOS_REC_SIZE); if (ret == 0){ - if (flags & NOTIFY_UIDGID){ - entry.uid = inode->i_uid; - entry.gid = inode->i_gid; - /* Remove those flags msdos don't like */ - flags &= ~NOTIFY_UIDGID; - } - if (flags & NOTIFY_MODE){ - entry.mode = inode->i_mode; - flags &= ~NOTIFY_MODE; - } - if (flags & NOTIFY_TIME){ - entry.atime = inode->i_atime; - entry.mtime = inode->i_mtime; - entry.ctime = inode->i_ctime; - } + if (attr->ia_valid & ATTR_UID) + entry.uid = attr->ia_uid; + if (attr->ia_valid & ATTR_GID) + entry.gid = attr->ia_gid; + if (attr->ia_valid & ATTR_MODE) + entry.mode = attr->ia_mode; + if (attr->ia_valid & ATTR_ATIME) + entry.atime = attr->ia_atime; + if (attr->ia_valid & ATTR_MTIME) + entry.mtime = attr->ia_mtime; + if (attr->ia_valid & ATTR_CTIME) + entry.ctime = attr->ia_ctime; + entry.nlink = inode->i_nlink; filp.f_pos = inode->u.umsdos_i.pos; ret = umsdos_emd_dir_write (emd_owner,&filp,(char*)&entry ,UMSDOS_REC_SIZE); + PRINTK (("notify pos %d ret %d nlink %d " ,inode->u.umsdos_i.pos ,ret,entry.nlink)); @@ -332,20 +342,14 @@ notify_change operation are done only on the EMD file. The msdos fs is not even called. */ - #if 0 - if (ret == 0 - && (S_ISDIR(inode->i_mode) - || S_ISREG(inode->i_mode))){ - ret = msdos_notify_change(flags, inode); - printk ("msdos_notify %x %d",inode,ret); - } - #endif } iput (emd_owner); } PRINTK (("\n")); } } + if (ret == 0) + inode_setattr(inode, attr); return ret; } diff -u --recursive --new-file v1.1.56/linux/fs/umsdos/namei.c linux/fs/umsdos/namei.c --- v1.1.56/linux/fs/umsdos/namei.c Mon Aug 15 11:47:11 1994 +++ linux/fs/umsdos/namei.c Sun Oct 23 18:57:28 1994 @@ -618,7 +618,7 @@ } if (ret == 0){ oldinode->i_nlink++; - ret = UMSDOS_notify_change (0,oldinode); + ret = UMSDOS_notify_change (0,NULL,oldinode); } iput (oldinode); iput (dir); @@ -923,7 +923,7 @@ iput (hdir); } }else{ - ret = UMSDOS_notify_change (0,inode); + ret = UMSDOS_notify_change (0,NULL,inode); } iput (inode); } diff -u --recursive --new-file v1.1.56/linux/fs/xiafs/bitmap.c linux/fs/xiafs/bitmap.c --- v1.1.56/linux/fs/xiafs/bitmap.c Mon Aug 15 11:47:12 1994 +++ linux/fs/xiafs/bitmap.c Sat Oct 22 16:24:03 1994 @@ -18,14 +18,10 @@ #include #include -#include "xiafs_mac.h" +#include +#include "xiafs_mac.h" -#define clear_bit(nr,addr) ({\ -char res; \ -__asm__ __volatile__("btrl %1,%2\n\tsetnb %0": \ -"=q" (res):"r" (nr),"m" (*(addr))); \ -res;}) char internal_error_message[]="XIA-FS: internal error %s %d\n"; @@ -59,9 +55,7 @@ for (j=0; j < 32; j++) if (tmp & (1 << j)) break; - __asm__ ("btsl %1,%2\n\tsetb %0": \ - "=q" (res):"r" (j),"m" (bmap[i])); - if (res) { + if (set_bit(j,bmap+i)) { start_bit=j + (i << 5) + 1; goto repeat; } @@ -241,7 +235,7 @@ if (!bh) return; offset = bit & (XIAFS_BITS_PER_Z(sb) -1); - if (clear_bit(offset, bh->b_data)) + if (!clear_bit(offset, bh->b_data)) printk("XIA-FS: dev %04x" " block bit %u (0x%x) already cleared (%s %d)\n", sb->s_dev, bit, bit, WHERE_ERR); @@ -301,7 +295,7 @@ if (!bh) return; clear_inode(inode); - if (clear_bit(ino & (XIAFS_BITS_PER_Z(sb)-1), bh->b_data)) + if (!clear_bit(ino & (XIAFS_BITS_PER_Z(sb)-1), bh->b_data)) printk("XIA-FS: dev %04x" "inode bit %ld (0x%lx) already cleared (%s %d)\n", inode->i_dev, ino, ino, WHERE_ERR); diff -u --recursive --new-file v1.1.56/linux/include/asm-alpha/bitops.h linux/include/asm-alpha/bitops.h --- v1.1.56/linux/include/asm-alpha/bitops.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-alpha/bitops.h Sun Oct 23 20:56:31 1994 @@ -0,0 +1,85 @@ +#ifndef _ALPHA_BITOPS_H +#define _ALPHA_BITOPS_H + +/* + * Copyright 1994, Linus Torvalds. + */ + +/* + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 64 is the LSB of (addr+1). + */ + +extern __inline__ unsigned long set_bit(unsigned long nr, void * addr) +{ + unsigned long oldbit; + unsigned long temp; + + __asm__ __volatile__( + "\n1:\t" + "ldq_l %0,%1\n\t" + "and %0,%3,%2\n\t" + "bne %2,2f\n\t" + "xor %0,%3,%0\n\t" + "stq_c %0,%1\n\t" + "beq %0,1b\n" + "2:" + :"=&r" (temp), + "=m" (((unsigned long *) addr)[nr >> 6]), + "=&r" (oldbit) + :"r" (1UL << (nr & 63)), + "m" (((unsigned long *) addr)[nr >> 6])); + return oldbit; +} + +extern __inline__ unsigned long clear_bit(unsigned long nr, void * addr) +{ + unsigned long oldbit; + unsigned long temp; + + __asm__ __volatile__( + "\n1:\t" + "ldq_l %0,%1\n\t" + "and %0,%3,%2\n\t" + "beq %2,2f\n\t" + "xor %0,%3,%0\n\t" + "stq_c %0,%1\n\t" + "beq %0,1b\n" + "2:" + :"=&r" (temp), + "=m" (((unsigned long *) addr)[nr >> 6]), + "=&r" (oldbit) + :"r" (1UL << (nr & 63)), + "m" (((unsigned long *) addr)[nr >> 6])); + return oldbit; +} + +extern __inline__ unsigned long change_bit(unsigned long nr, void * addr) +{ + unsigned long oldbit; + unsigned long temp; + + __asm__ __volatile__( + "\n1:\t" + "ldq_l %0,%1\n\t" + "and %0,%3,%2\n\t" + "xor %0,%3,%0\n\t" + "stq_c %0,%1\n\t" + "beq %0,1b\n" + :"=&r" (temp), + "=m" (((unsigned long *) addr)[nr >> 6]), + "=&r" (oldbit) + :"r" (1UL << (nr & 63)), + "m" (((unsigned long *) addr)[nr >> 6])); + return oldbit; +} + +extern __inline__ unsigned long test_bit(int nr, void * addr) +{ + return (1UL << (nr & 63)) & ((unsigned long *) addr)[nr >> 6]; +} + +#endif /* _ALPHA_BITOPS_H */ diff -u --recursive --new-file v1.1.56/linux/include/linux/fs.h linux/include/linux/fs.h --- v1.1.56/linux/include/linux/fs.h Sun Oct 23 13:30:13 1994 +++ linux/include/linux/fs.h Sun Oct 23 19:02:13 1994 @@ -127,13 +127,6 @@ #define FIBMAP 1 /* bmap access */ #define FIGETBSZ 2 /* get the block size used for bmap */ -/* these flags tell notify_change what is being changed */ - -#define NOTIFY_SIZE 1 -#define NOTIFY_MODE 2 -#define NOTIFY_TIME 4 -#define NOTIFY_UIDGID 8 - typedef char buffer_block[BLOCK_SIZE]; struct buffer_head { @@ -174,6 +167,38 @@ #ifdef __KERNEL__ +/* + * Attribute flags. These should be or-ed together to figure out what + * has been changed! + */ +#define ATTR_MODE 1 +#define ATTR_UID 2 +#define ATTR_GID 4 +#define ATTR_SIZE 8 +#define ATTR_ATIME 16 +#define ATTR_MTIME 32 +#define ATTR_CTIME 64 + +/* + * This is the Inode Attributes structure, used for notify_change(). It + * uses the above definitions as flags, to know which values have changed. + * Also, in this manner, a Filesystem can look at only the values it cares + * about. Basically, these are the attributes that the VFS layer can + * request to change from the FS layer. + * + * Derek Atkins 94-10-20 + */ +struct iattr { + unsigned int ia_valid; + umode_t ia_mode; + uid_t ia_uid; + gid_t ia_gid; + off_t ia_size; + time_t ia_atime; + time_t ia_mtime; + time_t ia_ctime; +}; + struct inode { dev_t i_dev; unsigned long i_ino; @@ -331,7 +356,7 @@ struct super_operations { void (*read_inode) (struct inode *); - int (*notify_change) (int flags, struct inode *); + int (*notify_change) (struct inode *, struct iattr *); void (*write_inode) (struct inode *); void (*put_inode) (struct inode *); void (*put_super) (struct super_block *); @@ -435,7 +460,7 @@ extern int fsync_dev(dev_t dev); extern void sync_supers(dev_t dev); extern int bmap(struct inode * inode,int block); -extern int notify_change(int flags, struct inode * inode); +extern int notify_change(struct inode *, struct iattr *); extern int namei(const char * pathname, struct inode ** res_inode); extern int lnamei(const char * pathname, struct inode ** res_inode); extern int permission(struct inode * inode,int mask); @@ -482,6 +507,9 @@ extern void dcache_add(struct inode *, const char *, int, unsigned long); extern int dcache_lookup(struct inode *, const char *, int, unsigned long *); + +extern int inode_change_ok(struct inode *, struct iattr *); +extern void inode_setattr(struct inode *, struct iattr *); extern inline struct inode * iget(struct super_block * sb,int nr) { diff -u --recursive --new-file v1.1.56/linux/include/linux/hdreg.h linux/include/linux/hdreg.h --- v1.1.56/linux/include/linux/hdreg.h Fri Oct 21 10:15:06 1994 +++ linux/include/linux/hdreg.h Mon Oct 24 08:39:01 1994 @@ -8,6 +8,7 @@ */ /* Hd controller regs. Ref: IBM AT Bios-listing */ +/* For a second IDE interface, xor all addresses with 0x80 */ #define HD_DATA 0x1f0 /* _CTL when writing */ #define HD_ERROR 0x1f1 /* see err-bits */ #define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ @@ -16,10 +17,12 @@ #define HD_HCYL 0x1f5 /* high byte of starting cyl */ #define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */ #define HD_STATUS 0x1f7 /* see status-bits */ -#define HD_PRECOMP HD_ERROR /* same io address, read=error, write=precomp */ +#define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */ +#define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */ #define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */ -#define HD_CMD 0x3f6 +#define HD_CMD 0x3f6 /* used for resets */ +#define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */ /* Bits of HD_STATUS */ #define ERR_STAT 0x01 @@ -41,7 +44,9 @@ #define WIN_SEEK 0x70 #define WIN_DIAGNOSE 0x90 #define WIN_SPECIFY 0x91 +#define WIN_SETIDLE 0x97 +#define WIN_PIDENTIFY 0xA1 /* identify ATA-PI device */ #define WIN_MULTREAD 0xC4 /* read multiple sectors */ #define WIN_MULTWRITE 0xC5 /* write multiple sectors */ #define WIN_SETMULT 0xC6 /* enable read multiple */ @@ -56,25 +61,29 @@ #define ECC_ERR 0x40 /* Uncorrectable ECC error */ #define BBD_ERR 0x80 /* block marked bad */ - -/* HDIO_GETGEO is the preferred choice - HDIO_REQ will be removed at some - later date */ -#define HDIO_REQ 0x301 -#define HDIO_GETGEO 0x301 struct hd_geometry { unsigned char heads; unsigned char sectors; unsigned short cylinders; unsigned long start; }; -#define HDIO_GETUNMASKINTR 0x302 -#define HDIO_SETUNMASKINTR 0x303 -#define HDIO_GETMULTCOUNT 0x304 -#define HDIO_SETMULTCOUNT 0x305 -#define HDIO_GETIDENTITY 0x307 -#endif -/* structure returned by HDIO_GETIDENTITY, as per ASC X3T9.2 rev 4a */ +/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x30n/0x31n */ +#define HDIO_GETGEO 0x301 /* get device geometry */ +#define HDIO_REQ HDIO_GETGEO /* obsolete, use HDIO_GETGEO */ +#define HDIO_GET_UNMASKINTR 0x302 /* get current unmask setting */ +#define HDIO_SETUNMASKINTR 0x303 /* obsolete */ +#define HDIO_GET_MULTCOUNT 0x304 /* get current IDE blockmode setting */ +#define HDIO_SETMULTCOUNT 0x305 /* obsolete */ +#define HDIO_GET_IDENTITY 0x307 /* get IDE identification info */ + +/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x32n/0x33n */ +#define HDIO_SET_MULTCOUNT 0x321 /* set IDE blockmode */ +#define HDIO_SET_UNMASKINTR 0x322 /* permit other irqs during I/O */ +#define HDIO_SET_KEEPSETTINGS 0x323 /* keep ioctl settings on reset */ +#define HDIO_SET_XFERMODE 0x324 /* set IDE transfer mode */ + +/* structure returned by HDIO_GET_IDENTITY, as per ANSI ATA2 rev.2f spec */ struct hd_driveid { unsigned short config; /* lots of obsolete bit flags */ unsigned short cyls; /* "physical" cyls */ @@ -124,3 +133,4 @@ /* unsigned short vendor7 [32];*/ /* vendor unique (words 128-159) */ /* unsigned short reservedyy[96];*/ /* reserved (words 160-255) */ }; +#endif diff -u --recursive --new-file v1.1.56/linux/include/linux/msdos_fs.h linux/include/linux/msdos_fs.h --- v1.1.56/linux/include/linux/msdos_fs.h Sun Aug 21 17:48:38 1994 +++ linux/include/linux/msdos_fs.h Sun Oct 23 19:40:49 1994 @@ -175,7 +175,7 @@ extern int msdos_bmap(struct inode *inode,int block); extern void msdos_read_inode(struct inode *inode); extern void msdos_write_inode(struct inode *inode); -extern int msdos_notify_change(int flags,struct inode *inode); +extern int msdos_notify_change(struct inode *,struct iattr *); /* dir.c */ diff -u --recursive --new-file v1.1.56/linux/include/linux/sysv_fs.h linux/include/linux/sysv_fs.h --- v1.1.56/linux/include/linux/sysv_fs.h Wed Aug 3 09:32:33 1994 +++ linux/include/linux/sysv_fs.h Sun Oct 23 19:41:19 1994 @@ -421,7 +421,7 @@ extern struct super_block *sysv_read_super(struct super_block *,void *,int); extern void sysv_write_super(struct super_block *); extern void sysv_read_inode(struct inode *); -extern int sysv_notify_change(int,struct inode *); +extern int sysv_notify_change(struct inode *, struct iattr *); extern void sysv_write_inode(struct inode *); extern void sysv_put_inode(struct inode *); extern void sysv_statfs(struct super_block *, struct statfs *); diff -u --recursive --new-file v1.1.56/linux/include/linux/umsdos_fs.p linux/include/linux/umsdos_fs.p --- v1.1.56/linux/include/linux/umsdos_fs.p Mon Jul 25 17:56:44 1994 +++ linux/include/linux/umsdos_fs.p Mon Oct 24 07:51:44 1994 @@ -77,7 +77,7 @@ int umsdos_get_dirowner (struct inode *inode, struct inode **result); void UMSDOS_read_inode (struct inode *inode); void UMSDOS_write_inode (struct inode *inode); -int UMSDOS_notify_change (int flags, struct inode *inode); +int UMSDOS_notify_change (struct inode *inode, struct iattr *attr); struct super_block *UMSDOS_read_super (struct super_block *s, void *data, int silent); diff -u --recursive --new-file v1.1.56/linux/init/main.c linux/init/main.c --- v1.1.56/linux/init/main.c Fri Aug 26 14:44:45 1994 +++ linux/init/main.c Sat Oct 22 15:30:34 1994 @@ -157,7 +157,7 @@ static char command_line[COMMAND_LINE_SIZE] = { 0, }; -char *get_options(char *str, int *ints) +char *get_options(char *str, int *ints) { char *cur = str; int i=1; @@ -253,7 +253,12 @@ printk("Calibrating delay loop.. "); while (loops_per_sec <<= 1) { + /* wait for "start of" clock tick */ ticks = jiffies; + while (ticks == jiffies) + /* nothing */; + /* Go .. */ + ticks = jiffies; __delay(loops_per_sec); ticks = jiffies - ticks; if (ticks >= HZ) { @@ -271,7 +276,7 @@ } printk("failed\n"); } - + /* * This is a simple kernel command line parsing function: it parses @@ -347,7 +352,7 @@ /* * Then check if it's an environment variable or * an option. - */ + */ if (strchr(line,'=')) { if (envs >= MAX_INIT_ENVS) break; @@ -459,7 +464,7 @@ ipc_init(); #endif sti(); - + /* * check if exception 16 works correctly.. This is truly evil * code: it disables the high 8 interrupts to make sure that diff -u --recursive --new-file v1.1.56/linux/kernel/vm86.c linux/kernel/vm86.c --- v1.1.56/linux/kernel/vm86.c Tue Oct 11 09:29:24 1994 +++ linux/kernel/vm86.c Sat Oct 22 15:17:06 1994 @@ -45,8 +45,8 @@ #define set_flags(X,new,mask) \ ((X) = ((X) & ~(mask)) | ((new) & (mask))) -#define SAFE_MASK (0x40DD5) -#define RETURN_MASK (0x40DFF) +#define SAFE_MASK (0xDD5) +#define RETURN_MASK (0xDFF) asmlinkage struct pt_regs * save_v86_state(struct vm86_regs * regs) { diff -u --recursive --new-file v1.1.56/linux/kernel/vsprintf.c linux/kernel/vsprintf.c --- v1.1.56/linux/kernel/vsprintf.c Sun Oct 9 12:00:29 1994 +++ linux/kernel/vsprintf.c Mon Oct 24 07:55:12 1994 @@ -234,7 +234,7 @@ case 'p': if (field_width == -1) { - field_width = 8; + field_width = 2*sizeof(void *); flags |= ZEROPAD; } str = number(str, diff -u --recursive --new-file v1.1.56/linux/mm/memory.c linux/mm/memory.c --- v1.1.56/linux/mm/memory.c Sun Oct 9 12:00:29 1994 +++ linux/mm/memory.c Sun Oct 23 12:33:58 1994 @@ -240,7 +240,7 @@ continue; if (old_pg_table >= high_memory || !(old_pg_table & PAGE_PRESENT)) { printk("copy_page_tables: bad page table: " - "probable memory corruption"); + "probable memory corruption\n"); *old_page_dir = 0; continue; }