Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 189250
b: refs/heads/master
c: 570b8fb
h: refs/heads/master
v: v3
  • Loading branch information
Mathieu Desnoyers authored and James Morris committed Mar 30, 2010
1 parent cf01c02 commit e8acdac
Show file tree
Hide file tree
Showing 15 changed files with 55 additions and 113 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4660d3d240ac6c92cd3ad33657ca302026bdc24b
refs/heads/master: 570b8fb505896e007fd3bb07573ba6640e51851d
4 changes: 1 addition & 3 deletions trunk/arch/x86/kernel/head32.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

#include <linux/init.h>
#include <linux/start_kernel.h>
#include <linux/mm.h>

#include <asm/setup.h>
#include <asm/sections.h>
Expand Down Expand Up @@ -45,10 +44,9 @@ void __init i386_start_kernel(void)
#ifdef CONFIG_BLK_DEV_INITRD
/* Reserve INITRD */
if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
/* Assume only end is not page aligned */
u64 ramdisk_image = boot_params.hdr.ramdisk_image;
u64 ramdisk_size = boot_params.hdr.ramdisk_size;
u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
u64 ramdisk_end = ramdisk_image + ramdisk_size;
reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
}
#endif
Expand Down
3 changes: 1 addition & 2 deletions trunk/arch/x86/kernel/head64.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,9 @@ void __init x86_64_start_reservations(char *real_mode_data)
#ifdef CONFIG_BLK_DEV_INITRD
/* Reserve INITRD */
if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
/* Assume only end is not page aligned */
unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
unsigned long ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
unsigned long ramdisk_end = ramdisk_image + ramdisk_size;
reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
}
#endif
Expand Down
10 changes: 4 additions & 6 deletions trunk/arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,17 +314,16 @@ static void __init reserve_brk(void)
#define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT)
static void __init relocate_initrd(void)
{
/* Assume only end is not page aligned */

u64 ramdisk_image = boot_params.hdr.ramdisk_image;
u64 ramdisk_size = boot_params.hdr.ramdisk_size;
u64 area_size = PAGE_ALIGN(ramdisk_size);
u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
u64 ramdisk_here;
unsigned long slop, clen, mapaddr;
char *p, *q;

/* We need to move the initrd down into lowmem */
ramdisk_here = find_e820_area(0, end_of_lowmem, area_size,
ramdisk_here = find_e820_area(0, end_of_lowmem, ramdisk_size,
PAGE_SIZE);

if (ramdisk_here == -1ULL)
Expand All @@ -333,7 +332,7 @@ static void __init relocate_initrd(void)

/* Note: this includes all the lowmem currently occupied by
the initrd, we rely on that fact to keep the data intact. */
reserve_early(ramdisk_here, ramdisk_here + area_size,
reserve_early(ramdisk_here, ramdisk_here + ramdisk_size,
"NEW RAMDISK");
initrd_start = ramdisk_here + PAGE_OFFSET;
initrd_end = initrd_start + ramdisk_size;
Expand Down Expand Up @@ -377,10 +376,9 @@ static void __init relocate_initrd(void)

static void __init reserve_initrd(void)
{
/* Assume only end is not page aligned */
u64 ramdisk_image = boot_params.hdr.ramdisk_image;
u64 ramdisk_size = boot_params.hdr.ramdisk_size;
u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
u64 ramdisk_end = ramdisk_image + ramdisk_size;
u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;

if (!boot_params.hdr.type_of_loader ||
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/x86/kernel/vmlinux.lds.S
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,8 @@ SECTIONS
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
__smp_locks = .;
*(.smp_locks)
. = ALIGN(PAGE_SIZE);
__smp_locks_end = .;
. = ALIGN(PAGE_SIZE);
}

#ifdef CONFIG_X86_64
Expand Down
32 changes: 6 additions & 26 deletions trunk/arch/x86/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,31 +331,19 @@ int devmem_is_allowed(unsigned long pagenr)

void free_init_pages(char *what, unsigned long begin, unsigned long end)
{
unsigned long addr;
unsigned long begin_aligned, end_aligned;
unsigned long addr = begin;

/* Make sure boundaries are page aligned */
begin_aligned = PAGE_ALIGN(begin);
end_aligned = end & PAGE_MASK;

if (WARN_ON(begin_aligned != begin || end_aligned != end)) {
begin = begin_aligned;
end = end_aligned;
}

if (begin >= end)
if (addr >= end)
return;

addr = begin;

/*
* If debugging page accesses then do not free this memory but
* mark them not present - any buggy init-section access will
* create a kernel page fault:
*/
#ifdef CONFIG_DEBUG_PAGEALLOC
printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
begin, end);
begin, PAGE_ALIGN(end));
set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
#else
/*
Expand All @@ -370,7 +358,8 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
for (; addr < end; addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
init_page_count(virt_to_page(addr));
memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
memset((void *)(addr & ~(PAGE_SIZE-1)),
POISON_FREE_INITMEM, PAGE_SIZE);
free_page(addr);
totalram_pages++;
}
Expand All @@ -387,15 +376,6 @@ void free_initmem(void)
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
/*
* end could be not aligned, and We can not align that,
* decompresser could be confused by aligned initrd_end
* We already reserve the end partial page before in
* - i386_start_kernel()
* - x86_64_start_kernel()
* - relocate_initrd()
* So here We can do PAGE_ALIGN() safely to get partial page to be freed
*/
free_init_pages("initrd memory", start, PAGE_ALIGN(end));
free_init_pages("initrd memory", start, end);
}
#endif
9 changes: 2 additions & 7 deletions trunk/fs/logfs/dev_bdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ static void writeseg_end_io(struct bio *bio, int err)
prefetchw(&bvec->bv_page->flags);

end_page_writeback(page);
page_cache_release(page);
} while (bvec >= bio->bi_io_vec);
bio_put(bio);
if (atomic_dec_and_test(&super->s_pending_writes))
Expand All @@ -98,10 +97,8 @@ static int __bdev_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,
unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9);
int i;

