@@ -39,11 +39,24 @@ struct shmem_sb_info {
unsigned long shrinklist_len; /* Length of shrinklist */
};
+struct shmem_dev_info {
+ void *private_data;
+ int (*migratepage)(struct address_space *mapping,
+ struct page *newpage, struct page *page,
+ enum migrate_mode mode, void *dev_priv_data);
+};
+
static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
{
return container_of(inode, struct shmem_inode_info, vfs_inode);
}
+static inline void shmem_set_dev_info(struct address_space *mapping,
+ struct shmem_dev_info *info)
+{
+ mapping->private_data = info;
+}
+
/*
* Functions in mm/shmem.c called directly from elsewhere:
*/
@@ -1290,6 +1290,21 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
return 0;
}
+#ifdef CONFIG_MIGRATION
+static int shmem_migratepage(struct address_space *mapping,
+ struct page *newpage, struct page *page,
+ enum migrate_mode mode)
+{
+ struct shmem_dev_info *dev_info = mapping->private_data;
+
+ if (dev_info && dev_info->migratepage)
+ return dev_info->migratepage(mapping, newpage, page,
+ mode, dev_info->private_data);
+
+ return migrate_page(mapping, newpage, page, mode);
+}
+#endif
+
#if defined(CONFIG_NUMA) && defined(CONFIG_TMPFS)
static void shmem_show_mpol(struct seq_file *seq, struct mempolicy *mpol)
{
@@ -3654,7 +3669,7 @@ static void shmem_destroy_inodecache(void)
.write_end = shmem_write_end,
#endif
#ifdef CONFIG_MIGRATION
- .migratepage = migrate_page,
+ .migratepage = shmem_migratepage,
#endif
.error_remove_page = generic_error_remove_page,
};