diff options
author | David S. Miller <davem@davemloft.net> | 2010-01-23 01:45:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-23 01:45:46 -0500 |
commit | 6be325719b3e54624397e413efd4b33a997e55a3 (patch) | |
tree | 57f321a56794cab2222e179b16731e0d76a4a68a /mm/shmem.c | |
parent | 26d92f9276a56d55511a427fb70bd70886af647a (diff) | |
parent | 92dcffb916d309aa01778bf8963a6932e4014d07 (diff) |
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Diffstat (limited to 'mm/shmem.c')
-rw-r--r-- | mm/shmem.c | 84 |
1 files changed, 47 insertions, 37 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index 356dd99566ec..eef4ebea5158 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/swap.h> | 31 | #include <linux/swap.h> |
32 | #include <linux/ima.h> | ||
33 | 32 | ||
34 | static struct vfsmount *shm_mnt; | 33 | static struct vfsmount *shm_mnt; |
35 | 34 | ||
@@ -42,6 +41,7 @@ static struct vfsmount *shm_mnt; | |||
42 | 41 | ||
43 | #include <linux/xattr.h> | 42 | #include <linux/xattr.h> |
44 | #include <linux/exportfs.h> | 43 | #include <linux/exportfs.h> |
44 | #include <linux/posix_acl.h> | ||
45 | #include <linux/generic_acl.h> | 45 | #include <linux/generic_acl.h> |
46 | #include <linux/mman.h> | 46 | #include <linux/mman.h> |
47 | #include <linux/string.h> | 47 | #include <linux/string.h> |
@@ -810,7 +810,7 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr) | |||
810 | error = inode_setattr(inode, attr); | 810 | error = inode_setattr(inode, attr); |
811 | #ifdef CONFIG_TMPFS_POSIX_ACL | 811 | #ifdef CONFIG_TMPFS_POSIX_ACL |
812 | if (!error && (attr->ia_valid & ATTR_MODE)) | 812 | if (!error && (attr->ia_valid & ATTR_MODE)) |
813 | error = generic_acl_chmod(inode, &shmem_acl_ops); | 813 | error = generic_acl_chmod(inode); |
814 | #endif | 814 | #endif |
815 | if (page) | 815 | if (page) |
816 | page_cache_release(page); | 816 | page_cache_release(page); |
@@ -1017,7 +1017,14 @@ int shmem_unuse(swp_entry_t entry, struct page *page) | |||
1017 | goto out; | 1017 | goto out; |
1018 | } | 1018 | } |
1019 | mutex_unlock(&shmem_swaplist_mutex); | 1019 | mutex_unlock(&shmem_swaplist_mutex); |
1020 | out: return found; /* 0 or 1 or -ENOMEM */ | 1020 | /* |
1021 | * Can some race bring us here? We've been holding page lock, | ||
1022 | * so I think not; but would rather try again later than BUG() | ||
1023 | */ | ||
1024 | unlock_page(page); | ||
1025 | page_cache_release(page); | ||
1026 | out: | ||
1027 | return (found < 0) ? found : 0; | ||
1021 | } | 1028 | } |
1022 | 1029 | ||
1023 | /* | 1030 | /* |
@@ -1080,7 +1087,7 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc) | |||
1080 | else | 1087 | else |
1081 | inode = NULL; | 1088 | inode = NULL; |
1082 | spin_unlock(&info->lock); | 1089 | spin_unlock(&info->lock); |
1083 | swap_duplicate(swap); | 1090 | swap_shmem_alloc(swap); |
1084 | BUG_ON(page_mapped(page)); | 1091 | BUG_ON(page_mapped(page)); |
1085 | page_cache_release(page); /* pagecache ref */ | 1092 | page_cache_release(page); /* pagecache ref */ |
1086 | swap_writepage(page, wbc); | 1093 | swap_writepage(page, wbc); |
@@ -1817,11 +1824,15 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
1817 | return error; | 1824 | return error; |
1818 | } | 1825 | } |
1819 | } | 1826 | } |
1820 | error = shmem_acl_init(inode, dir); | 1827 | #ifdef CONFIG_TMPFS_POSIX_ACL |
1828 | error = generic_acl_init(inode, dir); | ||
1821 | if (error) { | 1829 | if (error) { |
1822 | iput(inode); | 1830 | iput(inode); |
1823 | return error; | 1831 | return error; |
1824 | } | 1832 | } |
1833 | #else | ||
1834 | error = 0; | ||
1835 | #endif | ||
1825 | if (dir->i_mode & S_ISGID) { | 1836 | if (dir->i_mode & S_ISGID) { |
1826 | inode->i_gid = dir->i_gid; | 1837 | inode->i_gid = dir->i_gid; |
1827 | if (S_ISDIR(mode)) | 1838 | if (S_ISDIR(mode)) |
@@ -2036,27 +2047,28 @@ static const struct inode_operations shmem_symlink_inode_operations = { | |||
2036 | * filesystem level, though. | 2047 | * filesystem level, though. |
2037 | */ | 2048 | */ |
2038 | 2049 | ||
2039 | static size_t shmem_xattr_security_list(struct inode *inode, char *list, | 2050 | static size_t shmem_xattr_security_list(struct dentry *dentry, char *list, |
2040 | size_t list_len, const char *name, | 2051 | size_t list_len, const char *name, |
2041 | size_t name_len) | 2052 | size_t name_len, int handler_flags) |
2042 | { | 2053 | { |
2043 | return security_inode_listsecurity(inode, list, list_len); | 2054 | return security_inode_listsecurity(dentry->d_inode, list, list_len); |
2044 | } | 2055 | } |
2045 | 2056 | ||
2046 | static int shmem_xattr_security_get(struct inode *inode, const char *name, | 2057 | static int shmem_xattr_security_get(struct dentry *dentry, const char *name, |
2047 | void *buffer, size_t size) | 2058 | void *buffer, size_t size, int handler_flags) |
2048 | { | 2059 | { |
2049 | if (strcmp(name, "") == 0) | 2060 | if (strcmp(name, "") == 0) |
2050 | return -EINVAL; | 2061 | return -EINVAL; |
2051 | return xattr_getsecurity(inode, name, buffer, size); | 2062 | return xattr_getsecurity(dentry->d_inode, name, buffer, size); |
2052 | } | 2063 | } |
2053 | 2064 | ||
2054 | static int shmem_xattr_security_set(struct inode *inode, const char *name, | 2065 | static int shmem_xattr_security_set(struct dentry *dentry, const char *name, |
2055 | const void *value, size_t size, int flags) | 2066 | const void *value, size_t size, int flags, int handler_flags) |
2056 | { | 2067 | { |
2057 | if (strcmp(name, "") == 0) | 2068 | if (strcmp(name, "") == 0) |
2058 | return -EINVAL; | 2069 | return -EINVAL; |
2059 | return security_inode_setsecurity(inode, name, value, size, flags); | 2070 | return security_inode_setsecurity(dentry->d_inode, name, value, |
2071 | size, flags); | ||
2060 | } | 2072 | } |
2061 | 2073 | ||
2062 | static struct xattr_handler shmem_xattr_security_handler = { | 2074 | static struct xattr_handler shmem_xattr_security_handler = { |
@@ -2067,8 +2079,8 @@ static struct xattr_handler shmem_xattr_security_handler = { | |||
2067 | }; | 2079 | }; |
2068 | 2080 | ||
2069 | static struct xattr_handler *shmem_xattr_handlers[] = { | 2081 | static struct xattr_handler *shmem_xattr_handlers[] = { |
2070 | &shmem_xattr_acl_access_handler, | 2082 | &generic_acl_access_handler, |
2071 | &shmem_xattr_acl_default_handler, | 2083 | &generic_acl_default_handler, |
2072 | &shmem_xattr_security_handler, | 2084 | &shmem_xattr_security_handler, |
2073 | NULL | 2085 | NULL |
2074 | }; | 2086 | }; |
@@ -2447,7 +2459,7 @@ static const struct inode_operations shmem_inode_operations = { | |||
2447 | .getxattr = generic_getxattr, | 2459 | .getxattr = generic_getxattr, |
2448 | .listxattr = generic_listxattr, | 2460 | .listxattr = generic_listxattr, |
2449 | .removexattr = generic_removexattr, | 2461 | .removexattr = generic_removexattr, |
2450 | .check_acl = shmem_check_acl, | 2462 | .check_acl = generic_check_acl, |
2451 | #endif | 2463 | #endif |
2452 | 2464 | ||
2453 | }; | 2465 | }; |
@@ -2470,7 +2482,7 @@ static const struct inode_operations shmem_dir_inode_operations = { | |||
2470 | .getxattr = generic_getxattr, | 2482 | .getxattr = generic_getxattr, |
2471 | .listxattr = generic_listxattr, | 2483 | .listxattr = generic_listxattr, |
2472 | .removexattr = generic_removexattr, | 2484 | .removexattr = generic_removexattr, |
2473 | .check_acl = shmem_check_acl, | 2485 | .check_acl = generic_check_acl, |
2474 | #endif | 2486 | #endif |
2475 | }; | 2487 | }; |
2476 | 2488 | ||
@@ -2481,7 +2493,7 @@ static const struct inode_operations shmem_special_inode_operations = { | |||
2481 | .getxattr = generic_getxattr, | 2493 | .getxattr = generic_getxattr, |
2482 | .listxattr = generic_listxattr, | 2494 | .listxattr = generic_listxattr, |
2483 | .removexattr = generic_removexattr, | 2495 | .removexattr = generic_removexattr, |
2484 | .check_acl = shmem_check_acl, | 2496 | .check_acl = generic_check_acl, |
2485 | #endif | 2497 | #endif |
2486 | }; | 2498 | }; |
2487 | 2499 | ||
@@ -2619,7 +2631,8 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags | |||
2619 | int error; | 2631 | int error; |
2620 | struct file *file; | 2632 | struct file *file; |
2621 | struct inode *inode; | 2633 | struct inode *inode; |
2622 | struct dentry *dentry, *root; | 2634 | struct path path; |
2635 | struct dentry *root; | ||
2623 | struct qstr this; | 2636 | struct qstr this; |
2624 | 2637 | ||
2625 | if (IS_ERR(shm_mnt)) | 2638 | if (IS_ERR(shm_mnt)) |
@@ -2636,38 +2649,35 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags | |||
2636 | this.len = strlen(name); | 2649 | this.len = strlen(name); |
2637 | this.hash = 0; /* will go */ | 2650 | this.hash = 0; /* will go */ |
2638 | root = shm_mnt->mnt_root; | 2651 | root = shm_mnt->mnt_root; |
2639 | dentry = d_alloc(root, &this); | 2652 | path.dentry = d_alloc(root, &this); |
2640 | if (!dentry) | 2653 | if (!path.dentry) |
2641 | goto put_memory; | 2654 | goto put_memory; |
2642 | 2655 | path.mnt = mntget(shm_mnt); | |
2643 | error = -ENFILE; | ||
2644 | file = get_empty_filp(); | ||
2645 | if (!file) | ||
2646 | goto put_dentry; | ||
2647 | 2656 | ||
2648 | error = -ENOSPC; | 2657 | error = -ENOSPC; |
2649 | inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags); | 2658 | inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags); |
2650 | if (!inode) | 2659 | if (!inode) |
2651 | goto close_file; | 2660 | goto put_dentry; |
2652 | 2661 | ||
2653 | d_instantiate(dentry, inode); | 2662 | d_instantiate(path.dentry, inode); |
2654 | inode->i_size = size; | 2663 | inode->i_size = size; |
2655 | inode->i_nlink = 0; /* It is unlinked */ | 2664 | inode->i_nlink = 0; /* It is unlinked */ |
2656 | init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ, | ||
2657 | &shmem_file_operations); | ||
2658 | |||
2659 | #ifndef CONFIG_MMU | 2665 | #ifndef CONFIG_MMU |
2660 | error = ramfs_nommu_expand_for_mapping(inode, size); | 2666 | error = ramfs_nommu_expand_for_mapping(inode, size); |
2661 | if (error) | 2667 | if (error) |
2662 | goto close_file; | 2668 | goto put_dentry; |
2663 | #endif | 2669 | #endif |
2664 | ima_counts_get(file); | 2670 | |
2671 | error = -ENFILE; | ||
2672 | file = alloc_file(&path, FMODE_WRITE | FMODE_READ, | ||
2673 | &shmem_file_operations); | ||
2674 | if (!file) | ||
2675 | goto put_dentry; | ||
2676 | |||
2665 | return file; | 2677 | return file; |
2666 | 2678 | ||
2667 | close_file: | ||
2668 | put_filp(file); | ||
2669 | put_dentry: | 2679 | put_dentry: |
2670 | dput(dentry); | 2680 | path_put(&path); |
2671 | put_memory: | 2681 | put_memory: |
2672 | shmem_unacct_size(flags, size); | 2682 | shmem_unacct_size(flags, size); |
2673 | return ERR_PTR(error); | 2683 | return ERR_PTR(error); |