hugetlb: hugepage migration core
[platform/adaptation/renesas_rcar/renesas_kernel.git] / fs / hugetlbfs / inode.c
index a4e9a7e..1f7ca50 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/statfs.h>
 #include <linux/security.h>
 #include <linux/magic.h>
+#include <linux/migrate.h>
 
 #include <asm/uaccess.h>
 
@@ -371,27 +372,10 @@ static void truncate_hugepages(struct inode *inode, loff_t lstart)
        hugetlb_unreserve_pages(inode, start, freed);
 }
 
-static void hugetlbfs_delete_inode(struct inode *inode)
+static void hugetlbfs_evict_inode(struct inode *inode)
 {
        truncate_hugepages(inode, 0);
-       clear_inode(inode);
-}
-
-static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock)
-{
-       if (generic_detach_inode(inode)) {
-               truncate_hugepages(inode, 0);
-               clear_inode(inode);
-               destroy_inode(inode);
-       }
-}
-
-static void hugetlbfs_drop_inode(struct inode *inode)
-{
-       if (!inode->i_nlink)
-               generic_delete_inode(inode);
-       else
-               hugetlbfs_forget_inode(inode);
+       end_writeback(inode);
 }
 
 static inline void
@@ -448,19 +432,20 @@ static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr)
 
        error = inode_change_ok(inode, attr);
        if (error)
-               goto out;
+               return error;
 
        if (ia_valid & ATTR_SIZE) {
                error = -EINVAL;
-               if (!(attr->ia_size & ~huge_page_mask(h)))
-                       error = hugetlb_vmtruncate(inode, attr->ia_size);
+               if (attr->ia_size & ~huge_page_mask(h))
+                       return -EINVAL;
+               error = hugetlb_vmtruncate(inode, attr->ia_size);
                if (error)
-                       goto out;
-               attr->ia_valid &= ~ATTR_SIZE;
+                       return error;
        }
-       error = inode_setattr(inode, attr);
-out:
-       return error;
+
+       setattr_copy(inode, attr);
+       mark_inode_dirty(inode);
+       return 0;
 }
 
 static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid, 
@@ -589,6 +574,19 @@ static int hugetlbfs_set_page_dirty(struct page *page)
        return 0;
 }
 
+static int hugetlbfs_migrate_page(struct address_space *mapping,
+                               struct page *newpage, struct page *page)
+{
+       int rc;
+
+       rc = migrate_huge_page_move_mapping(mapping, newpage, page);
+       if (rc)
+               return rc;
+       migrate_page_copy(newpage, page);
+
+       return 0;
+}
+
 static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb);
@@ -675,6 +673,7 @@ static const struct address_space_operations hugetlbfs_aops = {
        .write_begin    = hugetlbfs_write_begin,
        .write_end      = hugetlbfs_write_end,
        .set_page_dirty = hugetlbfs_set_page_dirty,
+       .migratepage    = hugetlbfs_migrate_page,
 };
 
 
@@ -712,9 +711,8 @@ static const struct inode_operations hugetlbfs_inode_operations = {
 static const struct super_operations hugetlbfs_ops = {
        .alloc_inode    = hugetlbfs_alloc_inode,
        .destroy_inode  = hugetlbfs_destroy_inode,
+       .evict_inode    = hugetlbfs_evict_inode,
        .statfs         = hugetlbfs_statfs,
-       .delete_inode   = hugetlbfs_delete_inode,
-       .drop_inode     = hugetlbfs_drop_inode,
        .put_super      = hugetlbfs_put_super,
        .show_options   = generic_show_options,
 };