]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - mm/shmem.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
[karo-tx-linux.git] / mm / shmem.c
index 0cd7f66f1c668ceb7043f21f0715aff7881962b5..855eaf5b8d5bd964d4af0f6d1280d347b9490e8d 100644 (file)
@@ -433,8 +433,6 @@ static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long
 
                spin_unlock(&info->lock);
                page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping));
-               if (page)
-                       set_page_private(page, 0);
                spin_lock(&info->lock);
 
                if (!page) {
@@ -2561,6 +2559,45 @@ out4:
        return error;
 }
 
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
+/**
+ * mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file
+ * @inode: the inode to be searched
+ * @pgoff: the offset to be searched
+ * @pagep: the pointer for the found page to be stored
+ * @ent: the pointer for the found swap entry to be stored
+ *
+ * If a page is found, refcount of it is incremented. Callers should handle
+ * these refcount.
+ */
+void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff,
+                                       struct page **pagep, swp_entry_t *ent)
+{
+       swp_entry_t entry = { .val = 0 }, *ptr;
+       struct page *page = NULL;
+       struct shmem_inode_info *info = SHMEM_I(inode);
+
+       if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode))
+               goto out;
+
+       spin_lock(&info->lock);
+       ptr = shmem_swp_entry(info, pgoff, NULL);
+#ifdef CONFIG_SWAP
+       if (ptr && ptr->val) {
+               entry.val = ptr->val;
+               page = find_get_page(&swapper_space, entry.val);
+       } else
+#endif
+               page = find_get_page(inode->i_mapping, pgoff);
+       if (ptr)
+               shmem_swp_unmap(ptr);
+       spin_unlock(&info->lock);
+out:
+       *pagep = page;
+       *ent = entry;
+}
+#endif
+
 #else /* !CONFIG_SHMEM */
 
 /*
@@ -2600,6 +2637,31 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user)
        return 0;
 }
 
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
+/**
+ * mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file
+ * @inode: the inode to be searched
+ * @pgoff: the offset to be searched
+ * @pagep: the pointer for the found page to be stored
+ * @ent: the pointer for the found swap entry to be stored
+ *
+ * If a page is found, refcount of it is incremented. Callers should handle
+ * these refcount.
+ */
+void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff,
+                                       struct page **pagep, swp_entry_t *ent)
+{
+       struct page *page = NULL;
+
+       if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode))
+               goto out;
+       page = find_get_page(inode->i_mapping, pgoff);
+out:
+       *pagep = page;
+       *ent = (swp_entry_t){ .val = 0 };
+}
+#endif
+
 #define shmem_vm_ops                           generic_file_vm_ops
 #define shmem_file_operations                  ramfs_file_operations
 #define shmem_get_inode(sb, dir, mode, dev, flags)     ramfs_get_inode(sb, dir, mode, dev)