if (max_pages > BIO_MAX_PAGES)
max_pages = BIO_MAX_PAGES;
bio = bio_alloc(GFP_NOFS, max_pages);
BUG_ON(!bio);
BUG_ON(!bio); /* FIXME: handle this */

for (i = 0; i < nr_pages; i++) {
if (i >= max_pages) {
Expand Down Expand Up @@ -194,10 +191,8 @@ static int do_erase(struct super_block *sb, u64 ofs, pgoff_t index,
unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9);
int i;

if (max_pages > BIO_MAX_PAGES)
max_pages = BIO_MAX_PAGES;
bio = bio_alloc(GFP_NOFS, max_pages);
BUG_ON(!bio);
BUG_ON(!bio); /* FIXME: handle this */

for (i = 0; i < nr_pages; i++) {
if (i >= max_pages) {
Expand Down
4 changes: 2 additions & 2 deletions trunk/fs/logfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,12 @@ static int __logfs_readdir(struct file *file, void *buf, filldir_t filldir)
(filler_t *)logfs_readpage, NULL);
if (IS_ERR(page))
return PTR_ERR(page);
dd = kmap(page);
dd = kmap_atomic(page, KM_USER0);
BUG_ON(dd->namelen == 0);

full = filldir(buf, (char *)dd->name, be16_to_cpu(dd->namelen),
pos, be64_to_cpu(dd->ino), dd->type);
kunmap(page);
kunmap_atomic(dd, KM_USER0);
page_cache_release(page);
if (full)
break;
Expand Down
7 changes: 0 additions & 7 deletions trunk/fs/logfs/journal.c
Original file line number Diff line number Diff line change
Expand Up @@ -800,15 +800,13 @@ void do_logfs_journal_wl_pass(struct super_block *sb)
{
struct logfs_super *super = logfs_super(sb);
struct logfs_area *area = super->s_journal_area;
struct btree_head32 *head = &super->s_reserved_segments;
u32 segno, ec;
int i, err;

log_journal("Journal requires wear-leveling.\n");
/* Drop old segments */
journal_for_each(i)
if (super->s_journal_seg[i]) {
btree_remove32(head, super->s_journal_seg[i]);
logfs_set_segment_unreserved(sb,
super->s_journal_seg[i],
super->s_journal_ec[i]);
Expand All @@ -821,13 +819,8 @@ void do_logfs_journal_wl_pass(struct super_block *sb)
super->s_journal_seg[i] = segno;
super->s_journal_ec[i] = ec;
logfs_set_segment_reserved(sb, segno);
err = btree_insert32(head, segno, (void *)1, GFP_KERNEL);
BUG_ON(err); /* mempool should prevent this */
err = logfs_erase_segment(sb, segno, 1);
BUG_ON(err); /* FIXME: remount-ro would be nicer */
}
/* Manually move journal_area */
freeseg(sb, area->a_segno);
area->a_segno = super->s_journal_seg[0];
area->a_is_open = 0;
area->a_used_bytes = 0;
Expand Down
1 change: 0 additions & 1 deletion trunk/fs/logfs/logfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,6 @@ void move_page_to_btree(struct page *page);
int logfs_init_mapping(struct super_block *sb);
void logfs_sync_area(struct logfs_area *area);
void logfs_sync_segments(struct super_block *sb);
void freeseg(struct super_block *sb, u32 segno);

/* area handling */
int logfs_init_areas(struct super_block *sb);
Expand Down
13 changes: 1 addition & 12 deletions trunk/fs/logfs/readwrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -1594,6 +1594,7 @@ int logfs_delete(struct inode *inode, pgoff_t index,
return ret;
}

/* Rewrite cannot mark the inode dirty but has to write it immediatly. */
int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs,
gc_level_t gc_level, long flags)
{
Expand All @@ -1610,18 +1611,6 @@ int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs,
if (level != 0)
alloc_indirect_block(inode, page, 0);
err = logfs_write_buf(inode, page, flags);
if (!err && shrink_level(gc_level) == 0) {
/* Rewrite cannot mark the inode dirty but has to
* write it immediatly.
* Q: Can't we just create an alias for the inode
* instead? And if not, why not?
*/
if (inode->i_ino == LOGFS_INO_MASTER)
logfs_write_anchor(inode->i_sb);
else {
err = __logfs_write_inode(inode, flags);
}
}
}
logfs_put_write_page(page);
return err;
Expand Down
54 changes: 23 additions & 31 deletions trunk/fs/logfs/segment.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,57 +93,49 @@ void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
} while (len);
}

static void pad_partial_page(struct logfs_area *area)
/*
* bdev_writeseg will write full pages. Memset the tail to prevent data leaks.
*/
static void pad_wbuf(struct logfs_area *area, int final)
{
struct super_block *sb = area->a_sb;
struct logfs_super *super = logfs_super(sb);
struct page *page;
u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes);
pgoff_t index = ofs >> PAGE_SHIFT;
long offset = ofs & (PAGE_SIZE-1);
u32 len = PAGE_SIZE - offset;

if (len % PAGE_SIZE) {
page = get_mapping_page(sb, index, 0);
if (len == PAGE_SIZE) {
/* The math in this function can surely use some love */
len = 0;
}
if (len) {
BUG_ON(area->a_used_bytes >= super->s_segsize);

page = get_mapping_page(area->a_sb, index, 0);
BUG_ON(!page); /* FIXME: reserve a pool */
memset(page_address(page) + offset, 0xff, len);
SetPagePrivate(page);
page_cache_release(page);
}
}

static void pad_full_pages(struct logfs_area *area)
{
struct super_block *sb = area->a_sb;
struct logfs_super *super = logfs_super(sb);
u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes);
u32 len = super->s_segsize - area->a_used_bytes;
pgoff_t index = PAGE_CACHE_ALIGN(ofs) >> PAGE_CACHE_SHIFT;
pgoff_t no_indizes = len >> PAGE_CACHE_SHIFT;
struct page *page;
if (!final)
return;

while (no_indizes) {
page = get_mapping_page(sb, index, 0);
area->a_used_bytes += len;
for ( ; area->a_used_bytes < super->s_segsize;
area->a_used_bytes += PAGE_SIZE) {
/* Memset another page */
index++;
page = get_mapping_page(area->a_sb, index, 0);
BUG_ON(!page); /* FIXME: reserve a pool */
SetPageUptodate(page);
memset(page_address(page), 0xff, PAGE_CACHE_SIZE);
memset(page_address(page), 0xff, PAGE_SIZE);
SetPagePrivate(page);
page_cache_release(page);
index++;
no_indizes--;
}
}

/*
* bdev_writeseg will write full pages. Memset the tail to prevent data leaks.
* Also make sure we allocate (and memset) all pages for final writeout.
*/
static void pad_wbuf(struct logfs_area *area, int final)
{
pad_partial_page(area);
if (final)
pad_full_pages(area);
}

/*
* We have to be careful with the alias tree. Since lookup is done by bix,
* it needs to be normalized, so 14, 15, 16, etc. all match when dealing with
Expand Down Expand Up @@ -691,7 +683,7 @@ int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow)
return 0;
}

void freeseg(struct super_block *sb, u32 segno)
static void freeseg(struct super_block *sb, u32 segno)
{
struct logfs_super *super = logfs_super(sb);
struct address_space *mapping = super->s_mapping_inode->i_mapping;
Expand Down
15 changes: 8 additions & 7 deletions trunk/fs/logfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ static int logfs_recover_sb(struct super_block *sb)
}
if (valid0 && valid1 && ds_cmp(ds0, ds1)) {
printk(KERN_INFO"Superblocks don't match - fixing.\n");
return logfs_write_sb(sb);
return write_one_sb(sb, super->s_devops->find_last_sb);
}
/* If neither is valid now, something's wrong. Didn't we properly
* check them before?!? */
Expand All @@ -289,10 +289,6 @@ static int logfs_make_writeable(struct super_block *sb)
{
int err;

err = logfs_open_segfile(sb);
if (err)
return err;

/* Repair any broken superblock copies */
err = logfs_recover_sb(sb);
if (err)
Expand All @@ -303,6 +299,10 @@ static int logfs_make_writeable(struct super_block *sb)
if (err)
return err;

err = logfs_open_segfile(sb);
if (err)
return err;

/* Do one GC pass before any data gets dirtied */
logfs_gc_pass(sb);

Expand All @@ -328,7 +328,7 @@ static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt)

sb->s_root = d_alloc_root(rootdir);
if (!sb->s_root)
goto fail2;
goto fail;

super->s_erase_page = alloc_pages(GFP_KERNEL, 0);
if (!super->s_erase_page)
Expand Down Expand Up @@ -572,7 +572,8 @@ int logfs_get_sb_device(struct file_system_type *type, int flags,
return 0;

err1:
deactivate_locked_super(sb);
up_write(&sb->s_umount);
deactivate_super(sb);
return err;
err0:
kfree(super);
Expand Down
Loading

0 comments on commit e8acdac

Please sign in to comment.