Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 19380
b: refs/heads/master
c: e965f96
h: refs/heads/master
v: v3
  • Loading branch information
Christoph Lameter authored and Linus Torvalds committed Feb 1, 2006
1 parent c39c4d5 commit 33e7dab
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 2 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: 7e2ab150d1b3b286a4c864c60a549b2601777b63
refs/heads/master: e965f9630c651fa4249039fd4b80c9392d07a856
60 changes: 60 additions & 0 deletions trunk/fs/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -3049,6 +3049,66 @@ asmlinkage long sys_bdflush(int func, long data)
return 0;
}

/*
* Migration function for pages with buffers. This function can only be used
* if the underlying filesystem guarantees that no other references to "page"
* exist.
*/
#ifdef CONFIG_MIGRATION
int buffer_migrate_page(struct page *newpage, struct page *page)
{
struct address_space *mapping = page->mapping;
struct buffer_head *bh, *head;

if (!mapping)
return -EAGAIN;

if (!page_has_buffers(page))
return migrate_page(newpage, page);

head = page_buffers(page);

if (migrate_page_remove_references(newpage, page, 3))
return -EAGAIN;

bh = head;
do {
get_bh(bh);
lock_buffer(bh);
bh = bh->b_this_page;

} while (bh != head);

ClearPagePrivate(page);
set_page_private(newpage, page_private(page));
set_page_private(page, 0);
put_page(page);
get_page(newpage);

bh = head;
do {
set_bh_page(bh, newpage, bh_offset(bh));
bh = bh->b_this_page;

} while (bh != head);

SetPagePrivate(newpage);

migrate_page_copy(newpage, page);

bh = head;
do {
unlock_buffer(bh);
put_bh(bh);
bh = bh->b_this_page;

} while (bh != head);

return 0;
}
EXPORT_SYMBOL(buffer_migrate_page);
#endif

/*
* Buffer-head allocation
*/
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/ext2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,7 @@ struct address_space_operations ext2_aops = {
.bmap = ext2_bmap,
.direct_IO = ext2_direct_IO,
.writepages = ext2_writepages,
.migratepage = buffer_migrate_page,
};

struct address_space_operations ext2_aops_xip = {
Expand All @@ -723,6 +724,7 @@ struct address_space_operations ext2_nobh_aops = {
.bmap = ext2_bmap,
.direct_IO = ext2_direct_IO,
.writepages = ext2_writepages,
.migratepage = buffer_migrate_page,
};

/*
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/ext3/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1559,6 +1559,7 @@ static struct address_space_operations ext3_ordered_aops = {
.invalidatepage = ext3_invalidatepage,
.releasepage = ext3_releasepage,
.direct_IO = ext3_direct_IO,
.migratepage = buffer_migrate_page,
};

static struct address_space_operations ext3_writeback_aops = {
Expand All @@ -1572,6 +1573,7 @@ static struct address_space_operations ext3_writeback_aops = {
.invalidatepage = ext3_invalidatepage,
.releasepage = ext3_releasepage,
.direct_IO = ext3_direct_IO,
.migratepage = buffer_migrate_page,
};

static struct address_space_operations ext3_journalled_aops = {
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/xfs/linux-2.6/xfs_aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1462,4 +1462,5 @@ struct address_space_operations linvfs_aops = {
.commit_write = generic_commit_write,
.bmap = linvfs_bmap,
.direct_IO = linvfs_direct_IO,
.migratepage = buffer_migrate_page,
};
1 change: 1 addition & 0 deletions trunk/fs/xfs/linux-2.6/xfs_buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,7 @@ xfs_mapping_buftarg(
struct address_space *mapping;
static struct address_space_operations mapping_aops = {
.sync_page = block_sync_page,
.migratepage = fail_migrate_page,
};

inode = new_inode(bdev->bd_inode->i_sb);
Expand Down
8 changes: 8 additions & 0 deletions trunk/include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ struct address_space_operations {
loff_t offset, unsigned long nr_segs);
struct page* (*get_xip_page)(struct address_space *, sector_t,
int);
/* migrate the contents of a page to the specified target */
int (*migratepage) (struct page *, struct page *);
};

struct backing_dev_info;
Expand Down Expand Up @@ -1719,6 +1721,12 @@ extern void simple_release_fs(struct vfsmount **mount, int *count);

