aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c184
1 files changed, 10 insertions, 174 deletions
diff --git a/fs/open.c b/fs/open.c
index 74e5cd9f718e..630715f9f73d 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -17,7 +17,6 @@
17#include <linux/securebits.h> 17#include <linux/securebits.h>
18#include <linux/security.h> 18#include <linux/security.h>
19#include <linux/mount.h> 19#include <linux/mount.h>
20#include <linux/vfs.h>
21#include <linux/fcntl.h> 20#include <linux/fcntl.h>
22#include <linux/slab.h> 21#include <linux/slab.h>
23#include <asm/uaccess.h> 22#include <asm/uaccess.h>
@@ -30,174 +29,10 @@
30#include <linux/falloc.h> 29#include <linux/falloc.h>
31#include <linux/fs_struct.h> 30#include <linux/fs_struct.h>
32#include <linux/ima.h> 31#include <linux/ima.h>
32#include <linux/dnotify.h>
33 33
34#include "internal.h" 34#include "internal.h"
35 35
36int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
37{
38 int retval = -ENODEV;
39
40 if (dentry) {
41 retval = -ENOSYS;
42 if (dentry->d_sb->s_op->statfs) {
43 memset(buf, 0, sizeof(*buf));
44 retval = security_sb_statfs(dentry);
45 if (retval)
46 return retval;
47 retval = dentry->d_sb->s_op->statfs(dentry, buf);
48 if (retval == 0 && buf->f_frsize == 0)
49 buf->f_frsize = buf->f_bsize;
50 }
51 }
52 return retval;
53}
54
55EXPORT_SYMBOL(vfs_statfs);
56
57static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf)
58{
59 struct kstatfs st;
60 int retval;
61
62 retval = vfs_statfs(dentry, &st);
63 if (retval)
64 return retval;
65
66 if (sizeof(*buf) == sizeof(st))
67 memcpy(buf, &st, sizeof(st));
68 else {
69 if (sizeof buf->f_blocks == 4) {
70 if ((st.f_blocks | st.f_bfree | st.f_bavail |
71 st.f_bsize | st.f_frsize) &
72 0xffffffff00000000ULL)
73 return -EOVERFLOW;
74 /*
75 * f_files and f_ffree may be -1; it's okay to stuff
76 * that into 32 bits
77 */
78 if (st.f_files != -1 &&
79 (st.f_files & 0xffffffff00000000ULL))
80 return -EOVERFLOW;
81 if (st.f_ffree != -1 &&
82 (st.f_ffree & 0xffffffff00000000ULL))
83 return -EOVERFLOW;
84 }
85
86 buf->f_type = st.f_type;
87 buf->f_bsize = st.f_bsize;
88 buf->f_blocks = st.f_blocks;
89 buf->f_bfree = st.f_bfree;
90 buf->f_bavail = st.f_bavail;
91 buf->f_files = st.f_files;
92 buf->f_ffree = st.f_ffree;
93 buf->f_fsid = st.f_fsid;
94 buf->f_namelen = st.f_namelen;
95 buf->f_frsize = st.f_frsize;
96 memset(buf->f_spare, 0, sizeof(buf->f_spare));
97 }
98 return 0;
99}
100
101static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf)
102{
103 struct kstatfs st;
104 int retval;
105
106 retval = vfs_statfs(dentry, &st);
107 if (retval)
108 return retval;
109
110 if (sizeof(*buf) == sizeof(st))
111 memcpy(buf, &st, sizeof(st));
112 else {
113 buf->f_type = st.f_type;
114 buf->f_bsize = st.f_bsize;
115 buf->f_blocks = st.f_blocks;
116 buf->f_bfree = st.f_bfree;
117 buf->f_bavail = st.f_bavail;
118 buf->f_files = st.f_files;
119 buf->f_ffree = st.f_ffree;
120 buf->f_fsid = st.f_fsid;
121 buf->f_namelen = st.f_namelen;
122 buf->f_frsize = st.f_frsize;
123 memset(buf->f_spare, 0, sizeof(buf->f_spare));
124 }
125 return 0;
126}
127
128SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf)
129{
130 struct path path;
131 int error;
132
133 error = user_path(pathname, &path);
134 if (!error) {
135 struct statfs tmp;
136 error = vfs_statfs_native(path.dentry, &tmp);
137 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
138 error = -EFAULT;
139 path_put(&path);
140 }
141 return error;
142}
143
144SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf)
145{
146 struct path path;
147 long error;
148
149 if (sz != sizeof(*buf))
150 return -EINVAL;
151 error = user_path(pathname, &path);
152 if (!error) {
153 struct statfs64 tmp;
154 error = vfs_statfs64(path.dentry, &tmp);
155 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
156 error = -EFAULT;
157 path_put(&path);
158 }
159 return error;
160}
161
162SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf)
163{
164 struct file * file;
165 struct statfs tmp;
166 int error;
167
168 error = -EBADF;
169 file = fget(fd);
170 if (!file)
171 goto out;
172 error = vfs_statfs_native(file->f_path.dentry, &tmp);
173 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
174 error = -EFAULT;
175 fput(file);
176out:
177 return error;
178}
179
180SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf)
181{
182 struct file * file;
183 struct statfs64 tmp;
184 int error;
185
186 if (sz != sizeof(*buf))
187 return -EINVAL;
188
189 error = -EBADF;
190 file = fget(fd);
191 if (!file)
192 goto out;
193 error = vfs_statfs64(file->f_path.dentry, &tmp);
194 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
195 error = -EFAULT;
196 fput(file);
197out:
198 return error;
199}
200
201int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, 36int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
202 struct file *filp) 37 struct file *filp)
203{ 38{
@@ -276,7 +111,7 @@ static long do_sys_truncate(const char __user *pathname, loff_t length)
276 111
277 error = locks_verify_truncate(inode, NULL, length); 112 error = locks_verify_truncate(inode, NULL, length);
278 if (!error) 113 if (!error)
279 error = security_path_truncate(&path, length, 0); 114 error = security_path_truncate(&path);
280 if (!error) 115 if (!error)
281 error = do_truncate(path.dentry, length, 0, NULL); 116 error = do_truncate(path.dentry, length, 0, NULL);
282 117
@@ -331,8 +166,7 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
331 166
332 error = locks_verify_truncate(inode, file, length); 167 error = locks_verify_truncate(inode, file, length);
333 if (!error) 168 if (!error)
334 error = security_path_truncate(&file->f_path, length, 169 error = security_path_truncate(&file->f_path);
335 ATTR_MTIME|ATTR_CTIME);
336 if (!error) 170 if (!error)
337 error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); 171 error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
338out_putf: 172out_putf:
@@ -533,7 +367,7 @@ SYSCALL_DEFINE1(chdir, const char __user *, filename)
533 if (error) 367 if (error)
534 goto out; 368 goto out;
535 369
536 error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS); 370 error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
537 if (error) 371 if (error)
538 goto dput_and_out; 372 goto dput_and_out;
539 373
@@ -562,7 +396,7 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd)
562 if (!S_ISDIR(inode->i_mode)) 396 if (!S_ISDIR(inode->i_mode))
563 goto out_putf; 397 goto out_putf;
564 398
565 error = inode_permission(inode, MAY_EXEC | MAY_ACCESS); 399 error = inode_permission(inode, MAY_EXEC | MAY_CHDIR);
566 if (!error) 400 if (!error)
567 set_fs_pwd(current->fs, &file->f_path); 401 set_fs_pwd(current->fs, &file->f_path);
568out_putf: 402out_putf:
@@ -580,7 +414,7 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
580 if (error) 414 if (error)
581 goto out; 415 goto out;
582 416
583 error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS); 417 error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
584 if (error) 418 if (error)
585 goto dput_and_out; 419 goto dput_and_out;
586 420
@@ -1054,7 +888,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
1054 put_unused_fd(fd); 888 put_unused_fd(fd);
1055 fd = PTR_ERR(f); 889 fd = PTR_ERR(f);
1056 } else { 890 } else {
1057 fsnotify_open(f->f_path.dentry); 891 fsnotify_open(f);
1058 fd_install(fd, f); 892 fd_install(fd, f);
1059 } 893 }
1060 } 894 }
@@ -1197,7 +1031,9 @@ EXPORT_SYMBOL(generic_file_open);
1197 1031
1198/* 1032/*
1199 * This is used by subsystems that don't want seekable 1033 * This is used by subsystems that don't want seekable
1200 * file descriptors 1034 * file descriptors. The function is not supposed to ever fail, the only
1035 * reason it returns an 'int' and not 'void' is so that it can be plugged
1036 * directly into file_operations structure.
1201 */ 1037 */
1202int nonseekable_open(struct inode *inode, struct file *filp) 1038int nonseekable_open(struct inode *inode, struct file *filp)
1203{ 1039{