]> git.neil.brown.name Git - history.git/commitdiff
Import 1.1.57 1.1.57
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:42 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:42 +0000 (15:09 -0500)
34 files changed:
Makefile
drivers/block/floppy.c
drivers/block/hd.c
drivers/block/ll_rw_blk.c
fs/buffer.c
fs/ext/freelists.c
fs/ext/namei.c
fs/inode.c
fs/isofs/namei.c
fs/minix/bitmap.c
fs/minix/dir.c
fs/minix/namei.c
fs/msdos/inode.c
fs/namei.c
fs/nfs/inode.c
fs/open.c
fs/proc/base.c
fs/read_write.c
fs/sysv/balloc.c
fs/sysv/inode.c
fs/sysv/namei.c
fs/umsdos/inode.c
fs/umsdos/namei.c
fs/xiafs/bitmap.c
include/asm-alpha/bitops.h [new file with mode: 0644]
include/linux/fs.h
include/linux/hdreg.h
include/linux/msdos_fs.h
include/linux/sysv_fs.h
include/linux/umsdos_fs.p
init/main.c
kernel/vm86.c
kernel/vsprintf.c
mm/memory.c

index 7db486a13a07af0612213c5bde55564d73d5baf7..97bdbc9758927d6c61066414ad793b1012794d83 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 56
+SUBLEVEL = 57
 
 ARCH = i386
 
index 2ca87e6938f13637220b6496dbf4d977eec865b0..c9a48e6cdd1506c2be3b5d3354638fc45482e381 100644 (file)
@@ -314,17 +314,17 @@ static struct floppy_struct floppy_type[32] = {
        { 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 inline void debugt(char *message)
 
 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 disk_change(int drive)
        }
 }
 
-
+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 @@ static int set_dor(int fdc, char mask, char data)
                FDCS->dor = newdor;
                outb_p( newdor, FD_DOR);
        }
-       sti();
+       locked=0;
        return olddor;
 }
 
@@ -636,7 +639,10 @@ static void motor_off_callback(unsigned long nr)
 {
        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 struct timer_list motor_off_timer[N_DRIVE] = {
 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 @@ static void seek_interrupt(void)
            )
                DRS->flags &= ~FD_DISK_NEWCHANGE; /* effective seek */
        DRS->track = ST1;
+       DRS->select_date = jiffies;
        seek_floppy();
 }
 
@@ -1466,7 +1477,8 @@ static void start_motor(void)
 
        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 @@ static void start_motor(void)
        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 @@ static int buffer_chain_size(void)
        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 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
                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 @@ static void redo_fd_request(void)
                        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 @@ static int raw_cmd_ioctl(int drive, void *param)
        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 @@ void floppy_init(void)
 
 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 int floppy_grab_irq_and_dma(void)
 
 static void floppy_release_irq_and_dma(void)
 {
+       int i;
        cli();
        if (--usage_count){
                sti();
@@ -3156,10 +3165,7 @@ static void floppy_release_irq_and_dma(void)
        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);
 }
