diff --git a/[refs] b/[refs] index d4b7ba37b9b5..dd3e02277759 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7d32c0aca4fbd0319c860d12af5fae3e88c760e6 +refs/heads/master: b1f3bb494e8acddeb972331c2ac642b3c7bceeb9 diff --git a/trunk/arch/alpha/include/asm/atomic.h b/trunk/arch/alpha/include/asm/atomic.h index e756d04b6cd5..610dff44d94b 100644 --- a/trunk/arch/alpha/include/asm/atomic.h +++ b/trunk/arch/alpha/include/asm/atomic.h @@ -17,8 +17,8 @@ #define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) #define ATOMIC64_INIT(i) ( (atomic64_t) { (i) } ) -#define atomic_read(v) (*(volatile int *)&(v)->counter) -#define atomic64_read(v) (*(volatile long *)&(v)->counter) +#define atomic_read(v) ((v)->counter + 0) +#define atomic64_read(v) ((v)->counter + 0) #define atomic_set(v,i) ((v)->counter = (i)) #define atomic64_set(v,i) ((v)->counter = (i)) diff --git a/trunk/arch/arm/include/asm/atomic.h b/trunk/arch/arm/include/asm/atomic.h index a0162fa94564..e8ddec2cb158 100644 --- a/trunk/arch/arm/include/asm/atomic.h +++ b/trunk/arch/arm/include/asm/atomic.h @@ -24,7 +24,7 @@ * strex/ldrex monitor on some implementations. The reason we can use it for * atomic_set() is the clrex or dummy strex done on every exception return. */ -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) #if __LINUX_ARM_ARCH__ >= 6 diff --git a/trunk/arch/avr32/include/asm/atomic.h b/trunk/arch/avr32/include/asm/atomic.h index bbce6a1c6bb6..b131c27ddf57 100644 --- a/trunk/arch/avr32/include/asm/atomic.h +++ b/trunk/arch/avr32/include/asm/atomic.h @@ -19,7 +19,7 @@ #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) #define atomic_set(v, i) (((v)->counter) = i) /* diff --git a/trunk/arch/cris/include/asm/atomic.h b/trunk/arch/cris/include/asm/atomic.h index 88dc9b9c4ba0..a6aca819e9f3 100644 --- a/trunk/arch/cris/include/asm/atomic.h +++ b/trunk/arch/cris/include/asm/atomic.h @@ -15,7 +15,7 @@ #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) /* These should be written in asm but we do it in C for now. */ diff --git a/trunk/arch/frv/include/asm/atomic.h b/trunk/arch/frv/include/asm/atomic.h index fae32c7fdcb6..00a57af79afc 100644 --- a/trunk/arch/frv/include/asm/atomic.h +++ b/trunk/arch/frv/include/asm/atomic.h @@ -36,7 +36,7 @@ #define smp_mb__after_atomic_inc() barrier() #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) #define atomic_set(v, i) (((v)->counter) = (i)) #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS diff --git a/trunk/arch/h8300/include/asm/atomic.h b/trunk/arch/h8300/include/asm/atomic.h index e936804b7508..33c8c0fa9583 100644 --- a/trunk/arch/h8300/include/asm/atomic.h +++ b/trunk/arch/h8300/include/asm/atomic.h @@ -10,7 +10,7 @@ #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) #define atomic_set(v, i) (((v)->counter) = i) #include diff --git a/trunk/arch/ia64/include/asm/atomic.h b/trunk/arch/ia64/include/asm/atomic.h index 4e1948447a00..88405cb0832a 100644 --- a/trunk/arch/ia64/include/asm/atomic.h +++ b/trunk/arch/ia64/include/asm/atomic.h @@ -21,8 +21,8 @@ #define ATOMIC_INIT(i) ((atomic_t) { (i) }) #define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) -#define atomic_read(v) (*(volatile int *)&(v)->counter) -#define atomic64_read(v) (*(volatile long *)&(v)->counter) +#define atomic_read(v) ((v)->counter) +#define atomic64_read(v) ((v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) #define atomic64_set(v,i) (((v)->counter) = (i)) diff --git a/trunk/arch/m32r/include/asm/atomic.h b/trunk/arch/m32r/include/asm/atomic.h index d44a51e5271b..63f0cf0f50dd 100644 --- a/trunk/arch/m32r/include/asm/atomic.h +++ b/trunk/arch/m32r/include/asm/atomic.h @@ -26,7 +26,7 @@ * * Atomically reads the value of @v. */ -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) /** * atomic_set - set atomic variable diff --git a/trunk/arch/m68k/bvme6000/rtc.c b/trunk/arch/m68k/bvme6000/rtc.c index b46ea1714a89..cb8617bb194b 100644 --- a/trunk/arch/m68k/bvme6000/rtc.c +++ b/trunk/arch/m68k/bvme6000/rtc.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -35,10 +34,9 @@ static unsigned char days_in_mo[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -static char rtc_status; +static atomic_t rtc_status = ATOMIC_INIT(1); -static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE; unsigned char msr; @@ -132,29 +130,20 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } /* - * We enforce only one user at a time here with the open/close. - * Also clear the previous interrupt data on an open, and clean - * up things on a close. + * We enforce only one user at a time here with the open/close. */ - static int rtc_open(struct inode *inode, struct file *file) { - lock_kernel(); - if(rtc_status) { - unlock_kernel(); + if (!atomic_dec_and_test(&rtc_status)) { + atomic_inc(&rtc_status); return -EBUSY; } - - rtc_status = 1; - unlock_kernel(); return 0; } static int rtc_release(struct inode *inode, struct file *file) { - lock_kernel(); - rtc_status = 0; - unlock_kernel(); + atomic_inc(&rtc_status); return 0; } @@ -163,9 +152,9 @@ static int rtc_release(struct inode *inode, struct file *file) */ static const struct file_operations rtc_fops = { - .ioctl = rtc_ioctl, - .open = rtc_open, - .release = rtc_release, + .unlocked_ioctl = rtc_ioctl, + .open = rtc_open, + .release = rtc_release, }; static struct miscdevice rtc_dev = { diff --git a/trunk/arch/m68k/include/asm/atomic_mm.h b/trunk/arch/m68k/include/asm/atomic_mm.h index 6a223b3f7e74..d9d2ed647435 100644 --- a/trunk/arch/m68k/include/asm/atomic_mm.h +++ b/trunk/arch/m68k/include/asm/atomic_mm.h @@ -15,7 +15,7 @@ #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) #define atomic_set(v, i) (((v)->counter) = i) static inline void atomic_add(int i, atomic_t *v) diff --git a/trunk/arch/m68k/include/asm/atomic_no.h b/trunk/arch/m68k/include/asm/atomic_no.h index 289310c63a8a..5674cb9449bd 100644 --- a/trunk/arch/m68k/include/asm/atomic_no.h +++ b/trunk/arch/m68k/include/asm/atomic_no.h @@ -15,7 +15,7 @@ #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) #define atomic_set(v, i) (((v)->counter) = i) static __inline__ void atomic_add(int i, atomic_t *v) diff --git a/trunk/arch/m68k/mvme16x/rtc.c b/trunk/arch/m68k/mvme16x/rtc.c index 8da9c250d3e1..11ac6f63967a 100644 --- a/trunk/arch/m68k/mvme16x/rtc.c +++ b/trunk/arch/m68k/mvme16x/rtc.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -36,8 +35,7 @@ static const unsigned char days_in_mo[] = static atomic_t rtc_ready = ATOMIC_INIT(1); -static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { volatile MK48T08ptr_t rtc = (MK48T08ptr_t)MVME_RTC_BASE; unsigned long flags; @@ -120,22 +118,15 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } /* - * We enforce only one user at a time here with the open/close. - * Also clear the previous interrupt data on an open, and clean - * up things on a close. + * We enforce only one user at a time here with the open/close. */ - static int rtc_open(struct inode *inode, struct file *file) { - lock_kernel(); if( !atomic_dec_and_test(&rtc_ready) ) { atomic_inc( &rtc_ready ); - unlock_kernel(); return -EBUSY; } - unlock_kernel(); - return 0; } @@ -150,9 +141,9 @@ static int rtc_release(struct inode *inode, struct file *file) */ static const struct file_operations rtc_fops = { - .ioctl = rtc_ioctl, - .open = rtc_open, - .release = rtc_release, + .unlocked_ioctl = rtc_ioctl, + .open = rtc_open, + .release = rtc_release, }; static struct miscdevice rtc_dev= diff --git a/trunk/arch/mips/include/asm/atomic.h b/trunk/arch/mips/include/asm/atomic.h index 59dc0c7ef733..519197ede089 100644 --- a/trunk/arch/mips/include/asm/atomic.h +++ b/trunk/arch/mips/include/asm/atomic.h @@ -29,7 +29,7 @@ * * Atomically reads the value of @v. */ -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) /* * atomic_set - set atomic variable @@ -410,7 +410,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) * @v: pointer of type atomic64_t * */ -#define atomic64_read(v) (*(volatile long *)&(v)->counter) +#define atomic64_read(v) ((v)->counter) /* * atomic64_set - set atomic variable diff --git a/trunk/arch/mn10300/include/asm/atomic.h b/trunk/arch/mn10300/include/asm/atomic.h index e41222d6c2fd..5bf5be9566de 100644 --- a/trunk/arch/mn10300/include/asm/atomic.h +++ b/trunk/arch/mn10300/include/asm/atomic.h @@ -31,7 +31,7 @@ * Atomically reads the value of @v. Note that the guaranteed * useful range of an atomic_t is only 24 bits. */ -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) /** * atomic_set - set atomic variable diff --git a/trunk/arch/parisc/include/asm/atomic.h b/trunk/arch/parisc/include/asm/atomic.h index f81955934aeb..716634d1f546 100644 --- a/trunk/arch/parisc/include/asm/atomic.h +++ b/trunk/arch/parisc/include/asm/atomic.h @@ -189,7 +189,7 @@ static __inline__ void atomic_set(atomic_t *v, int i) static __inline__ int atomic_read(const atomic_t *v) { - return (*(volatile int *)&(v)->counter); + return v->counter; } /* exported interface */ @@ -286,7 +286,7 @@ atomic64_set(atomic64_t *v, s64 i) static __inline__ s64 atomic64_read(const atomic64_t *v) { - return (*(volatile long *)&(v)->counter); + return v->counter; } #define atomic64_add(i,v) ((void)(__atomic64_add_return( ((s64)(i)),(v)))) diff --git a/trunk/arch/sh/include/asm/atomic.h b/trunk/arch/sh/include/asm/atomic.h index c7983124d99d..275a448ae8c2 100644 --- a/trunk/arch/sh/include/asm/atomic.h +++ b/trunk/arch/sh/include/asm/atomic.h @@ -13,7 +13,7 @@ #define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) #define atomic_set(v,i) ((v)->counter = (i)) #if defined(CONFIG_GUSA_RB) diff --git a/trunk/arch/sparc/include/asm/atomic_32.h b/trunk/arch/sparc/include/asm/atomic_32.h index 7ae128b19d3f..f0d343c3b956 100644 --- a/trunk/arch/sparc/include/asm/atomic_32.h +++ b/trunk/arch/sparc/include/asm/atomic_32.h @@ -25,7 +25,7 @@ extern int atomic_cmpxchg(atomic_t *, int, int); extern int atomic_add_unless(atomic_t *, int, int); extern void atomic_set(atomic_t *, int); -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) #define atomic_add(i, v) ((void)__atomic_add_return( (int)(i), (v))) #define atomic_sub(i, v) ((void)__atomic_add_return(-(int)(i), (v))) diff --git a/trunk/arch/sparc/include/asm/atomic_64.h b/trunk/arch/sparc/include/asm/atomic_64.h index 2050ca02c423..f2e48009989e 100644 --- a/trunk/arch/sparc/include/asm/atomic_64.h +++ b/trunk/arch/sparc/include/asm/atomic_64.h @@ -13,8 +13,8 @@ #define ATOMIC_INIT(i) { (i) } #define ATOMIC64_INIT(i) { (i) } -#define atomic_read(v) (*(volatile int *)&(v)->counter) -#define atomic64_read(v) (*(volatile long *)&(v)->counter) +#define atomic_read(v) ((v)->counter) +#define atomic64_read(v) ((v)->counter) #define atomic_set(v, i) (((v)->counter) = i) #define atomic64_set(v, i) (((v)->counter) = i) diff --git a/trunk/arch/x86/include/asm/atomic.h b/trunk/arch/x86/include/asm/atomic.h index 37b39d27abe0..8f8217b9bdac 100644 --- a/trunk/arch/x86/include/asm/atomic.h +++ b/trunk/arch/x86/include/asm/atomic.h @@ -22,7 +22,7 @@ */ static inline int atomic_read(const atomic_t *v) { - return (*(volatile int *)&(v)->counter); + return v->counter; } /** diff --git a/trunk/arch/x86/include/asm/atomic64_64.h b/trunk/arch/x86/include/asm/atomic64_64.h index b014e235ea8d..51c5b4056929 100644 --- a/trunk/arch/x86/include/asm/atomic64_64.h +++ b/trunk/arch/x86/include/asm/atomic64_64.h @@ -18,7 +18,7 @@ */ static inline long atomic64_read(const atomic64_t *v) { - return (*(volatile long *)&(v)->counter); + return v->counter; } /** diff --git a/trunk/arch/xtensa/include/asm/atomic.h b/trunk/arch/xtensa/include/asm/atomic.h index a96a0619d0b7..22d6dde42619 100644 --- a/trunk/arch/xtensa/include/asm/atomic.h +++ b/trunk/arch/xtensa/include/asm/atomic.h @@ -46,7 +46,7 @@ * * Atomically reads the value of @v. */ -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) /** * atomic_set - set atomic variable diff --git a/trunk/fs/logfs/dev_bdev.c b/trunk/fs/logfs/dev_bdev.c index 9bd2ce2a3040..243c00071f76 100644 --- a/trunk/fs/logfs/dev_bdev.c +++ b/trunk/fs/logfs/dev_bdev.c @@ -303,11 +303,6 @@ static void bdev_put_device(struct super_block *sb) close_bdev_exclusive(logfs_super(sb)->s_bdev, FMODE_READ|FMODE_WRITE); } -static int bdev_can_write_buf(struct super_block *sb, u64 ofs) -{ - return 0; -} - static const struct logfs_device_ops bd_devops = { .find_first_sb = bdev_find_first_sb, .find_last_sb = bdev_find_last_sb, @@ -315,7 +310,6 @@ static const struct logfs_device_ops bd_devops = { .readpage = bdev_readpage, .writeseg = bdev_writeseg, .erase = bdev_erase, - .can_write_buf = bdev_can_write_buf, .sync = bdev_sync, .put_device = bdev_put_device, }; diff --git a/trunk/fs/logfs/dev_mtd.c b/trunk/fs/logfs/dev_mtd.c index a85d47d13e4b..cafb6ef2e05b 100644 --- a/trunk/fs/logfs/dev_mtd.c +++ b/trunk/fs/logfs/dev_mtd.c @@ -9,7 +9,6 @@ #include #include #include -#include #define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1)) @@ -127,8 +126,7 @@ static int mtd_readpage(void *_sb, struct page *page) err = mtd_read(sb, page->index << PAGE_SHIFT, PAGE_SIZE, page_address(page)); - if (err == -EUCLEAN || err == -EBADMSG) { - /* -EBADMSG happens regularly on power failures */ + if (err == -EUCLEAN) { err = 0; /* FIXME: force GC this segment */ } @@ -235,32 +233,12 @@ static void mtd_put_device(struct super_block *sb) put_mtd_device(logfs_super(sb)->s_mtd); } -static int mtd_can_write_buf(struct super_block *sb, u64 ofs) -{ - struct logfs_super *super = logfs_super(sb); - void *buf; - int err; - - buf = kmalloc(super->s_writesize, GFP_KERNEL); - if (!buf) - return -ENOMEM; - err = mtd_read(sb, ofs, super->s_writesize, buf); - if (err) - goto out; - if (memchr_inv(buf, 0xff, super->s_writesize)) - err = -EIO; - kfree(buf); -out: - return err; -} - static const struct logfs_device_ops mtd_devops = { .find_first_sb = mtd_find_first_sb, .find_last_sb = mtd_find_last_sb, .readpage = mtd_readpage, .writeseg = mtd_writeseg, .erase = mtd_erase, - .can_write_buf = mtd_can_write_buf, .sync = mtd_sync, .put_device = mtd_put_device, }; @@ -272,7 +250,5 @@ int logfs_get_sb_mtd(struct file_system_type *type, int flags, const struct logfs_device_ops *devops = &mtd_devops; mtd = get_mtd_device(NULL, mtdnr); - if (IS_ERR(mtd)) - return PTR_ERR(mtd); return logfs_get_sb_device(type, flags, mtd, NULL, devops, mnt); } diff --git a/trunk/fs/logfs/file.c b/trunk/fs/logfs/file.c index 0de524071870..370f367a933e 100644 --- a/trunk/fs/logfs/file.c +++ b/trunk/fs/logfs/file.c @@ -161,17 +161,7 @@ static int logfs_writepage(struct page *page, struct writeback_control *wbc) static void logfs_invalidatepage(struct page *page, unsigned long offset) { - struct logfs_block *block = logfs_block(page); - - if (block->reserved_bytes) { - struct super_block *sb = page->mapping->host->i_sb; - struct logfs_super *super = logfs_super(sb); - - super->s_dirty_pages -= block->reserved_bytes; - block->ops->free_block(sb, block); - BUG_ON(bitmap_weight(block->alias_map, LOGFS_BLOCK_FACTOR)); - } else - move_page_to_btree(page); + move_page_to_btree(page); BUG_ON(PagePrivate(page) || page->private); } @@ -222,8 +212,10 @@ int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, int logfs_fsync(struct file *file, struct dentry *dentry, int datasync) { struct super_block *sb = dentry->d_inode->i_sb; + struct logfs_super *super = logfs_super(sb); - logfs_write_anchor(sb); + /* FIXME: write anchor */ + super->s_devops->sync(sb); return 0; } diff --git a/trunk/fs/logfs/gc.c b/trunk/fs/logfs/gc.c index caa4419285dc..76c242fbe1b0 100644 --- a/trunk/fs/logfs/gc.c +++ b/trunk/fs/logfs/gc.c @@ -122,7 +122,7 @@ static void logfs_cleanse_block(struct super_block *sb, u64 ofs, u64 ino, logfs_safe_iput(inode, cookie); } -static u32 logfs_gc_segment(struct super_block *sb, u32 segno) +static u32 logfs_gc_segment(struct super_block *sb, u32 segno, u8 dist) { struct logfs_super *super = logfs_super(sb); struct logfs_segment_header sh; @@ -401,7 +401,7 @@ static int __logfs_gc_once(struct super_block *sb, struct gc_candidate *cand) segno, (u64)segno << super->s_segshift, dist, no_free_segments(sb), valid, super->s_free_bytes); - cleaned = logfs_gc_segment(sb, segno); + cleaned = logfs_gc_segment(sb, segno, dist); log_gc("GC segment #%02x complete - now %x valid\n", segno, valid - cleaned); BUG_ON(cleaned != valid); @@ -632,31 +632,38 @@ static int check_area(struct super_block *sb, int i) { struct logfs_super *super = logfs_super(sb); struct logfs_area *area = super->s_area[i]; - gc_level_t gc_level; - u32 cleaned, valid, ec; + struct logfs_object_header oh; u32 segno = area->a_segno; - u64 ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes); + u32 ofs = area->a_used_bytes; + __be32 crc; + int err; if (!area->a_is_open) return 0; - if (super->s_devops->can_write_buf(sb, ofs) == 0) - return 0; + for (ofs = area->a_used_bytes; + ofs <= super->s_segsize - sizeof(oh); + ofs += (u32)be16_to_cpu(oh.len) + sizeof(oh)) { + err = wbuf_read(sb, dev_ofs(sb, segno, ofs), sizeof(oh), &oh); + if (err) + return err; - printk(KERN_INFO"LogFS: Possibly incomplete write at %llx\n", ofs); - /* - * The device cannot write back the write buffer. Most likely the - * wbuf was already written out and the system crashed at some point - * before the journal commit happened. In that case we wouldn't have - * to do anything. But if the crash happened before the wbuf was - * written out correctly, we must GC this segment. So assume the - * worst and always do the GC run. - */ - area->a_is_open = 0; - valid = logfs_valid_bytes(sb, segno, &ec, &gc_level); - cleaned = logfs_gc_segment(sb, segno); - if (cleaned != valid) - return -EIO; + if (!memchr_inv(&oh, 0xff, sizeof(oh))) + break; + + crc = logfs_crc32(&oh, sizeof(oh) - 4, 4); + if (crc != oh.crc) { + printk(KERN_INFO "interrupted header at %llx\n", + dev_ofs(sb, segno, ofs)); + return 0; + } + } + if (ofs != area->a_used_bytes) { + printk(KERN_INFO "%x bytes unaccounted data found at %llx\n", + ofs - area->a_used_bytes, + dev_ofs(sb, segno, area->a_used_bytes)); + area->a_used_bytes = ofs; + } return 0; } diff --git a/trunk/fs/logfs/inode.c b/trunk/fs/logfs/inode.c index 755a92e8daa7..14ed27274da2 100644 --- a/trunk/fs/logfs/inode.c +++ b/trunk/fs/logfs/inode.c @@ -193,7 +193,6 @@ static void logfs_init_inode(struct super_block *sb, struct inode *inode) inode->i_ctime = CURRENT_TIME; inode->i_mtime = CURRENT_TIME; inode->i_nlink = 1; - li->li_refcount = 1; INIT_LIST_HEAD(&li->li_freeing_list); for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++) @@ -327,7 +326,7 @@ static void logfs_set_ino_generation(struct super_block *sb, u64 ino; mutex_lock(&super->s_journal_mutex); - ino = logfs_seek_hole(super->s_master_inode, super->s_last_ino + 1); + ino = logfs_seek_hole(super->s_master_inode, super->s_last_ino); super->s_last_ino = ino; super->s_inos_till_wrap--; if (super->s_inos_till_wrap < 0) { @@ -387,7 +386,8 @@ static void logfs_init_once(void *_li) static int logfs_sync_fs(struct super_block *sb, int wait) { - logfs_write_anchor(sb); + /* FIXME: write anchor */ + logfs_super(sb)->s_devops->sync(sb); return 0; } diff --git a/trunk/fs/logfs/journal.c b/trunk/fs/logfs/journal.c index 4b0e0616b357..fb0a613f885b 100644 --- a/trunk/fs/logfs/journal.c +++ b/trunk/fs/logfs/journal.c @@ -132,9 +132,10 @@ static int read_area(struct super_block *sb, struct logfs_je_area *a) ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes); if (super->s_writesize > 1) - return logfs_buf_recover(area, ofs, a + 1, super->s_writesize); + logfs_buf_recover(area, ofs, a + 1, super->s_writesize); else - return logfs_buf_recover(area, ofs, NULL, 0); + logfs_buf_recover(area, ofs, NULL, 0); + return 0; } static void *unpack(void *from, void *to) @@ -244,7 +245,7 @@ static int read_je(struct super_block *sb, u64 ofs) read_erasecount(sb, unpack(jh, scratch)); break; case JE_AREA: - err = read_area(sb, unpack(jh, scratch)); + read_area(sb, unpack(jh, scratch)); break; case JE_OBJ_ALIAS: err = logfs_load_object_aliases(sb, unpack(jh, scratch), diff --git a/trunk/fs/logfs/logfs.h b/trunk/fs/logfs/logfs.h index 93b55f337245..0a3df1a0c936 100644 --- a/trunk/fs/logfs/logfs.h +++ b/trunk/fs/logfs/logfs.h @@ -144,7 +144,6 @@ struct logfs_area_ops { * @erase: erase one segment * @read: read from the device * @erase: erase part of the device - * @can_write_buf: decide whether wbuf can be written to ofs */ struct logfs_device_ops { struct page *(*find_first_sb)(struct super_block *sb, u64 *ofs); @@ -154,7 +153,6 @@ struct logfs_device_ops { void (*writeseg)(struct super_block *sb, u64 ofs, size_t len); int (*erase)(struct super_block *sb, loff_t ofs, size_t len, int ensure_write); - int (*can_write_buf)(struct super_block *sb, u64 ofs); void (*sync)(struct super_block *sb); void (*put_device)(struct super_block *sb); }; @@ -396,7 +394,6 @@ struct logfs_super { int s_lock_count; mempool_t *s_block_pool; /* struct logfs_block pool */ mempool_t *s_shadow_pool; /* struct logfs_shadow pool */ - struct list_head s_writeback_list; /* writeback pages */ /* * Space accounting: * - s_used_bytes specifies space used to store valid data objects. @@ -601,19 +598,19 @@ void freeseg(struct super_block *sb, u32 segno); int logfs_init_areas(struct super_block *sb); void logfs_cleanup_areas(struct super_block *sb); int logfs_open_area(struct logfs_area *area, size_t bytes); -int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, +void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, int use_filler); -static inline int logfs_buf_write(struct logfs_area *area, u64 ofs, +static inline void logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len) { - return __logfs_buf_write(area, ofs, buf, len, 0); + __logfs_buf_write(area, ofs, buf, len, 0); } -static inline int logfs_buf_recover(struct logfs_area *area, u64 ofs, +static inline void logfs_buf_recover(struct logfs_area *area, u64 ofs, void *buf, size_t len) { - return __logfs_buf_write(area, ofs, buf, len, 1); + __logfs_buf_write(area, ofs, buf, len, 1); } /* super.c */ diff --git a/trunk/fs/logfs/readwrite.c b/trunk/fs/logfs/readwrite.c index 0718d112a1a5..3159db6958e5 100644 --- a/trunk/fs/logfs/readwrite.c +++ b/trunk/fs/logfs/readwrite.c @@ -892,8 +892,6 @@ u64 logfs_seek_hole(struct inode *inode, u64 bix) return bix; else if (li->li_data[INDIRECT_INDEX] & LOGFS_FULLY_POPULATED) bix = maxbix(li->li_height); - else if (bix >= maxbix(li->li_height)) - return bix; else { bix = seek_holedata_loop(inode, bix, 0); if (bix < maxbix(li->li_height)) @@ -1095,25 +1093,17 @@ static int logfs_reserve_bytes(struct inode *inode, int bytes) int get_page_reserve(struct inode *inode, struct page *page) { struct logfs_super *super = logfs_super(inode->i_sb); - struct logfs_block *block = logfs_block(page); int ret; - if (block && block->reserved_bytes) + if (logfs_block(page) && logfs_block(page)->reserved_bytes) return 0; logfs_get_wblocks(inode->i_sb, page, WF_LOCK); - while ((ret = logfs_reserve_bytes(inode, 6 * LOGFS_MAX_OBJECTSIZE)) && - !list_empty(&super->s_writeback_list)) { - block = list_entry(super->s_writeback_list.next, - struct logfs_block, alias_list); - block->ops->write_block(block); - } + ret = logfs_reserve_bytes(inode, 6 * LOGFS_MAX_OBJECTSIZE); if (!ret) { alloc_data_block(inode, page); - block = logfs_block(page); - block->reserved_bytes += 6 * LOGFS_MAX_OBJECTSIZE; + logfs_block(page)->reserved_bytes += 6 * LOGFS_MAX_OBJECTSIZE; super->s_dirty_pages += 6 * LOGFS_MAX_OBJECTSIZE; - list_move_tail(&block->alias_list, &super->s_writeback_list); } logfs_put_wblocks(inode->i_sb, page, WF_LOCK); return ret; @@ -1871,7 +1861,7 @@ int logfs_truncate(struct inode *inode, u64 target) size = target; logfs_get_wblocks(sb, NULL, 1); - err = __logfs_truncate(inode, size); + err = __logfs_truncate(inode, target); if (!err) err = __logfs_write_inode(inode, 0); logfs_put_wblocks(sb, NULL, 1); @@ -2259,7 +2249,6 @@ int logfs_init_rw(struct super_block *sb) int min_fill = 3 * super->s_no_blocks; INIT_LIST_HEAD(&super->s_object_alias); - INIT_LIST_HEAD(&super->s_writeback_list); mutex_init(&super->s_write_mutex); super->s_block_pool = mempool_create_kmalloc_pool(min_fill, sizeof(struct logfs_block)); diff --git a/trunk/fs/logfs/segment.c b/trunk/fs/logfs/segment.c index a9657afb70ad..f77ce2b470ba 100644 --- a/trunk/fs/logfs/segment.c +++ b/trunk/fs/logfs/segment.c @@ -67,7 +67,7 @@ static struct page *get_mapping_page(struct super_block *sb, pgoff_t index, return page; } -int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, +void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, int use_filler) { pgoff_t index = ofs >> PAGE_SHIFT; @@ -81,10 +81,8 @@ int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, copylen = min((ulong)len, PAGE_SIZE - offset); page = get_mapping_page(area->a_sb, index, use_filler); - if (IS_ERR(page)) - return PTR_ERR(page); - BUG_ON(!page); /* FIXME: reserve a pool */ SetPageUptodate(page); + BUG_ON(!page); /* FIXME: reserve a pool */ memcpy(page_address(page) + offset, buf, copylen); SetPagePrivate(page); page_cache_release(page); @@ -94,7 +92,6 @@ int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, offset = 0; index++; } while (len); - return 0; } static void pad_partial_page(struct logfs_area *area) diff --git a/trunk/fs/logfs/super.c b/trunk/fs/logfs/super.c index d651e10a1e9c..d7c23ed8349a 100644 --- a/trunk/fs/logfs/super.c +++ b/trunk/fs/logfs/super.c @@ -138,14 +138,10 @@ static int logfs_sb_set(struct super_block *sb, void *_super) sb->s_fs_info = super; sb->s_mtd = super->s_mtd; sb->s_bdev = super->s_bdev; -#ifdef CONFIG_BLOCK if (sb->s_bdev) sb->s_bdi = &bdev_get_queue(sb->s_bdev)->backing_dev_info; -#endif -#ifdef CONFIG_MTD if (sb->s_mtd) sb->s_bdi = sb->s_mtd->backing_dev_info; -#endif return 0; } @@ -386,7 +382,7 @@ static struct page *find_super_block(struct super_block *sb) if (!first || IS_ERR(first)) return NULL; last = super->s_devops->find_last_sb(sb, &super->s_sb_ofs[1]); - if (!last || IS_ERR(last)) { + if (!last || IS_ERR(first)) { page_cache_release(first); return NULL; } @@ -417,7 +413,7 @@ static int __logfs_read_sb(struct super_block *sb) page = find_super_block(sb); if (!page) - return -EINVAL; + return -EIO; ds = page_address(page); super->s_size = be64_to_cpu(ds->ds_filesystem_size); diff --git a/trunk/include/asm-generic/atomic.h b/trunk/include/asm-generic/atomic.h index c33749f95b32..c99c64dc5f3d 100644 --- a/trunk/include/asm-generic/atomic.h +++ b/trunk/include/asm-generic/atomic.h @@ -33,7 +33,7 @@ * Atomically reads the value of @v. Note that the guaranteed * useful range of an atomic_t is only 24 bits. */ -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ((v)->counter) /** * atomic_set - set atomic variable diff --git a/trunk/include/linux/types.h b/trunk/include/linux/types.h index 23d237a075e2..c42724f8c802 100644 --- a/trunk/include/linux/types.h +++ b/trunk/include/linux/types.h @@ -188,12 +188,12 @@ typedef u32 phys_addr_t; typedef phys_addr_t resource_size_t; typedef struct { - int counter; + volatile int counter; } atomic_t; #ifdef CONFIG_64BIT typedef struct { - long counter; + volatile long counter; } atomic64_t; #endif diff --git a/trunk/kernel/ptrace.c b/trunk/kernel/ptrace.c index 2f0f50b450a3..42ad8ae729a0 100644 --- a/trunk/kernel/ptrace.c +++ b/trunk/kernel/ptrace.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -665,6 +666,10 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data) struct task_struct *child; long ret; + /* + * This lock_kernel fixes a subtle race with suid exec + */ + lock_kernel(); if (request == PTRACE_TRACEME) { ret = ptrace_traceme(); if (!ret) @@ -698,6 +703,7 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data) out_put_task_struct: put_task_struct(child); out: + unlock_kernel(); return ret; } @@ -807,6 +813,10 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, struct task_struct *child; long ret; + /* + * This lock_kernel fixes a subtle race with suid exec + */ + lock_kernel(); if (request == PTRACE_TRACEME) { ret = ptrace_traceme(); goto out; @@ -836,6 +846,7 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, out_put_task_struct: put_task_struct(child); out: + unlock_kernel(); return ret; } #endif /* CONFIG_COMPAT */