aboutsummaryrefslogtreecommitdiffstats
path: root/mm/shmem.c
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2010-08-04 07:59:13 -0400
committerMichal Marek <mmarek@suse.cz>2010-08-04 07:59:13 -0400
commit772320e84588dcbe1600ffb83e5f328f2209ac2a (patch)
treea7de21b79340aeaa17c58126f6b801b82c77b53a /mm/shmem.c
parent1ce53adf13a54375d2a5c7cdbe341b2558389615 (diff)
parent9fe6206f400646a2322096b56c59891d530e8d51 (diff)
Merge commit 'v2.6.35' into kbuild/kbuild
Conflicts: arch/powerpc/Makefile
Diffstat (limited to 'mm/shmem.c')
-rw-r--r--mm/shmem.c143
1 files changed, 99 insertions, 44 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index eef4ebea5158..f65f84062db5 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) {
@@ -729,10 +727,11 @@ done2:
729 if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) { 727 if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) {
730 /* 728 /*
731 * Call truncate_inode_pages again: racing shmem_unuse_inode 729 * Call truncate_inode_pages again: racing shmem_unuse_inode
732 * may have swizzled a page in from swap since vmtruncate or 730 * may have swizzled a page in from swap since
733 * generic_delete_inode did it, before we lowered next_index. 731 * truncate_pagecache or generic_delete_inode did it, before we
734 * Also, though shmem_getpage checks i_size before adding to 732 * lowered next_index. Also, though shmem_getpage checks
735 * cache, no recheck after: so fix the narrow window there too. 733 * i_size before adding to cache, no recheck after: so fix the
734 * narrow window there too.
736 * 735 *
737 * Recalling truncate_inode_pages_range and unmap_mapping_range 736 * Recalling truncate_inode_pages_range and unmap_mapping_range
738 * every time for punch_hole (which never got a chance to clear 737 * every time for punch_hole (which never got a chance to clear
@@ -762,19 +761,17 @@ done2:
762 } 761 }
763} 762}
764 763
765static void shmem_truncate(struct inode *inode)
766{
767 shmem_truncate_range(inode, inode->i_size, (loff_t)-1);
768}
769
770static int shmem_notify_change(struct dentry *dentry, struct iattr *attr) 764static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
771{ 765{
772 struct inode *inode = dentry->d_inode; 766 struct inode *inode = dentry->d_inode;
773 struct page *page = NULL; 767 loff_t newsize = attr->ia_size;
774 int error; 768 int error;
775 769
776 if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { 770 if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)
777 if (attr->ia_size < inode->i_size) { 771 && newsize != inode->i_size) {
772 struct page *page = NULL;
773
774 if (newsize < inode->i_size) {
778 /* 775 /*
779 * If truncating down to a partial page, then 776 * If truncating down to a partial page, then
780 * if that page is already allocated, hold it 777 * if that page is already allocated, hold it
@@ -782,9 +779,9 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
782 * truncate_partial_page cannnot miss it were 779 * truncate_partial_page cannnot miss it were
783 * it assigned to swap. 780 * it assigned to swap.
784 */ 781 */
785 if (attr->ia_size & (PAGE_CACHE_SIZE-1)) { 782 if (newsize & (PAGE_CACHE_SIZE-1)) {
786 (void) shmem_getpage(inode, 783 (void) shmem_getpage(inode,
787 attr->ia_size>>PAGE_CACHE_SHIFT, 784 newsize >> PAGE_CACHE_SHIFT,
788 &page, SGP_READ, NULL); 785 &page, SGP_READ, NULL);
789 if (page) 786 if (page)
790 unlock_page(page); 787 unlock_page(page);
@@ -796,24 +793,29 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
796 * if it's being fully truncated to zero-length: the 793 * if it's being fully truncated to zero-length: the
797 * nrpages check is efficient enough in that case. 794 * nrpages check is efficient enough in that case.
798 */ 795 */
799 if (attr->ia_size) { 796 if (newsize) {
800 struct shmem_inode_info *info = SHMEM_I(inode); 797 struct shmem_inode_info *info = SHMEM_I(inode);
801 spin_lock(&info->lock); 798 spin_lock(&info->lock);
802 info->flags &= ~SHMEM_PAGEIN; 799 info->flags &= ~SHMEM_PAGEIN;
803 spin_unlock(&info->lock); 800 spin_unlock(&info->lock);
804 } 801 }
805 } 802 }
803
804 error = simple_setsize(inode, newsize);
805 if (page)
806 page_cache_release(page);
807 if (error)
808 return error;
809 shmem_truncate_range(inode, newsize, (loff_t)-1);
806 } 810 }
807 811
808 error = inode_change_ok(inode, attr); 812 error = inode_change_ok(inode, attr);
809 if (!error) 813 if (!error)
810 error = inode_setattr(inode, attr); 814 generic_setattr(inode, attr);
811#ifdef CONFIG_TMPFS_POSIX_ACL 815#ifdef CONFIG_TMPFS_POSIX_ACL
812 if (!error && (attr->ia_valid & ATTR_MODE)) 816 if (!error && (attr->ia_valid & ATTR_MODE))
813 error = generic_acl_chmod(inode); 817 error = generic_acl_chmod(inode);
814#endif 818#endif
815 if (page)
816 page_cache_release(page);
817 return error; 819 return error;
818} 820}
819 821
@@ -821,11 +823,11 @@ static void shmem_delete_inode(struct inode *inode)
821{ 823{
822 struct shmem_inode_info *info = SHMEM_I(inode); 824 struct shmem_inode_info *info = SHMEM_I(inode);
823 825
824 if (inode->i_op->truncate == shmem_truncate) { 826 if (inode->i_mapping->a_ops == &shmem_aops) {
825 truncate_inode_pages(inode->i_mapping, 0); 827 truncate_inode_pages(inode->i_mapping, 0);
826 shmem_unacct_size(info->flags, inode->i_size); 828 shmem_unacct_size(info->flags, inode->i_size);
827 inode->i_size = 0; 829 inode->i_size = 0;
828 shmem_truncate(inode); 830 shmem_truncate_range(inode, 0, (loff_t)-1);
829 if (!list_empty(&info->swaplist)) { 831 if (!list_empty(&info->swaplist)) {
830 mutex_lock(&shmem_swaplist_mutex); 832 mutex_lock(&shmem_swaplist_mutex);
831 list_del_init(&info->swaplist); 833 list_del_init(&info->swaplist);
@@ -1545,8 +1547,8 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
1545 return 0; 1547 return 0;
1546} 1548}
1547 1549
1548static struct inode *shmem_get_inode(struct super_block *sb, int mode, 1550static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir,
1549 dev_t dev, unsigned long flags) 1551 int mode, dev_t dev, unsigned long flags)
1550{ 1552{
1551 struct inode *inode; 1553 struct inode *inode;
1552 struct shmem_inode_info *info; 1554 struct shmem_inode_info *info;
@@ -1557,9 +1559,7 @@ static struct inode *shmem_get_inode(struct super_block *sb, int mode,
1557 1559
1558 inode = new_inode(sb); 1560 inode = new_inode(sb);
1559 if (inode) { 1561 if (inode) {
1560 inode->i_mode = mode; 1562 inode_init_owner(inode, dir, mode);
1561 inode->i_uid = current_fsuid();
1562 inode->i_gid = current_fsgid();
1563 inode->i_blocks = 0; 1563 inode->i_blocks = 0;
1564 inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; 1564 inode->i_mapping->backing_dev_info = &shmem_backing_dev_info;
1565 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 1565 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
@@ -1814,7 +1814,7 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1814 struct inode *inode; 1814 struct inode *inode;
1815 int error = -ENOSPC; 1815 int error = -ENOSPC;
1816 1816
1817 inode = shmem_get_inode(dir->i_sb, mode, dev, VM_NORESERVE); 1817 inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
1818 if (inode) { 1818 if (inode) {
1819 error = security_inode_init_security(inode, dir, NULL, NULL, 1819 error = security_inode_init_security(inode, dir, NULL, NULL,
1820 NULL); 1820 NULL);
@@ -1833,11 +1833,6 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1833#else 1833#else
1834 error = 0; 1834 error = 0;
1835#endif 1835#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; 1836 dir->i_size += BOGO_DIRENT_SIZE;
1842 dir->i_ctime = dir->i_mtime = CURRENT_TIME; 1837 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
1843 d_instantiate(dentry, inode); 1838 d_instantiate(dentry, inode);
@@ -1957,7 +1952,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
1957 if (len > PAGE_CACHE_SIZE) 1952 if (len > PAGE_CACHE_SIZE)
1958 return -ENAMETOOLONG; 1953 return -ENAMETOOLONG;
1959 1954
1960 inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0, VM_NORESERVE); 1955 inode = shmem_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0, VM_NORESERVE);
1961 if (!inode) 1956 if (!inode)
1962 return -ENOSPC; 1957 return -ENOSPC;
1963 1958
@@ -1992,8 +1987,6 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
1992 unlock_page(page); 1987 unlock_page(page);
1993 page_cache_release(page); 1988 page_cache_release(page);
1994 } 1989 }
1995 if (dir->i_mode & S_ISGID)
1996 inode->i_gid = dir->i_gid;
1997 dir->i_size += BOGO_DIRENT_SIZE; 1990 dir->i_size += BOGO_DIRENT_SIZE;
1998 dir->i_ctime = dir->i_mtime = CURRENT_TIME; 1991 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
1999 d_instantiate(dentry, inode); 1992 d_instantiate(dentry, inode);
@@ -2033,7 +2026,6 @@ static const struct inode_operations shmem_symlink_inline_operations = {
2033}; 2026};
2034 2027
2035static const struct inode_operations shmem_symlink_inode_operations = { 2028static const struct inode_operations shmem_symlink_inode_operations = {
2036 .truncate = shmem_truncate,
2037 .readlink = generic_readlink, 2029 .readlink = generic_readlink,
2038 .follow_link = shmem_follow_link, 2030 .follow_link = shmem_follow_link,
2039 .put_link = shmem_put_link, 2031 .put_link = shmem_put_link,
@@ -2071,14 +2063,14 @@ static int shmem_xattr_security_set(struct dentry *dentry, const char *name,
2071 size, flags); 2063 size, flags);
2072} 2064}
2073 2065
2074static struct xattr_handler shmem_xattr_security_handler = { 2066static const struct xattr_handler shmem_xattr_security_handler = {
2075 .prefix = XATTR_SECURITY_PREFIX, 2067 .prefix = XATTR_SECURITY_PREFIX,
2076 .list = shmem_xattr_security_list, 2068 .list = shmem_xattr_security_list,
2077 .get = shmem_xattr_security_get, 2069 .get = shmem_xattr_security_get,
2078 .set = shmem_xattr_security_set, 2070 .set = shmem_xattr_security_set,
2079}; 2071};
2080 2072
2081static struct xattr_handler *shmem_xattr_handlers[] = { 2073static const struct xattr_handler *shmem_xattr_handlers[] = {
2082 &generic_acl_access_handler, 2074 &generic_acl_access_handler,
2083 &generic_acl_default_handler, 2075 &generic_acl_default_handler,
2084 &shmem_xattr_security_handler, 2076 &shmem_xattr_security_handler,
@@ -2366,7 +2358,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
2366 sb->s_flags |= MS_POSIXACL; 2358 sb->s_flags |= MS_POSIXACL;
2367#endif 2359#endif
2368 2360
2369 inode = shmem_get_inode(sb, S_IFDIR | sbinfo->mode, 0, VM_NORESERVE); 2361 inode = shmem_get_inode(sb, NULL, S_IFDIR | sbinfo->mode, 0, VM_NORESERVE);
2370 if (!inode) 2362 if (!inode)
2371 goto failed; 2363 goto failed;
2372 inode->i_uid = sbinfo->uid; 2364 inode->i_uid = sbinfo->uid;
@@ -2444,14 +2436,13 @@ static const struct file_operations shmem_file_operations = {
2444 .write = do_sync_write, 2436 .write = do_sync_write,
2445 .aio_read = shmem_file_aio_read, 2437 .aio_read = shmem_file_aio_read,
2446 .aio_write = generic_file_aio_write, 2438 .aio_write = generic_file_aio_write,
2447 .fsync = simple_sync_file, 2439 .fsync = noop_fsync,
2448 .splice_read = generic_file_splice_read, 2440 .splice_read = generic_file_splice_read,
2449 .splice_write = generic_file_splice_write, 2441 .splice_write = generic_file_splice_write,
2450#endif 2442#endif
2451}; 2443};
2452 2444
2453static const struct inode_operations shmem_inode_operations = { 2445static const struct inode_operations shmem_inode_operations = {
2454 .truncate = shmem_truncate,
2455 .setattr = shmem_notify_change, 2446 .setattr = shmem_notify_change,
2456 .truncate_range = shmem_truncate_range, 2447 .truncate_range = shmem_truncate_range,
2457#ifdef CONFIG_TMPFS_POSIX_ACL 2448#ifdef CONFIG_TMPFS_POSIX_ACL
@@ -2570,6 +2561,45 @@ out4:
2570 return error; 2561 return error;
2571} 2562}
2572 2563
2564#ifdef CONFIG_CGROUP_MEM_RES_CTLR
2565/**
2566 * mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file
2567 * @inode: the inode to be searched
2568 * @pgoff: the offset to be searched
2569 * @pagep: the pointer for the found page to be stored
2570 * @ent: the pointer for the found swap entry to be stored
2571 *
2572 * If a page is found, refcount of it is incremented. Callers should handle
2573 * these refcount.
2574 */
2575void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff,
2576 struct page **pagep, swp_entry_t *ent)
2577{
2578 swp_entry_t entry = { .val = 0 }, *ptr;
2579 struct page *page = NULL;
2580 struct shmem_inode_info *info = SHMEM_I(inode);
2581
2582 if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode))
2583 goto out;
2584
2585 spin_lock(&info->lock);
2586 ptr = shmem_swp_entry(info, pgoff, NULL);
2587#ifdef CONFIG_SWAP
2588 if (ptr && ptr->val) {
2589 entry.val = ptr->val;
2590 page = find_get_page(&swapper_space, entry.val);
2591 } else
2592#endif
2593 page = find_get_page(inode->i_mapping, pgoff);
2594 if (ptr)
2595 shmem_swp_unmap(ptr);
2596 spin_unlock(&info->lock);
2597out:
2598 *pagep = page;
2599 *ent = entry;
2600}
2601#endif
2602
2573#else /* !CONFIG_SHMEM */ 2603#else /* !CONFIG_SHMEM */
2574 2604
2575/* 2605/*
@@ -2609,9 +2639,34 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user)
2609 return 0; 2639 return 0;
2610} 2640}
2611 2641
2642#ifdef CONFIG_CGROUP_MEM_RES_CTLR
2643/**
2644 * mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file
2645 * @inode: the inode to be searched
2646 * @pgoff: the offset to be searched
2647 * @pagep: the pointer for the found page to be stored
2648 * @ent: the pointer for the found swap entry to be stored
2649 *
2650 * If a page is found, refcount of it is incremented. Callers should handle
2651 * these refcount.
2652 */
2653void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff,
2654 struct page **pagep, swp_entry_t *ent)
2655{
2656 struct page *page = NULL;
2657
2658 if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode))
2659 goto out;
2660 page = find_get_page(inode->i_mapping, pgoff);
2661out:
2662 *pagep = page;
2663 *ent = (swp_entry_t){ .val = 0 };
2664}
2665#endif
2666
2612#define shmem_vm_ops generic_file_vm_ops 2667#define shmem_vm_ops generic_file_vm_ops
2613#define shmem_file_operations ramfs_file_operations 2668#define shmem_file_operations ramfs_file_operations
2614#define shmem_get_inode(sb, mode, dev, flags) ramfs_get_inode(sb, mode, dev) 2669#define shmem_get_inode(sb, dir, mode, dev, flags) ramfs_get_inode(sb, dir, mode, dev)
2615#define shmem_acct_size(flags, size) 0 2670#define shmem_acct_size(flags, size) 0
2616#define shmem_unacct_size(flags, size) do {} while (0) 2671#define shmem_unacct_size(flags, size) do {} while (0)
2617#define SHMEM_MAX_BYTES MAX_LFS_FILESIZE 2672#define SHMEM_MAX_BYTES MAX_LFS_FILESIZE
@@ -2655,7 +2710,7 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags
2655 path.mnt = mntget(shm_mnt); 2710 path.mnt = mntget(shm_mnt);
2656 2711
2657 error = -ENOSPC; 2712 error = -ENOSPC;
2658 inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags); 2713 inode = shmem_get_inode(root->d_sb, NULL, S_IFREG | S_IRWXUGO, 0, flags);
2659 if (!inode) 2714 if (!inode)
2660 goto put_dentry; 2715 goto put_dentry;
2661 2716