index 7964c7d6a6977a00d80910ec42ef28970a5bd68d..a0347961b43194b4319e58574d4b73af025cf24f 100644 (file)
@@ -305,7 +305,8 @@ static void identify_intr(void)
        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 @@ static int hd_ioctl(struct inode * inode, struct file * file,
 {
        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 @@ static int hd_ioctl(struct inode * inode, struct file * file,
                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 @@ static int hd_ioctl(struct inode * inode, struct file * file,
                        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 @@ static int hd_ioctl(struct inode * inode, struct file * file,
                        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 @@ static int hd_ioctl(struct inode * inode, struct file * file,
                        }
                        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;
index 3336a031605372d0ebbb8ec4b415cbd56db96983..37888c37efdca508d3568da18222d54b7ed45041 100644 (file)
@@ -126,7 +126,6 @@ int is_read_only(int dev)
 
        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));
 }
index 75bbbe580fc890cdf152b684efa9fbef955d63cf..16773ed8b30b13a5dcfd6c58177e9d3a79873e00 100644 (file)
@@ -1106,11 +1106,6 @@ static inline unsigned long try_to_share_buffers(unsigned long address,
        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 @@ unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, in
        for (i=0, j=0; j<PAGE_SIZE ; i++, j += size, where += size) {
                if (bh[i]) {
                        if (bh[i]->b_uptodate)
-                               COPYBLK(size, (unsigned long) bh[i]->b_data, where);
+                               memcpy((void *) where, bh[i]->b_data, size);
                        brelse(bh[i]);
                }
        }
index 13bc4de305e970fdd2cd0bd633c44d33c7a9f67e..29c4c4289fd5522292bf538a8119d1beca2db446 100644 (file)
 #include <linux/string.h>
 #include <linux/locks.h>
 
-#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("ext_new_block: block empty, skipping to %d\n", efb->next);
                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);
index 45f91cb9b93de9455750b1926982ddc11f622114..85a411e94824ff391ed98894549e5d33270ffef2 100644 (file)
  */
 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);
 }
 
 /*
index e089ec92f9f3b39a114a9f469f2dc03ed23090f9..07d8dad4b22710d8cdbba0c370d946018e764641 100644 (file)
@@ -233,6 +233,59 @@ static void read_inode(struct inode * inode)
        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 @@ static void read_inode(struct inode * inode)
  * 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;
 }
 
index a28225076084971973c6eec7d12b4d42d723ba69..8ff7728eea20fc5c97631c0447feaf14c382f396 100644 (file)
  */
 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);
 }
 
 /*
index 53ff26cecb12c5aa0a13f19949fe8d9d4b94aac5..d42b86eea819e729c2f2f471c4acca3858d2a29d 100644 (file)
 
 #include <asm/bitops.h>
 
-#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 @@ repeat:
        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 @@ repeat:
                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 @@ struct inode * minix_new_inode(const struct inode * dir)
        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);
index 2a1134495f9d32b5bb3638e3fa2a921a086b1c8f..6ece61971733fbc50230b84c1cb846c1d070ec90 100644 (file)
@@ -86,13 +86,13 @@ static int minix_readdir(struct inode * inode, struct file * filp,
                        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);
index 3393aaf84b655f8ede4d0ea722adb7c94deb22b9..8246e3ce7544ffe0438720344e54c841ab458075 100644 (file)
 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);
 }
 
 /*
index ef19810091fff845243bdf9cd6df1c5dfd09bf77..7d276756e0ec0150ef63c4c2b0483cdedf45cbb6 100644 (file)
@@ -420,28 +420,34 @@ void msdos_write_inode(struct inode *inode)
 }
 
 
-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;
 }
index 099f3ef96a462e8ccf5d0163b7f2e6bfe6b16668..542f1c472d9b1c1f676c60878b5c74af677cbd7b 100644 (file)
@@ -373,6 +373,7 @@ int open_namei(const char * pathname, int flag, int mode,
                        iput(inode);
                        return -EACCES;
                }
+               flag &= ~O_TRUNC;
        } else {
                if (IS_RDONLY(inode) && (flag & 2)) {
                        iput(inode);
@@ -404,14 +405,18 @@ int open_namei(const char * pathname, int flag, int mode,
                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;
index 2eec8ca48ed64656545b61bb53946efc3aedff35..17f2cb6f0d970d17c73c4ca258c94875ad590e2f 100644 (file)
@@ -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 @@ struct inode *nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle,
        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 = sattr.gid = (unsigned) -1;
-       if (flags & NOTIFY_SIZE)
-               sattr.size = S_ISREG(inode->i_mode) ? inode->i_size : -1;
+               sattr.uid = (unsigned) -1;
+
+       if (attr->ia_valid & ATTR_GID)
+               sattr.gid = attr->ia_gid;
+       else
+               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 @@ int nfs_notify_change(int flags, struct inode *inode)
        inode->i_dirt = 0;
        return error;
 }
-
index 08d80514c2b6d69c2823d14253af2532ac678875..e72ef7bf657ce8084f9c597e221ad12f612b5098 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -69,6 +69,7 @@ asmlinkage int sys_truncate(const char * path, unsigned int length)
 {
        struct inode * inode;
        int error;
+       struct iattr newattrs;
 
        error = namei(path,&inode);
        if (error)
@@ -85,12 +86,13 @@ asmlinkage int sys_truncate(const char * path, unsigned int length)
                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 @@ asmlinkage int sys_ftruncate(unsigned int fd, unsigned int length)
 {
        struct inode * inode;
        struct file * file;
+       struct iattr newattrs;
 
        if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
                return -EBADF;
@@ -108,12 +111,13 @@ asmlinkage int sys_ftruncate(unsigned int fd, unsigned int length)
                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 @@ asmlinkage int sys_utime(char * filename, struct utimbuf * times)
        struct inode * inode;
        long actime,modtime;
        int error;
+       struct iattr newattrs;
 
        error = namei(filename,&inode);
        if (error)
@@ -140,19 +145,20 @@ asmlinkage int sys_utime(char * filename, struct utimbuf * times)
                }
                actime = get_fs_long((unsigned long *) &times->actime);
                modtime = get_fs_long((unsigned long *) &times->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 @@ asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
 {
        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 @@ asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group)
 {
        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 @@ asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group)
                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 @@ asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
                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);
 }
 
 /*
index 2ca380a254b58c95d6b31dcff34a1020bd428804..3dcf0189bd209bebda336a11f4e7cfb8d58f1fc1 100644 (file)
@@ -69,8 +69,6 @@ static struct proc_dir_entry base_dir[] = {
 
 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 @@ int proc_match(int len,const char * name,struct proc_dir_entry * de)
                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,
index c2717df2e765740d40febd8f985d87806eec2b89..9c3b43d9858fe5195fa83342fc6ff9e4d2be1e8a 100644 (file)
@@ -159,8 +159,10 @@ asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count)
         * 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;
 }
index e8d5e3d87e886c6efc24c0e976f1df749de43ed6..0a89b37f7f5776c3a72cf33349b454460f022f5d 100644 (file)
    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 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
                        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 @@ int sysv_new_block(struct super_block * sb)
                        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);
index 07ef17030b0df9f68e90a20f256da8ceb6b7ea81..bb5c026741572344cd6b0bc8e6fed85a2ccc6ddb 100644 (file)
@@ -715,9 +715,16 @@ void sysv_read_inode(struct inode * inode)
 }
 
 /* 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;
index 2bf21afdd8fd8f5efabfb4a377f5a7d54c9fb04c..a0c7ef59a15f94aed8b442c0890c690275b8e8b0 100644 (file)
 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 && buffer[len]) then buffer is longer than name */
