diff options
Diffstat (limited to 'mm/shmem.c')
-rw-r--r-- | mm/shmem.c | 95 |
1 files changed, 74 insertions, 21 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index eef4ebea5158..855eaf5b8d5b 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -433,8 +433,6 @@ static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long | |||
433 | 433 | ||
434 | spin_unlock(&info->lock); | 434 | spin_unlock(&info->lock); |
435 | page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping)); | 435 | page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping)); |
436 | if (page) | ||
437 | set_page_private(page, 0); | ||
438 | spin_lock(&info->lock); | 436 | spin_lock(&info->lock); |
439 | 437 | ||
440 | if (!page) { | 438 | if (!page) { |
@@ -1545,8 +1543,8 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma) | |||
1545 | return 0; | 1543 | return 0; |
1546 | } | 1544 | } |
1547 | 1545 | ||
1548 | static struct inode *shmem_get_inode(struct super_block *sb, int mode, | 1546 | static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir, |
1549 | dev_t dev, unsigned long flags) | 1547 | int mode, dev_t dev, unsigned long flags) |
1550 | { | 1548 | { |
1551 | struct inode *inode; | 1549 | struct inode *inode; |
1552 | struct shmem_inode_info *info; | 1550 | struct shmem_inode_info *info; |
@@ -1557,9 +1555,7 @@ static struct inode *shmem_get_inode(struct super_block *sb, int mode, | |||
1557 | 1555 | ||
1558 | inode = new_inode(sb); | 1556 | inode = new_inode(sb); |
1559 | if (inode) { | 1557 | if (inode) { |
1560 | inode->i_mode = mode; | 1558 | inode_init_owner(inode, dir, mode); |
1561 | inode->i_uid = current_fsuid(); | ||
1562 | inode->i_gid = current_fsgid(); | ||
1563 | inode->i_blocks = 0; | 1559 | inode->i_blocks = 0; |
1564 | inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; | 1560 | inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; |
1565 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 1561 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
@@ -1814,7 +1810,7 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
1814 | struct inode *inode; | 1810 | struct inode *inode; |
1815 | int error = -ENOSPC; | 1811 | int error = -ENOSPC; |
1816 | 1812 | ||
1817 | inode = shmem_get_inode(dir->i_sb, mode, dev, VM_NORESERVE); | 1813 | inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE); |
1818 | if (inode) { | 1814 | if (inode) { |
1819 | error = security_inode_init_security(inode, dir, NULL, NULL, | 1815 | error = security_inode_init_security(inode, dir, NULL, NULL, |
1820 | NULL); | 1816 | NULL); |
@@ -1833,11 +1829,6 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
1833 | #else | 1829 | #else |
1834 | error = 0; | 1830 | error = 0; |
1835 | #endif | 1831 | #endif |
1836 | if (dir->i_mode & S_ISGID) { | ||
1837 | inode->i_gid = dir->i_gid; | ||
1838 | if (S_ISDIR(mode)) | ||
1839 | inode->i_mode |= S_ISGID; | ||
1840 | } | ||
1841 | dir->i_size += BOGO_DIRENT_SIZE; | 1832 | dir->i_size += BOGO_DIRENT_SIZE; |
1842 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 1833 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; |
1843 | d_instantiate(dentry, inode); | 1834 | d_instantiate(dentry, inode); |
@@ -1957,7 +1948,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
1957 | if (len > PAGE_CACHE_SIZE) | 1948 | if (len > PAGE_CACHE_SIZE) |
1958 | return -ENAMETOOLONG; | 1949 | return -ENAMETOOLONG; |
1959 | 1950 | ||
1960 | inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0, VM_NORESERVE); | 1951 | inode = shmem_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0, VM_NORESERVE); |
1961 | if (!inode) | 1952 | if (!inode) |
1962 | return -ENOSPC; | 1953 | return -ENOSPC; |
1963 | 1954 | ||
@@ -1992,8 +1983,6 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
1992 | unlock_page(page); | 1983 | unlock_page(page); |
1993 | page_cache_release(page); | 1984 | page_cache_release(page); |
1994 | } | 1985 | } |
1995 | if (dir->i_mode & S_ISGID) | ||
1996 | inode->i_gid = dir->i_gid; | ||
1997 | dir->i_size += BOGO_DIRENT_SIZE; | 1986 | dir->i_size += BOGO_DIRENT_SIZE; |
1998 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 1987 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; |
1999 | d_instantiate(dentry, inode); | 1988 | d_instantiate(dentry, inode); |
@@ -2071,14 +2060,14 @@ static int shmem_xattr_security_set(struct dentry *dentry, const char *name, | |||
2071 | size, flags); | 2060 | size, flags); |
2072 | } | 2061 | } |
2073 | 2062 | ||
2074 | static struct xattr_handler shmem_xattr_security_handler = { | 2063 | static const struct xattr_handler shmem_xattr_security_handler = { |
2075 | .prefix = XATTR_SECURITY_PREFIX, | 2064 | .prefix = XATTR_SECURITY_PREFIX, |
2076 | .list = shmem_xattr_security_list, | 2065 | .list = shmem_xattr_security_list, |
2077 | .get = shmem_xattr_security_get, | 2066 | .get = shmem_xattr_security_get, |
2078 | .set = shmem_xattr_security_set, | 2067 | .set = shmem_xattr_security_set, |
2079 | }; | 2068 | }; |
2080 | 2069 | ||
2081 | static struct xattr_handler *shmem_xattr_handlers[] = { | 2070 | static const struct xattr_handler *shmem_xattr_handlers[] = { |
2082 | &generic_acl_access_handler, | 2071 | &generic_acl_access_handler, |
2083 | &generic_acl_default_handler, | 2072 | &generic_acl_default_handler, |
2084 | &shmem_xattr_security_handler, | 2073 | &shmem_xattr_security_handler, |
@@ -2366,7 +2355,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) | |||
2366 | sb->s_flags |= MS_POSIXACL; | 2355 | sb->s_flags |= MS_POSIXACL; |
2367 | #endif | 2356 | #endif |
2368 | 2357 | ||
2369 | inode = shmem_get_inode(sb, S_IFDIR | sbinfo->mode, 0, VM_NORESERVE); | 2358 | inode = shmem_get_inode(sb, NULL, S_IFDIR | sbinfo->mode, 0, VM_NORESERVE); |
2370 | if (!inode) | 2359 | if (!inode) |
2371 | goto failed; | 2360 | goto failed; |
2372 | inode->i_uid = sbinfo->uid; | 2361 | inode->i_uid = sbinfo->uid; |
@@ -2570,6 +2559,45 @@ out4: | |||
2570 | return error; | 2559 | return error; |
2571 | } | 2560 | } |
2572 | 2561 | ||
2562 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR | ||
2563 | /** | ||
2564 | * mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file | ||
2565 | * @inode: the inode to be searched | ||
2566 | * @pgoff: the offset to be searched | ||
2567 | * @pagep: the pointer for the found page to be stored | ||
2568 | * @ent: the pointer for the found swap entry to be stored | ||
2569 | * | ||
2570 | * If a page is found, refcount of it is incremented. Callers should handle | ||
2571 | * these refcount. | ||
2572 | */ | ||
2573 | void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff, | ||
2574 | struct page **pagep, swp_entry_t *ent) | ||
2575 | { | ||
2576 | swp_entry_t entry = { .val = 0 }, *ptr; | ||
2577 | struct page *page = NULL; | ||
2578 | struct shmem_inode_info *info = SHMEM_I(inode); | ||
2579 | |||
2580 | if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode)) | ||
2581 | goto out; | ||
2582 | |||
2583 | spin_lock(&info->lock); | ||
2584 | ptr = shmem_swp_entry(info, pgoff, NULL); | ||
2585 | #ifdef CONFIG_SWAP | ||
2586 | if (ptr && ptr->val) { | ||
2587 | entry.val = ptr->val; | ||
2588 | page = find_get_page(&swapper_space, entry.val); | ||
2589 | } else | ||
2590 | #endif | ||
2591 | page = find_get_page(inode->i_mapping, pgoff); | ||
2592 | if (ptr) | ||
2593 | shmem_swp_unmap(ptr); | ||
2594 | spin_unlock(&info->lock); | ||
2595 | out: | ||
2596 | *pagep = page; | ||
2597 | *ent = entry; | ||
2598 | } | ||
2599 | #endif | ||
2600 | |||
2573 | #else /* !CONFIG_SHMEM */ | 2601 | #else /* !CONFIG_SHMEM */ |
2574 | 2602 | ||
2575 | /* | 2603 | /* |
@@ -2609,9 +2637,34 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user) | |||
2609 | return 0; | 2637 | return 0; |
2610 | } | 2638 | } |
2611 | 2639 | ||
2640 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR | ||
2641 | /** | ||
2642 | * mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file | ||
2643 | * @inode: the inode to be searched | ||
2644 | * @pgoff: the offset to be searched | ||
2645 | * @pagep: the pointer for the found page to be stored | ||
2646 | * @ent: the pointer for the found swap entry to be stored | ||
2647 | * | ||
2648 | * If a page is found, refcount of it is incremented. Callers should handle | ||
2649 | * these refcount. | ||
2650 | */ | ||
2651 | void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff, | ||
2652 | struct page **pagep, swp_entry_t *ent) | ||
2653 | { | ||
2654 | struct page *page = NULL; | ||
2655 | |||
2656 | if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode)) | ||
2657 | goto out; | ||
2658 | page = find_get_page(inode->i_mapping, pgoff); | ||
2659 | out: | ||
2660 | *pagep = page; | ||
2661 | *ent = (swp_entry_t){ .val = 0 }; | ||
2662 | } | ||
2663 | #endif | ||
2664 | |||
2612 | #define shmem_vm_ops generic_file_vm_ops | 2665 | #define shmem_vm_ops generic_file_vm_ops |
2613 | #define shmem_file_operations ramfs_file_operations | 2666 | #define shmem_file_operations ramfs_file_operations |
2614 | #define shmem_get_inode(sb, mode, dev, flags) ramfs_get_inode(sb, mode, dev) | 2667 | #define shmem_get_inode(sb, dir, mode, dev, flags) ramfs_get_inode(sb, dir, mode, dev) |
2615 | #define shmem_acct_size(flags, size) 0 | 2668 | #define shmem_acct_size(flags, size) 0 |
2616 | #define shmem_unacct_size(flags, size) do {} while (0) | 2669 | #define shmem_unacct_size(flags, size) do {} while (0) |
2617 | #define SHMEM_MAX_BYTES MAX_LFS_FILESIZE | 2670 | #define SHMEM_MAX_BYTES MAX_LFS_FILESIZE |
@@ -2655,7 +2708,7 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags | |||
2655 | path.mnt = mntget(shm_mnt); | 2708 | path.mnt = mntget(shm_mnt); |
2656 | 2709 | ||
2657 | error = -ENOSPC; | 2710 | error = -ENOSPC; |
2658 | inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags); | 2711 | inode = shmem_get_inode(root->d_sb, NULL, S_IFREG | S_IRWXUGO, 0, flags); |
2659 | if (!inode) | 2712 | if (!inode) |
2660 | goto put_dentry; | 2713 | goto put_dentry; |
2661 | 2714 | ||