aboutsummaryrefslogtreecommitdiffstats
path: root/mm/shmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/shmem.c')
-rw-r--r--mm/shmem.c120
1 files changed, 105 insertions, 15 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index 84b5cf9b63c5..b96de69f236b 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -23,11 +23,11 @@
23 * which makes it a completely usable filesystem. 23 * which makes it a completely usable filesystem.
24 */ 24 */
25 25
26#include <linux/config.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/init.h> 27#include <linux/init.h>
29#include <linux/devfs_fs_kernel.h>
30#include <linux/fs.h> 28#include <linux/fs.h>
29#include <linux/xattr.h>
30#include <linux/generic_acl.h>
31#include <linux/mm.h> 31#include <linux/mm.h>
32#include <linux/mman.h> 32#include <linux/mman.h>
33#include <linux/file.h> 33#include <linux/file.h>
@@ -47,6 +47,7 @@
47#include <linux/namei.h> 47#include <linux/namei.h>
48#include <linux/ctype.h> 48#include <linux/ctype.h>
49#include <linux/migrate.h> 49#include <linux/migrate.h>
50#include <linux/highmem.h>
50 51
51#include <asm/uaccess.h> 52#include <asm/uaccess.h>
52#include <asm/div64.h> 53#include <asm/div64.h>
@@ -174,10 +175,11 @@ static inline void shmem_unacct_blocks(unsigned long flags, long pages)
174} 175}
175 176
176static struct super_operations shmem_ops; 177static struct super_operations shmem_ops;
177static struct address_space_operations shmem_aops; 178static const struct address_space_operations shmem_aops;
178static struct file_operations shmem_file_operations; 179static struct file_operations shmem_file_operations;
179static struct inode_operations shmem_inode_operations; 180static struct inode_operations shmem_inode_operations;
180static struct inode_operations shmem_dir_inode_operations; 181static struct inode_operations shmem_dir_inode_operations;
182static struct inode_operations shmem_special_inode_operations;
181static struct vm_operations_struct shmem_vm_ops; 183static struct vm_operations_struct shmem_vm_ops;
182 184
183static struct backing_dev_info shmem_backing_dev_info __read_mostly = { 185static struct backing_dev_info shmem_backing_dev_info __read_mostly = {
@@ -638,7 +640,7 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
638 struct page *page = NULL; 640 struct page *page = NULL;
639 int error; 641 int error;
640 642
641 if (attr->ia_valid & ATTR_SIZE) { 643 if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
642 if (attr->ia_size < inode->i_size) { 644 if (attr->ia_size < inode->i_size) {
643 /* 645 /*
644 * If truncating down to a partial page, then 646 * If truncating down to a partial page, then
@@ -671,6 +673,10 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
671 error = inode_change_ok(inode, attr); 673 error = inode_change_ok(inode, attr);
672 if (!error) 674 if (!error)
673 error = inode_setattr(inode, attr); 675 error = inode_setattr(inode, attr);
676#ifdef CONFIG_TMPFS_POSIX_ACL
677 if (!error && (attr->ia_valid & ATTR_MODE))
678 error = generic_acl_chmod(inode, &shmem_acl_ops);
679#endif
674 if (page) 680 if (page)
675 page_cache_release(page); 681 page_cache_release(page);
676 return error; 682 return error;
@@ -1046,12 +1052,12 @@ repeat:
1046 swappage = lookup_swap_cache(swap); 1052 swappage = lookup_swap_cache(swap);
1047 if (!swappage) { 1053 if (!swappage) {
1048 shmem_swp_unmap(entry); 1054 shmem_swp_unmap(entry);
1049 spin_unlock(&info->lock);
1050 /* here we actually do the io */ 1055 /* here we actually do the io */
1051 if (type && *type == VM_FAULT_MINOR) { 1056 if (type && *type == VM_FAULT_MINOR) {
1052 inc_page_state(pgmajfault); 1057 __count_vm_event(PGMAJFAULT);
1053 *type = VM_FAULT_MAJOR; 1058 *type = VM_FAULT_MAJOR;
1054 } 1059 }
1060 spin_unlock(&info->lock);
1055 swappage = shmem_swapin(info, swap, idx); 1061 swappage = shmem_swapin(info, swap, idx);
1056 if (!swappage) { 1062 if (!swappage) {
1057 spin_lock(&info->lock); 1063 spin_lock(&info->lock);
@@ -1352,7 +1358,6 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
1352 inode->i_mode = mode; 1358 inode->i_mode = mode;
1353 inode->i_uid = current->fsuid; 1359 inode->i_uid = current->fsuid;
1354 inode->i_gid = current->fsgid; 1360 inode->i_gid = current->fsgid;
1355 inode->i_blksize = PAGE_CACHE_SIZE;
1356 inode->i_blocks = 0; 1361 inode->i_blocks = 0;
1357 inode->i_mapping->a_ops = &shmem_aops; 1362 inode->i_mapping->a_ops = &shmem_aops;
1358 inode->i_mapping->backing_dev_info = &shmem_backing_dev_info; 1363 inode->i_mapping->backing_dev_info = &shmem_backing_dev_info;
@@ -1364,6 +1369,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
1364 1369
1365 switch (mode & S_IFMT) { 1370 switch (mode & S_IFMT) {
1366 default: 1371 default:
1372 inode->i_op = &shmem_special_inode_operations;
1367 init_special_inode(inode, mode, dev); 1373 init_special_inode(inode, mode, dev);
1368 break; 1374 break;
1369 case S_IFREG: 1375 case S_IFREG:
@@ -1684,7 +1690,11 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1684 iput(inode); 1690 iput(inode);
1685 return error; 1691 return error;
1686 } 1692 }
1687 error = 0; 1693 }
1694 error = shmem_acl_init(inode, dir);
1695 if (error) {
1696 iput(inode);
1697 return error;
1688 } 1698 }
1689 if (dir->i_mode & S_ISGID) { 1699 if (dir->i_mode & S_ISGID) {
1690 inode->i_gid = dir->i_gid; 1700 inode->i_gid = dir->i_gid;
@@ -1899,6 +1909,53 @@ static struct inode_operations shmem_symlink_inode_operations = {
1899 .put_link = shmem_put_link, 1909 .put_link = shmem_put_link,
1900}; 1910};
1901 1911
1912#ifdef CONFIG_TMPFS_POSIX_ACL
1913/**
1914 * Superblocks without xattr inode operations will get security.* xattr
1915 * support from the VFS "for free". As soon as we have any other xattrs
1916 * like ACLs, we also need to implement the security.* handlers at
1917 * filesystem level, though.
1918 */
1919
1920static size_t shmem_xattr_security_list(struct inode *inode, char *list,
1921 size_t list_len, const char *name,
1922 size_t name_len)
1923{
1924 return security_inode_listsecurity(inode, list, list_len);
1925}
1926
1927static int shmem_xattr_security_get(struct inode *inode, const char *name,
1928 void *buffer, size_t size)
1929{
1930 if (strcmp(name, "") == 0)
1931 return -EINVAL;
1932 return security_inode_getsecurity(inode, name, buffer, size,
1933 -EOPNOTSUPP);
1934}
1935
1936static int shmem_xattr_security_set(struct inode *inode, const char *name,
1937 const void *value, size_t size, int flags)
1938{
1939 if (strcmp(name, "") == 0)
1940 return -EINVAL;
1941 return security_inode_setsecurity(inode, name, value, size, flags);
1942}
1943
1944struct xattr_handler shmem_xattr_security_handler = {
1945 .prefix = XATTR_SECURITY_PREFIX,
1946 .list = shmem_xattr_security_list,
1947 .get = shmem_xattr_security_get,
1948 .set = shmem_xattr_security_set,
1949};
1950
1951static struct xattr_handler *shmem_xattr_handlers[] = {
1952 &shmem_xattr_acl_access_handler,
1953 &shmem_xattr_acl_default_handler,
1954 &shmem_xattr_security_handler,
1955 NULL
1956};
1957#endif
1958
1902static int shmem_parse_options(char *options, int *mode, uid_t *uid, 1959static int shmem_parse_options(char *options, int *mode, uid_t *uid,
1903 gid_t *gid, unsigned long *blocks, unsigned long *inodes, 1960 gid_t *gid, unsigned long *blocks, unsigned long *inodes,
1904 int *policy, nodemask_t *policy_nodes) 1961 int *policy, nodemask_t *policy_nodes)
@@ -2096,6 +2153,10 @@ static int shmem_fill_super(struct super_block *sb,
2096 sb->s_magic = TMPFS_MAGIC; 2153 sb->s_magic = TMPFS_MAGIC;
2097 sb->s_op = &shmem_ops; 2154 sb->s_op = &shmem_ops;
2098 sb->s_time_gran = 1; 2155 sb->s_time_gran = 1;
2156#ifdef CONFIG_TMPFS_POSIX_ACL
2157 sb->s_xattr = shmem_xattr_handlers;
2158 sb->s_flags |= MS_POSIXACL;
2159#endif
2099 2160
2100 inode = shmem_get_inode(sb, S_IFDIR | mode, 0); 2161 inode = shmem_get_inode(sb, S_IFDIR | mode, 0);
2101 if (!inode) 2162 if (!inode)
@@ -2132,6 +2193,7 @@ static void shmem_destroy_inode(struct inode *inode)
2132 /* only struct inode is valid if it's an inline symlink */ 2193 /* only struct inode is valid if it's an inline symlink */
2133 mpol_free_shared_policy(&SHMEM_I(inode)->policy); 2194 mpol_free_shared_policy(&SHMEM_I(inode)->policy);
2134 } 2195 }
2196 shmem_acl_destroy_inode(inode);
2135 kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode)); 2197 kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
2136} 2198}
2137 2199
@@ -2143,6 +2205,10 @@ static void init_once(void *foo, struct kmem_cache *cachep,
2143 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == 2205 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
2144 SLAB_CTOR_CONSTRUCTOR) { 2206 SLAB_CTOR_CONSTRUCTOR) {
2145 inode_init_once(&p->vfs_inode); 2207 inode_init_once(&p->vfs_inode);
2208#ifdef CONFIG_TMPFS_POSIX_ACL
2209 p->i_acl = NULL;
2210 p->i_default_acl = NULL;
2211#endif
2146 } 2212 }
2147} 2213}
2148 2214
@@ -2158,11 +2224,10 @@ static int init_inodecache(void)
2158 2224
2159static void destroy_inodecache(void) 2225static void destroy_inodecache(void)
2160{ 2226{
2161 if (kmem_cache_destroy(shmem_inode_cachep)) 2227 kmem_cache_destroy(shmem_inode_cachep);
2162 printk(KERN_INFO "shmem_inode_cache: not all structures were freed\n");
2163} 2228}
2164 2229
2165static struct address_space_operations shmem_aops = { 2230static const struct address_space_operations shmem_aops = {
2166 .writepage = shmem_writepage, 2231 .writepage = shmem_writepage,
2167 .set_page_dirty = __set_page_dirty_nobuffers, 2232 .set_page_dirty = __set_page_dirty_nobuffers,
2168#ifdef CONFIG_TMPFS 2233#ifdef CONFIG_TMPFS
@@ -2187,6 +2252,14 @@ static struct inode_operations shmem_inode_operations = {
2187 .truncate = shmem_truncate, 2252 .truncate = shmem_truncate,
2188 .setattr = shmem_notify_change, 2253 .setattr = shmem_notify_change,
2189 .truncate_range = shmem_truncate_range, 2254 .truncate_range = shmem_truncate_range,
2255#ifdef CONFIG_TMPFS_POSIX_ACL
2256 .setxattr = generic_setxattr,
2257 .getxattr = generic_getxattr,
2258 .listxattr = generic_listxattr,
2259 .removexattr = generic_removexattr,
2260 .permission = shmem_permission,
2261#endif
2262
2190}; 2263};
2191 2264
2192static struct inode_operations shmem_dir_inode_operations = { 2265static struct inode_operations shmem_dir_inode_operations = {
@@ -2201,6 +2274,25 @@ static struct inode_operations shmem_dir_inode_operations = {
2201 .mknod = shmem_mknod, 2274 .mknod = shmem_mknod,
2202 .rename = shmem_rename, 2275 .rename = shmem_rename,
2203#endif 2276#endif
2277#ifdef CONFIG_TMPFS_POSIX_ACL
2278 .setattr = shmem_notify_change,
2279 .setxattr = generic_setxattr,
2280 .getxattr = generic_getxattr,
2281 .listxattr = generic_listxattr,
2282 .removexattr = generic_removexattr,
2283 .permission = shmem_permission,
2284#endif
2285};
2286
2287static struct inode_operations shmem_special_inode_operations = {
2288#ifdef CONFIG_TMPFS_POSIX_ACL
2289 .setattr = shmem_notify_change,
2290 .setxattr = generic_setxattr,
2291 .getxattr = generic_getxattr,
2292 .listxattr = generic_listxattr,
2293 .removexattr = generic_removexattr,
2294 .permission = shmem_permission,
2295#endif
2204}; 2296};
2205 2297
2206static struct super_operations shmem_ops = { 2298static struct super_operations shmem_ops = {
@@ -2252,10 +2344,8 @@ static int __init init_tmpfs(void)
2252 printk(KERN_ERR "Could not register tmpfs\n"); 2344 printk(KERN_ERR "Could not register tmpfs\n");
2253 goto out2; 2345 goto out2;
2254 } 2346 }
2255#ifdef CONFIG_TMPFS 2347
2256 devfs_mk_dir("shm"); 2348 shm_mnt = vfs_kern_mount(&tmpfs_fs_type, MS_NOUSER,
2257#endif
2258 shm_mnt = do_kern_mount(tmpfs_fs_type.name, MS_NOUSER,
2259 tmpfs_fs_type.name, NULL); 2349 tmpfs_fs_type.name, NULL);
2260 if (IS_ERR(shm_mnt)) { 2350 if (IS_ERR(shm_mnt)) {
2261 error = PTR_ERR(shm_mnt); 2351 error = PTR_ERR(shm_mnt);