-       return 0;
+       if (len > maxlen)
+               return 0;
+       if (len < maxlen && buffer[len])
+               return 0;
+       return !memcmp(name, buffer, len);
 }
 
 /*
index c813d4107c194e9edc06ac08e2dde9ec5880a735..4227f33819be97ac2804736b7595584c5bf3623c 100644 (file)
@@ -257,13 +257,24 @@ void UMSDOS_read_inode(struct inode *inode)
 */
 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 @@ int UMSDOS_notify_change (int flags, struct inode *inode)
                                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 @@ int UMSDOS_notify_change (int flags, struct inode *inode)
                                                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;
 }
 
index 3ec2ff6178bea886d070319e877bd5ee5caaca1d..2c2f55f059ac8972dc4d6de864e3421c01fbc751 100644 (file)
@@ -618,7 +618,7 @@ int UMSDOS_link (
        }
        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 @@ int UMSDOS_unlink (
                                                                iput (hdir);
                                                        }
                                                }else{
-                                                       ret = UMSDOS_notify_change (0,inode);
+                                                       ret = UMSDOS_notify_change (0,NULL,inode);
                                                }
                                                iput (inode);
                                        }
index e91f63cd368277445670a476903c3cb67e4422bb..089829481fb2be1c20f0b7e9c3c64bab944ba31e 100644 (file)
 #include <linux/kernel.h>
 #include <linux/string.h>
 
