diff -urNp z/include/asm-i386/system.h zz/include/asm-i386/system.h --- z/include/asm-i386/system.h Tue Jul 16 12:06:58 2002 +++ zz/include/asm-i386/system.h Tue Jul 16 12:08:06 2002 @@ -167,7 +167,7 @@ static inline void __set_64bit (unsigned "lock cmpxchg8b (%0)\n\t" "jnz 1b" : /* no outputs */ - : "D"(ptr), + : "r"(ptr), "b"(low), "c"(high) : "ax","dx","memory"); @@ -198,6 +198,30 @@ static inline void __set_64bit_var (unsi __set_64bit(ptr, ll_low(value), ll_high(value)) ) /* + * The memory clobber is needed in the read side only if + * there is an unsafe writer before the read_64bit, which should + * never be the case, but just to be safe. + */ +static inline unsigned long long read_64bit(unsigned long long * ptr) +{ + unsigned long low, high; + + __asm__ __volatile__ ( + "\n1:\t" + "movl (%2), %%eax\n\t" + "movl 4(%2), %%edx\n\t" + "movl %%eax, %%ebx\n\t" + "movl %%edx, %%ecx\n\t" + "lock cmpxchg8b (%2)\n\t" + "jnz 1b" + : "=&b" (low), "=&c" (high) + : "r" (ptr) + : "ax","dx","memory"); + + return low | ((unsigned long long) high << 32); +} + +/* * Note: no "lock" prefix even on SMP: xchg always implies lock anyway * Note 2: xchg has side effect, so that attribute volatile is necessary, * but generally the primitive is invalid, *ptr is output argument. --ANK diff -urNp z/include/linux/fs.h zz/include/linux/fs.h --- z/include/linux/fs.h Tue Jul 16 12:07:05 2002 +++ zz/include/linux/fs.h Tue Jul 16 12:07:40 2002 @@ -536,6 +536,25 @@ struct inode { } u; }; +static inline loff_t i_size_read(struct inode * inode) +{ +#if BITS_PER_LONG==32 + return (loff_t) read_64bit((unsigned long long *) &inode->i_size); +#elif BITS_PER_LONG==64 + return inode->i_size; +#endif +} + +static inline void i_size_write(struct inode * inode, loff_t i_size) +{ +#if BITS_PER_LONG==32 + set_64bit((unsigned long long *) &inode->i_size, + (unsigned long long) i_size); +#elif BITS_PER_LONG==64 + inode->i_size = i_size; +#endif +} + static inline void inode_add_bytes(struct inode *inode, loff_t bytes) { inode->i_blocks += bytes >> 9;