extern ssize_t simple_read_from_buffer(void __user *, size_t, loff_t *, const void *, size_t);

#ifdef CONFIG_MIGRATION
extern int buffer_migrate_page(struct page *, struct page *);
#else
#define buffer_migrate_page NULL
#endif

extern int inode_change_ok(struct inode *, struct iattr *);
extern int __must_check inode_setattr(struct inode *, struct iattr *);

Expand Down
5 changes: 5 additions & 0 deletions trunk/include/linux/swap.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,18 @@ extern int isolate_lru_page(struct page *p);
extern int putback_lru_pages(struct list_head *l);
extern int migrate_page(struct page *, struct page *);
extern void migrate_page_copy(struct page *, struct page *);
extern int migrate_page_remove_references(struct page *, struct page *, int);
extern int migrate_pages(struct list_head *l, struct list_head *t,
struct list_head *moved, struct list_head *failed);
extern int fail_migrate_page(struct page *, struct page *);
#else
static inline int isolate_lru_page(struct page *p) { return -ENOSYS; }
static inline int putback_lru_pages(struct list_head *l) { return 0; }
static inline int migrate_pages(struct list_head *l, struct list_head *t,
struct list_head *moved, struct list_head *failed) { return -ENOSYS; }
/* Possible settings for the migrate_page() method in address_operations */
#define migrate_page NULL
#define fail_migrate_page NULL
#endif

#ifdef CONFIG_MMU
Expand Down
1 change: 1 addition & 0 deletions trunk/mm/rmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ void remove_from_swap(struct page *page)

delete_from_swap_cache(page);
}
EXPORT_SYMBOL(remove_from_swap);
#endif

/*
Expand Down
1 change: 1 addition & 0 deletions trunk/mm/swap_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static struct address_space_operations swap_aops = {
.writepage = swap_writepage,
.sync_page = block_sync_page,
.set_page_dirty = __set_page_dirty_nobuffers,
.migratepage = migrate_page,
};

static struct backing_dev_info swap_backing_dev_info = {
Expand Down
20 changes: 19 additions & 1 deletion trunk/mm/vmscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,15 @@ int putback_lru_pages(struct list_head *l)
return count;
}

/*
* Non migratable page
*/
int fail_migrate_page(struct page *newpage, struct page *page)
{
return -EIO;
}
EXPORT_SYMBOL(fail_migrate_page);

/*
* swapout a single page
* page is locked upon entry, unlocked on exit
Expand Down Expand Up @@ -659,6 +668,7 @@ static int swap_page(struct page *page)
retry:
return -EAGAIN;
}
EXPORT_SYMBOL(swap_page);

/*
* Page migration was first developed in the context of the memory hotplug
Expand All @@ -674,7 +684,7 @@ static int swap_page(struct page *page)
* Remove references for a page and establish the new page with the correct
* basic settings to be able to stop accesses to the page.
*/
static int migrate_page_remove_references(struct page *newpage,
int migrate_page_remove_references(struct page *newpage,
struct page *page, int nr_refs)
{
struct address_space *mapping = page_mapping(page);
Expand Down Expand Up @@ -749,6 +759,7 @@ static int migrate_page_remove_references(struct page *newpage,

return 0;
}
EXPORT_SYMBOL(migrate_page_remove_references);

/*
* Copy the page to its new location
Expand Down Expand Up @@ -788,6 +799,7 @@ void migrate_page_copy(struct page *newpage, struct page *page)
if (PageWriteback(newpage))
end_page_writeback(newpage);
}
EXPORT_SYMBOL(migrate_page_copy);

/*
* Common logic to directly migrate a single page suitable for
Expand Down Expand Up @@ -815,6 +827,7 @@ int migrate_page(struct page *newpage, struct page *page)
remove_from_swap(newpage);
return 0;
}
EXPORT_SYMBOL(migrate_page);

/*
* migrate_pages
Expand Down Expand Up @@ -914,6 +927,11 @@ int migrate_pages(struct list_head *from, struct list_head *to,
if (!mapping)
goto unlock_both;

if (mapping->a_ops->migratepage) {
rc = mapping->a_ops->migratepage(newpage, page);
goto unlock_both;
}

/*
* Trigger writeout if page is dirty
*/
Expand Down

0 comments on commit 33e7dab

Please sign in to comment.