-#include "xiafs_mac.h"
+#include <asm/bitops.h>
 
+#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 @@ zone_found:
     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 @@ void xiafs_free_zone(struct super_block * sb, int d_addr)
     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 @@ void xiafs_free_inode(struct inode * inode)
     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 --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
new file mode 100644 (file)
index 0000000..fa43605
--- /dev/null
@@ -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 */
index a7d01f3c0b92d3b8831a01d9786bcd8775ca6ded..7240fc7157c80da6826733af5b279c06e51c934f 100644 (file)
@@ -127,13 +127,6 @@ extern unsigned long name_cache_init(unsigned long start, unsigned long end);
 #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 @@ struct buffer_head {
 
 #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 <warlord@MIT.EDU> 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 inode_operations {
 
 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 void sync_dev(dev_t dev);
 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);
@@ -483,6 +508,9 @@ extern int file_fsync(struct inode *, struct file *);
 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)
 {
        return __iget(sb,nr,1);
index 3a553f58a00f492f8d5827b66f1821550089fd12..df88b8720a3354b14f7c7bc28deca9c3eab15db6 100644 (file)
@@ -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 */
 #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         */
 #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 @@ struct hd_driveid {
        /* unsigned short vendor7  [32];*/      /* vendor unique (words 128-159) */
        /* unsigned short reservedyy[96];*/     /* reserved (words 160-255) */
 };
+#endif
index f66ccc2899302377cfadbe03f9f1572d67156b5b..41eb49e9fbfda62adeb7c1905bddf70aa67ce28c 100644 (file)
@@ -175,7 +175,7 @@ extern void msdos_statfs(struct super_block *sb,struct statfs *buf);
 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 */
 
index fcba989291bea5de926009a3d5b9930bc3a1acca..c498b44984c4c509095a9c25d60b7dc953fa1096 100644 (file)
@@ -421,7 +421,7 @@ extern void sysv_put_super(struct super_block *);
 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 *);
index 053541aded3e4c914634cc61d7dccac19cc932b2..ef91d03edfcbee81b1063880e490eb4d5ca9302a 100644 (file)
@@ -77,7 +77,7 @@ void umsdos_patch_inode (struct inode *inode,
 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);
index 5884fc4befa215c7ff415b2d26ca285cbaae0a0a..d41fcbb76fd233c0f883a37fd4506367b801886a 100644 (file)
@@ -157,7 +157,7 @@ static char fpu_error = 0;
 
 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,6 +253,11 @@ static void calibrate_delay(void)
 
        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;
@@ -271,7 +276,7 @@ static void calibrate_delay(void)
        }
        printk("failed\n");
 }
-       
+
 
 /*
  * This is a simple kernel command line parsing function: it parses
@@ -347,7 +352,7 @@ static void parse_options(char *line)
                /*
                 * Then check if it's an environment variable or
                 * an option.
-                */     
+                */
                if (strchr(line,'=')) {
                        if (envs >= MAX_INIT_ENVS)
                                break;
@@ -459,7 +464,7 @@ asmlinkage void start_kernel(void)
        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
index 1c56954a75854bbb9aab246d52adda996e8dae9f..144d93a024c700f68ed03f606520d550981a487e 100644 (file)
@@ -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)
 {
index 00748da06a0f1f6334fea6ef6b1fe12c785bc31e..b85f78420ca7b63c9b249ba80612219a11a2bb1f 100644 (file)
@@ -234,7 +234,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
 
                case 'p':
                        if (field_width == -1) {
-                               field_width = 8;
+                               field_width = 2*sizeof(void *);
                                flags |= ZEROPAD;
                        }
                        str = number(str,
index c304ee84780fea6ae8e2895ca4c72f0c7af6c443..ebaa521a9812c9e90b026af2675317a721fa0704 100644 (file)
@@ -240,7 +240,7 @@ int copy_page_tables(struct task_struct * tsk)
                        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;
                }