aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-16 15:04:02 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-16 15:04:02 -0500
commitbac5e54c29f352d962a2447d22735316b347b9f1 (patch)
tree7642993fa93164835ffaa2dacd341388193f1979 /mm
parent529e89430d6c0d64db8ac474cb95e68e2527c79a (diff)
parentc05c4edd876b7ae92787d1295868afcb89b6a348 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (38 commits) direct I/O fallback sync simplification ocfs: stop using do_sync_mapping_range cleanup blockdev_direct_IO locking make generic_acl slightly more generic sanitize xattr handler prototypes libfs: move EXPORT_SYMBOL for d_alloc_name vfs: force reval of target when following LAST_BIND symlinks (try #7) ima: limit imbalance msg Untangling ima mess, part 3: kill dead code in ima Untangling ima mess, part 2: deal with counters Untangling ima mess, part 1: alloc_file() O_TRUNC open shouldn't fail after file truncation ima: call ima_inode_free ima_inode_free IMA: clean up the IMA counts updating code ima: only insert at inode creation time ima: valid return code from ima_inode_alloc fs: move get_empty_filp() deffinition to internal.h Sanitize exec_permission_lite() Kill cached_lookup() and real_lookup() Kill path_lookup_open() ... Trivial conflicts in fs/direct-io.c
Diffstat (limited to 'mm')
-rw-r--r--mm/Makefile1
-rw-r--r--mm/filemap.c15
-rw-r--r--mm/shmem.c71
-rw-r--r--mm/shmem_acl.c171
4 files changed, 37 insertions, 221 deletions
diff --git a/mm/Makefile b/mm/Makefile
index 82131d0f8d85..7a68d2ab5560 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -22,7 +22,6 @@ obj-$(CONFIG_HUGETLBFS) += hugetlb.o
22obj-$(CONFIG_NUMA) += mempolicy.o 22obj-$(CONFIG_NUMA) += mempolicy.o
23obj-$(CONFIG_SPARSEMEM) += sparse.o 23obj-$(CONFIG_SPARSEMEM) += sparse.o
24obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o 24obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o
25obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o
26obj-$(CONFIG_SLOB) += slob.o 25obj-$(CONFIG_SLOB) += slob.o
27obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o 26obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o
28obj-$(CONFIG_KSM) += ksm.o 27obj-$(CONFIG_KSM) += ksm.o
diff --git a/mm/filemap.c b/mm/filemap.c
index 8b4d88f9249e..96ac6b0eb6cb 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2240,7 +2240,6 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
2240 size_t count, ssize_t written) 2240 size_t count, ssize_t written)
2241{ 2241{
2242 struct file *file = iocb->ki_filp; 2242 struct file *file = iocb->ki_filp;
2243 struct address_space *mapping = file->f_mapping;
2244 ssize_t status; 2243 ssize_t status;
2245 struct iov_iter i; 2244 struct iov_iter i;
2246 2245
@@ -2252,15 +2251,6 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
2252 *ppos = pos + status; 2251 *ppos = pos + status;
2253 } 2252 }
2254 2253
2255 /*
2256 * If we get here for O_DIRECT writes then we must have fallen through
2257 * to buffered writes (block instantiation inside i_size). So we sync
2258 * the file data here, to try to honour O_DIRECT expectations.
2259 */
2260 if (unlikely(file->f_flags & O_DIRECT) && written)
2261 status = filemap_write_and_wait_range(mapping,
2262 pos, pos + written - 1);
2263
2264 return written ? written : status; 2254 return written ? written : status;
2265} 2255}
2266EXPORT_SYMBOL(generic_file_buffered_write); 2256EXPORT_SYMBOL(generic_file_buffered_write);
@@ -2359,10 +2349,7 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
2359 * semantics. 2349 * semantics.
2360 */ 2350 */
2361 endbyte = pos + written_buffered - written - 1; 2351 endbyte = pos + written_buffered - written - 1;
2362 err = do_sync_mapping_range(file->f_mapping, pos, endbyte, 2352 err = filemap_write_and_wait_range(file->f_mapping, pos, endbyte);
2363 SYNC_FILE_RANGE_WAIT_BEFORE|
2364 SYNC_FILE_RANGE_WRITE|
2365 SYNC_FILE_RANGE_WAIT_AFTER);
2366 if (err == 0) { 2353 if (err == 0) {
2367 written = written_buffered; 2354 written = written_buffered;
2368 invalidate_mapping_pages(mapping, 2355 invalidate_mapping_pages(mapping,
diff --git a/mm/shmem.c b/mm/shmem.c
index 4fb41c83daca..f8485062f3ba 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
34static struct vfsmount *shm_mnt; 33static 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);
@@ -1824,11 +1824,13 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1824 return error; 1824 return error;
1825 } 1825 }
1826 } 1826 }
1827 error = shmem_acl_init(inode, dir); 1827#ifdef CONFIG_TMPFS_POSIX_ACL
1828 error = generic_acl_init(inode, dir);
1828 if (error) { 1829 if (error) {
1829 iput(inode); 1830 iput(inode);
1830 return error; 1831 return error;
1831 } 1832 }
1833#endif
1832 if (dir->i_mode & S_ISGID) { 1834 if (dir->i_mode & S_ISGID) {
1833 inode->i_gid = dir->i_gid; 1835 inode->i_gid = dir->i_gid;
1834 if (S_ISDIR(mode)) 1836 if (S_ISDIR(mode))
@@ -2043,27 +2045,28 @@ static const struct inode_operations shmem_symlink_inode_operations = {
2043 * filesystem level, though. 2045 * filesystem level, though.
2044 */ 2046 */
2045 2047
2046static size_t shmem_xattr_security_list(struct inode *inode, char *list, 2048static size_t shmem_xattr_security_list(struct dentry *dentry, char *list,
2047 size_t list_len, const char *name, 2049 size_t list_len, const char *name,
2048 size_t name_len) 2050 size_t name_len, int handler_flags)
2049{ 2051{
2050 return security_inode_listsecurity(inode, list, list_len); 2052 return security_inode_listsecurity(dentry->d_inode, list, list_len);
2051} 2053}
2052 2054
2053static int shmem_xattr_security_get(struct inode *inode, const char *name, 2055static int shmem_xattr_security_get(struct dentry *dentry, const char *name,
2054 void *buffer, size_t size) 2056 void *buffer, size_t size, int handler_flags)
2055{ 2057{
2056 if (strcmp(name, "") == 0) 2058 if (strcmp(name, "") == 0)
2057 return -EINVAL; 2059 return -EINVAL;
2058 return xattr_getsecurity(inode, name, buffer, size); 2060 return xattr_getsecurity(dentry->d_inode, name, buffer, size);
2059} 2061}
2060 2062
2061static int shmem_xattr_security_set(struct inode *inode, const char *name, 2063static int shmem_xattr_security_set(struct dentry *dentry, const char *name,
2062 const void *value, size_t size, int flags) 2064 const void *value, size_t size, int flags, int handler_flags)
2063{ 2065{
2064 if (strcmp(name, "") == 0) 2066 if (strcmp(name, "") == 0)
2065 return -EINVAL; 2067 return -EINVAL;
2066 return security_inode_setsecurity(inode, name, value, size, flags); 2068 return security_inode_setsecurity(dentry->d_inode, name, value,
2069 size, flags);
2067} 2070}
2068 2071
2069static struct xattr_handler shmem_xattr_security_handler = { 2072static struct xattr_handler shmem_xattr_security_handler = {
@@ -2074,8 +2077,8 @@ static struct xattr_handler shmem_xattr_security_handler = {
2074}; 2077};
2075 2078
2076static struct xattr_handler *shmem_xattr_handlers[] = { 2079static struct xattr_handler *shmem_xattr_handlers[] = {
2077 &shmem_xattr_acl_access_handler, 2080 &generic_acl_access_handler,
2078 &shmem_xattr_acl_default_handler, 2081 &generic_acl_default_handler,
2079 &shmem_xattr_security_handler, 2082 &shmem_xattr_security_handler,
2080 NULL 2083 NULL
2081}; 2084};
@@ -2454,7 +2457,7 @@ static const struct inode_operations shmem_inode_operations = {
2454 .getxattr = generic_getxattr, 2457 .getxattr = generic_getxattr,
2455 .listxattr = generic_listxattr, 2458 .listxattr = generic_listxattr,
2456 .removexattr = generic_removexattr, 2459 .removexattr = generic_removexattr,
2457 .check_acl = shmem_check_acl, 2460 .check_acl = generic_check_acl,
2458#endif 2461#endif
2459 2462
2460}; 2463};
@@ -2477,7 +2480,7 @@ static const struct inode_operations shmem_dir_inode_operations = {
2477 .getxattr = generic_getxattr, 2480 .getxattr = generic_getxattr,
2478 .listxattr = generic_listxattr, 2481 .listxattr = generic_listxattr,
2479 .removexattr = generic_removexattr, 2482 .removexattr = generic_removexattr,
2480 .check_acl = shmem_check_acl, 2483 .check_acl = generic_check_acl,
2481#endif 2484#endif
2482}; 2485};
2483 2486
@@ -2488,7 +2491,7 @@ static const struct inode_operations shmem_special_inode_operations = {
2488 .getxattr = generic_getxattr, 2491 .getxattr = generic_getxattr,
2489 .listxattr = generic_listxattr, 2492 .listxattr = generic_listxattr,
2490 .removexattr = generic_removexattr, 2493 .removexattr = generic_removexattr,
2491 .check_acl = shmem_check_acl, 2494 .check_acl = generic_check_acl,
2492#endif 2495#endif
2493}; 2496};
2494 2497
@@ -2626,7 +2629,8 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags
2626 int error; 2629 int error;
2627 struct file *file; 2630 struct file *file;
2628 struct inode *inode; 2631 struct inode *inode;
2629 struct dentry *dentry, *root; 2632 struct path path;
2633 struct dentry *root;
2630 struct qstr this; 2634 struct qstr this;
2631 2635
2632 if (IS_ERR(shm_mnt)) 2636 if (IS_ERR(shm_mnt))
@@ -2643,38 +2647,35 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags
2643 this.len = strlen(name); 2647 this.len = strlen(name);
2644 this.hash = 0; /* will go */ 2648 this.hash = 0; /* will go */
2645 root = shm_mnt->mnt_root; 2649 root = shm_mnt->mnt_root;
2646 dentry = d_alloc(root, &this); 2650 path.dentry = d_alloc(root, &this);
2647 if (!dentry) 2651 if (!path.dentry)
2648 goto put_memory; 2652 goto put_memory;
2649 2653 path.mnt = mntget(shm_mnt);
2650 error = -ENFILE;
2651 file = get_empty_filp();
2652 if (!file)
2653 goto put_dentry;
2654 2654
2655 error = -ENOSPC; 2655 error = -ENOSPC;
2656 inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags); 2656 inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags);
2657 if (!inode) 2657 if (!inode)
2658 goto close_file; 2658 goto put_dentry;
2659 2659
2660 d_instantiate(dentry, inode); 2660 d_instantiate(path.dentry, inode);
2661 inode->i_size = size; 2661 inode->i_size = size;
2662 inode->i_nlink = 0; /* It is unlinked */ 2662 inode->i_nlink = 0; /* It is unlinked */
2663 init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
2664 &shmem_file_operations);
2665
2666#ifndef CONFIG_MMU 2663#ifndef CONFIG_MMU
2667 error = ramfs_nommu_expand_for_mapping(inode, size); 2664 error = ramfs_nommu_expand_for_mapping(inode, size);
2668 if (error) 2665 if (error)
2669 goto close_file; 2666 goto put_dentry;
2670#endif 2667#endif
2671 ima_counts_get(file); 2668
2669 error = -ENFILE;
2670 file = alloc_file(&path, FMODE_WRITE | FMODE_READ,
2671 &shmem_file_operations);
2672 if (!file)
2673 goto put_dentry;
2674
2672 return file; 2675 return file;
2673 2676
2674close_file:
2675 put_filp(file);
2676put_dentry: 2677put_dentry:
2677 dput(dentry); 2678 path_put(&path);
2678put_memory: 2679put_memory:
2679 shmem_unacct_size(flags, size); 2680 shmem_unacct_size(flags, size);
2680 return ERR_PTR(error); 2681 return ERR_PTR(error);
diff --git a/mm/shmem_acl.c b/mm/shmem_acl.c
deleted file mode 100644
index df2c87fdae50..000000000000
--- a/mm/shmem_acl.c
+++ /dev/null
@@ -1,171 +0,0 @@
1/*
2 * mm/shmem_acl.c
3 *
4 * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
5 *
6 * This file is released under the GPL.
7 */
8
9#include <linux/fs.h>
10#include <linux/shmem_fs.h>
11#include <linux/xattr.h>
12#include <linux/generic_acl.h>
13
14/**
15 * shmem_get_acl - generic_acl_operations->getacl() operation
16 */
17static struct posix_acl *
18shmem_get_acl(struct inode *inode, int type)
19{
20 struct posix_acl *acl = NULL;
21
22 spin_lock(&inode->i_lock);
23 switch(type) {
24 case ACL_TYPE_ACCESS:
25 acl = posix_acl_dup(inode->i_acl);
26 break;
27
28 case ACL_TYPE_DEFAULT:
29 acl = posix_acl_dup(inode->i_default_acl);
30 break;
31 }
32 spin_unlock(&inode->i_lock);
33
34 return acl;
35}
36
37/**
38 * shmem_set_acl - generic_acl_operations->setacl() operation
39 */
40static void
41shmem_set_acl(struct inode *inode, int type, struct posix_acl *acl)
42{
43 struct posix_acl *free = NULL;
44
45 spin_lock(&inode->i_lock);
46 switch(type) {
47 case ACL_TYPE_ACCESS:
48 free = inode->i_acl;
49 inode->i_acl = posix_acl_dup(acl);
50 break;
51
52 case ACL_TYPE_DEFAULT:
53 free = inode->i_default_acl;
54 inode->i_default_acl = posix_acl_dup(acl);
55 break;
56 }
57 spin_unlock(&inode->i_lock);
58 posix_acl_release(free);
59}
60
61struct generic_acl_operations shmem_acl_ops = {
62 .getacl = shmem_get_acl,
63 .setacl = shmem_set_acl,
64};
65
66/**
67 * shmem_list_acl_access, shmem_get_acl_access, shmem_set_acl_access,
68 * shmem_xattr_acl_access_handler - plumbing code to implement the
69 * system.posix_acl_access xattr using the generic acl functions.
70 */
71
72static size_t
73shmem_list_acl_access(struct inode *inode, char *list, size_t list_size,
74 const char *name, size_t name_len)
75{
76 return generic_acl_list(inode, &shmem_acl_ops, ACL_TYPE_ACCESS,
77 list, list_size);
78}
79
80static int
81shmem_get_acl_access(struct inode *inode, const char *name, void *buffer,
82 size_t size)
83{
84 if (strcmp(name, "") != 0)
85 return -EINVAL;
86 return generic_acl_get(inode, &shmem_acl_ops, ACL_TYPE_ACCESS, buffer,
87 size);
88}
89
90static int
91shmem_set_acl_access(struct inode *inode, const char *name, const void *value,
92 size_t size, int flags)
93{
94 if (strcmp(name, "") != 0)
95 return -EINVAL;
96 return generic_acl_set(inode, &shmem_acl_ops, ACL_TYPE_ACCESS, value,
97 size);
98}
99
100struct xattr_handler shmem_xattr_acl_access_handler = {
101 .prefix = POSIX_ACL_XATTR_ACCESS,
102 .list = shmem_list_acl_access,
103 .get = shmem_get_acl_access,
104 .set = shmem_set_acl_access,
105};
106
107/**
108 * shmem_list_acl_default, shmem_get_acl_default, shmem_set_acl_default,
109 * shmem_xattr_acl_default_handler - plumbing code to implement the
110 * system.posix_acl_default xattr using the generic acl functions.
111 */
112
113static size_t
114shmem_list_acl_default(struct inode *inode, char *list, size_t list_size,
115 const char *name, size_t name_len)
116{
117 return generic_acl_list(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT,
118 list, list_size);
119}
120
121static int
122shmem_get_acl_default(struct inode *inode, const char *name, void *buffer,
123 size_t size)
124{
125 if (strcmp(name, "") != 0)
126 return -EINVAL;
127 return generic_acl_get(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT, buffer,
128 size);
129}
130
131static int
132shmem_set_acl_default(struct inode *inode, const char *name, const void *value,
133 size_t size, int flags)
134{
135 if (strcmp(name, "") != 0)
136 return -EINVAL;
137 return generic_acl_set(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT, value,
138 size);
139}
140
141struct xattr_handler shmem_xattr_acl_default_handler = {
142 .prefix = POSIX_ACL_XATTR_DEFAULT,
143 .list = shmem_list_acl_default,
144 .get = shmem_get_acl_default,
145 .set = shmem_set_acl_default,
146};
147
148/**
149 * shmem_acl_init - Inizialize the acl(s) of a new inode
150 */
151int
152shmem_acl_init(struct inode *inode, struct inode *dir)
153{
154 return generic_acl_init(inode, dir, &shmem_acl_ops);
155}
156
157/**
158 * shmem_check_acl - check_acl() callback for generic_permission()
159 */
160int
161shmem_check_acl(struct inode *inode, int mask)
162{
163 struct posix_acl *acl = shmem_get_acl(inode, ACL_TYPE_ACCESS);
164
165 if (acl) {
166 int error = posix_acl_permission(inode, acl, mask);
167 posix_acl_release(acl);
168 return error;
169 }
170 return -EAGAIN;
171}