Diff markup
1 /* 1 /*
2 * linux/fs/open.c 2 * linux/fs/open.c
3 * 3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */ 5 */
6 6
7 #include <linux/string.h> 7 #include <linux/string.h>
8 #include <linux/mm.h> 8 #include <linux/mm.h>
>> 9 #include <linux/utime.h>
9 #include <linux/file.h> 10 #include <linux/file.h>
>> 11 #include <linux/smp_lock.h>
10 #include <linux/quotaops.h> 12 #include <linux/quotaops.h>
11 #include <linux/fsnotify.h> !! 13 #include <linux/dnotify.h>
12 #include <linux/module.h> 14 #include <linux/module.h>
13 #include <linux/slab.h> 15 #include <linux/slab.h>
14 #include <linux/tty.h> 16 #include <linux/tty.h>
15 #include <linux/namei.h> 17 #include <linux/namei.h>
16 #include <linux/backing-dev.h> 18 #include <linux/backing-dev.h>
17 #include <linux/capability.h> <<
18 #include <linux/security.h> 19 #include <linux/security.h>
19 #include <linux/mount.h> 20 #include <linux/mount.h>
20 #include <linux/vfs.h> 21 #include <linux/vfs.h>
21 #include <linux/fcntl.h> <<
22 #include <asm/uaccess.h> 22 #include <asm/uaccess.h>
23 #include <linux/fs.h> 23 #include <linux/fs.h>
24 #include <linux/personality.h> <<
25 #include <linux/pagemap.h> 24 #include <linux/pagemap.h>
26 #include <linux/syscalls.h> 25 #include <linux/syscalls.h>
27 #include <linux/rcupdate.h> <<
28 #include <linux/audit.h> <<
29 #include <linux/falloc.h> <<
30 26
31 int vfs_statfs(struct dentry *dentry, struct k !! 27 #include <asm/unistd.h>
>> 28
>> 29 int vfs_statfs(struct super_block *sb, struct kstatfs *buf)
32 { 30 {
33 int retval = -ENODEV; 31 int retval = -ENODEV;
34 32
35 if (dentry) { !! 33 if (sb) {
36 retval = -ENOSYS; 34 retval = -ENOSYS;
37 if (dentry->d_sb->s_op->statfs !! 35 if (sb->s_op->statfs) {
38 memset(buf, 0, sizeof( 36 memset(buf, 0, sizeof(*buf));
39 retval = security_sb_s !! 37 retval = security_sb_statfs(sb);
40 if (retval) 38 if (retval)
41 return retval; 39 return retval;
42 retval = dentry->d_sb- !! 40 retval = sb->s_op->statfs(sb, buf);
43 if (retval == 0 && buf 41 if (retval == 0 && buf->f_frsize == 0)
44 buf->f_frsize 42 buf->f_frsize = buf->f_bsize;
45 } 43 }
46 } 44 }
47 return retval; 45 return retval;
48 } 46 }
49 47
50 EXPORT_SYMBOL(vfs_statfs); 48 EXPORT_SYMBOL(vfs_statfs);
51 49
52 static int vfs_statfs_native(struct dentry *de !! 50 static int vfs_statfs_native(struct super_block *sb, struct statfs *buf)
53 { 51 {
54 struct kstatfs st; 52 struct kstatfs st;
55 int retval; 53 int retval;
56 54
57 retval = vfs_statfs(dentry, &st); !! 55 retval = vfs_statfs(sb, &st);
58 if (retval) 56 if (retval)
59 return retval; 57 return retval;
60 58
61 if (sizeof(*buf) == sizeof(st)) 59 if (sizeof(*buf) == sizeof(st))
62 memcpy(buf, &st, sizeof(st)); 60 memcpy(buf, &st, sizeof(st));
63 else { 61 else {
64 if (sizeof buf->f_blocks == 4) 62 if (sizeof buf->f_blocks == 4) {
65 if ((st.f_blocks | st. 63 if ((st.f_blocks | st.f_bfree | st.f_bavail) &
66 0xffffffff00000000 64 0xffffffff00000000ULL)
67 return -EOVERF 65 return -EOVERFLOW;
68 /* 66 /*
69 * f_files and f_ffree 67 * f_files and f_ffree may be -1; it's okay to stuff
70 * that into 32 bits 68 * that into 32 bits
71 */ 69 */
72 if (st.f_files != -1 & 70 if (st.f_files != -1 &&
73 (st.f_files & 0xff 71 (st.f_files & 0xffffffff00000000ULL))
74 return -EOVERF 72 return -EOVERFLOW;
75 if (st.f_ffree != -1 & 73 if (st.f_ffree != -1 &&
76 (st.f_ffree & 0xff 74 (st.f_ffree & 0xffffffff00000000ULL))
77 return -EOVERF 75 return -EOVERFLOW;
78 } 76 }
79 77
80 buf->f_type = st.f_type; 78 buf->f_type = st.f_type;
81 buf->f_bsize = st.f_bsize; 79 buf->f_bsize = st.f_bsize;
82 buf->f_blocks = st.f_blocks; 80 buf->f_blocks = st.f_blocks;
83 buf->f_bfree = st.f_bfree; 81 buf->f_bfree = st.f_bfree;
84 buf->f_bavail = st.f_bavail; 82 buf->f_bavail = st.f_bavail;
85 buf->f_files = st.f_files; 83 buf->f_files = st.f_files;
86 buf->f_ffree = st.f_ffree; 84 buf->f_ffree = st.f_ffree;
87 buf->f_fsid = st.f_fsid; 85 buf->f_fsid = st.f_fsid;
88 buf->f_namelen = st.f_namelen; 86 buf->f_namelen = st.f_namelen;
89 buf->f_frsize = st.f_frsize; 87 buf->f_frsize = st.f_frsize;
90 memset(buf->f_spare, 0, sizeof 88 memset(buf->f_spare, 0, sizeof(buf->f_spare));
91 } 89 }
92 return 0; 90 return 0;
93 } 91 }
94 92
95 static int vfs_statfs64(struct dentry *dentry, !! 93 static int vfs_statfs64(struct super_block *sb, struct statfs64 *buf)
96 { 94 {
97 struct kstatfs st; 95 struct kstatfs st;
98 int retval; 96 int retval;
99 97
100 retval = vfs_statfs(dentry, &st); !! 98 retval = vfs_statfs(sb, &st);
101 if (retval) 99 if (retval)
102 return retval; 100 return retval;
103 101
104 if (sizeof(*buf) == sizeof(st)) 102 if (sizeof(*buf) == sizeof(st))
105 memcpy(buf, &st, sizeof(st)); 103 memcpy(buf, &st, sizeof(st));
106 else { 104 else {
107 buf->f_type = st.f_type; 105 buf->f_type = st.f_type;
108 buf->f_bsize = st.f_bsize; 106 buf->f_bsize = st.f_bsize;
109 buf->f_blocks = st.f_blocks; 107 buf->f_blocks = st.f_blocks;
110 buf->f_bfree = st.f_bfree; 108 buf->f_bfree = st.f_bfree;
111 buf->f_bavail = st.f_bavail; 109 buf->f_bavail = st.f_bavail;
112 buf->f_files = st.f_files; 110 buf->f_files = st.f_files;
113 buf->f_ffree = st.f_ffree; 111 buf->f_ffree = st.f_ffree;
114 buf->f_fsid = st.f_fsid; 112 buf->f_fsid = st.f_fsid;
115 buf->f_namelen = st.f_namelen; 113 buf->f_namelen = st.f_namelen;
116 buf->f_frsize = st.f_frsize; 114 buf->f_frsize = st.f_frsize;
117 memset(buf->f_spare, 0, sizeof 115 memset(buf->f_spare, 0, sizeof(buf->f_spare));
118 } 116 }
119 return 0; 117 return 0;
120 } 118 }
121 119
122 asmlinkage long sys_statfs(const char __user * 120 asmlinkage long sys_statfs(const char __user * path, struct statfs __user * buf)
123 { 121 {
124 struct nameidata nd; 122 struct nameidata nd;
125 int error; 123 int error;
126 124
127 error = user_path_walk(path, &nd); 125 error = user_path_walk(path, &nd);
128 if (!error) { 126 if (!error) {
129 struct statfs tmp; 127 struct statfs tmp;
130 error = vfs_statfs_native(nd.p !! 128 error = vfs_statfs_native(nd.dentry->d_inode->i_sb, &tmp);
131 if (!error && copy_to_user(buf 129 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
132 error = -EFAULT; 130 error = -EFAULT;
133 path_put(&nd.path); !! 131 path_release(&nd);
134 } 132 }
135 return error; 133 return error;
136 } 134 }
137 135
138 136
139 asmlinkage long sys_statfs64(const char __user 137 asmlinkage long sys_statfs64(const char __user *path, size_t sz, struct statfs64 __user *buf)
140 { 138 {
141 struct nameidata nd; 139 struct nameidata nd;
142 long error; 140 long error;
143 141
144 if (sz != sizeof(*buf)) 142 if (sz != sizeof(*buf))
145 return -EINVAL; 143 return -EINVAL;
146 error = user_path_walk(path, &nd); 144 error = user_path_walk(path, &nd);
147 if (!error) { 145 if (!error) {
148 struct statfs64 tmp; 146 struct statfs64 tmp;
149 error = vfs_statfs64(nd.path.d !! 147 error = vfs_statfs64(nd.dentry->d_inode->i_sb, &tmp);
150 if (!error && copy_to_user(buf 148 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
151 error = -EFAULT; 149 error = -EFAULT;
152 path_put(&nd.path); !! 150 path_release(&nd);
153 } 151 }
154 return error; 152 return error;
155 } 153 }
156 154
157 155
158 asmlinkage long sys_fstatfs(unsigned int fd, s 156 asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user * buf)
159 { 157 {
160 struct file * file; 158 struct file * file;
161 struct statfs tmp; 159 struct statfs tmp;
162 int error; 160 int error;
163 161
164 error = -EBADF; 162 error = -EBADF;
165 file = fget(fd); 163 file = fget(fd);
166 if (!file) 164 if (!file)
167 goto out; 165 goto out;
168 error = vfs_statfs_native(file->f_path !! 166 error = vfs_statfs_native(file->f_dentry->d_inode->i_sb, &tmp);
169 if (!error && copy_to_user(buf, &tmp, 167 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
170 error = -EFAULT; 168 error = -EFAULT;
171 fput(file); 169 fput(file);
172 out: 170 out:
173 return error; 171 return error;
174 } 172 }
175 173
176 asmlinkage long sys_fstatfs64(unsigned int fd, 174 asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, struct statfs64 __user *buf)
177 { 175 {
178 struct file * file; 176 struct file * file;
179 struct statfs64 tmp; 177 struct statfs64 tmp;
180 int error; 178 int error;
181 179
182 if (sz != sizeof(*buf)) 180 if (sz != sizeof(*buf))
183 return -EINVAL; 181 return -EINVAL;
184 182
185 error = -EBADF; 183 error = -EBADF;
186 file = fget(fd); 184 file = fget(fd);
187 if (!file) 185 if (!file)
188 goto out; 186 goto out;
189 error = vfs_statfs64(file->f_path.dent !! 187 error = vfs_statfs64(file->f_dentry->d_inode->i_sb, &tmp);
190 if (!error && copy_to_user(buf, &tmp, 188 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
191 error = -EFAULT; 189 error = -EFAULT;
192 fput(file); 190 fput(file);
193 out: 191 out:
194 return error; 192 return error;
195 } 193 }
196 194
197 int do_truncate(struct dentry *dentry, loff_t !! 195 int do_truncate(struct dentry *dentry, loff_t length)
198 struct file *filp) <<
199 { 196 {
200 int err; 197 int err;
201 struct iattr newattrs; 198 struct iattr newattrs;
202 199
203 /* Not pretty: "inode->i_size" shouldn 200 /* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
204 if (length < 0) 201 if (length < 0)
205 return -EINVAL; 202 return -EINVAL;
206 203
207 newattrs.ia_size = length; 204 newattrs.ia_size = length;
208 newattrs.ia_valid = ATTR_SIZE | time_a !! 205 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
209 if (filp) { <<
210 newattrs.ia_file = filp; <<
211 newattrs.ia_valid |= ATTR_FILE <<
212 } <<
213 206
214 /* Remove suid/sgid on truncate too */ !! 207 down(&dentry->d_inode->i_sem);
215 newattrs.ia_valid |= should_remove_sui <<
216 <<
217 mutex_lock(&dentry->d_inode->i_mutex); <<
218 err = notify_change(dentry, &newattrs) 208 err = notify_change(dentry, &newattrs);
219 mutex_unlock(&dentry->d_inode->i_mutex !! 209 up(&dentry->d_inode->i_sem);
220 return err; 210 return err;
221 } 211 }
222 212
223 static long do_sys_truncate(const char __user !! 213 static inline long do_sys_truncate(const char __user * path, loff_t length)
224 { 214 {
225 struct nameidata nd; 215 struct nameidata nd;
226 struct inode * inode; 216 struct inode * inode;
227 int error; 217 int error;
228 218
229 error = -EINVAL; 219 error = -EINVAL;
230 if (length < 0) /* sorry, but loff_t s 220 if (length < 0) /* sorry, but loff_t says... */
231 goto out; 221 goto out;
232 222
233 error = user_path_walk(path, &nd); 223 error = user_path_walk(path, &nd);
234 if (error) 224 if (error)
235 goto out; 225 goto out;
236 inode = nd.path.dentry->d_inode; !! 226 inode = nd.dentry->d_inode;
237 227
238 /* For directories it's -EISDIR, for o 228 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
239 error = -EISDIR; 229 error = -EISDIR;
240 if (S_ISDIR(inode->i_mode)) 230 if (S_ISDIR(inode->i_mode))
241 goto dput_and_out; 231 goto dput_and_out;
242 232
243 error = -EINVAL; 233 error = -EINVAL;
244 if (!S_ISREG(inode->i_mode)) 234 if (!S_ISREG(inode->i_mode))
245 goto dput_and_out; 235 goto dput_and_out;
246 236
247 error = vfs_permission(&nd, MAY_WRITE) !! 237 error = permission(inode,MAY_WRITE,&nd);
248 if (error) 238 if (error)
249 goto dput_and_out; 239 goto dput_and_out;
250 240
251 error = -EROFS; 241 error = -EROFS;
252 if (IS_RDONLY(inode)) 242 if (IS_RDONLY(inode))
253 goto dput_and_out; 243 goto dput_and_out;
254 244
255 error = -EPERM; 245 error = -EPERM;
256 if (IS_IMMUTABLE(inode) || IS_APPEND(i 246 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
257 goto dput_and_out; 247 goto dput_and_out;
258 248
259 error = get_write_access(inode); <<
260 if (error) <<
261 goto dput_and_out; <<
262 <<
263 /* 249 /*
264 * Make sure that there are no leases. !! 250 * Make sure that there are no leases.
265 * against the truncate racing with a <<
266 */ 251 */
267 error = break_lease(inode, FMODE_WRITE 252 error = break_lease(inode, FMODE_WRITE);
268 if (error) 253 if (error)
269 goto put_write_and_out; !! 254 goto dput_and_out;
>> 255
>> 256 error = get_write_access(inode);
>> 257 if (error)
>> 258 goto dput_and_out;
270 259
271 error = locks_verify_truncate(inode, N 260 error = locks_verify_truncate(inode, NULL, length);
272 if (!error) { 261 if (!error) {
273 DQUOT_INIT(inode); 262 DQUOT_INIT(inode);
274 error = do_truncate(nd.path.de !! 263 error = do_truncate(nd.dentry, length);
275 } 264 }
276 <<
277 put_write_and_out: <<
278 put_write_access(inode); 265 put_write_access(inode);
>> 266
279 dput_and_out: 267 dput_and_out:
280 path_put(&nd.path); !! 268 path_release(&nd);
281 out: 269 out:
282 return error; 270 return error;
283 } 271 }
284 272
285 asmlinkage long sys_truncate(const char __user 273 asmlinkage long sys_truncate(const char __user * path, unsigned long length)
286 { 274 {
287 /* on 32-bit boxen it will cut the ran 275 /* on 32-bit boxen it will cut the range 2^31--2^32-1 off */
288 return do_sys_truncate(path, (long)len 276 return do_sys_truncate(path, (long)length);
289 } 277 }
290 278
291 static long do_sys_ftruncate(unsigned int fd, !! 279 static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
292 { 280 {
293 struct inode * inode; 281 struct inode * inode;
294 struct dentry *dentry; 282 struct dentry *dentry;
295 struct file * file; 283 struct file * file;
296 int error; 284 int error;
297 285
298 error = -EINVAL; 286 error = -EINVAL;
299 if (length < 0) 287 if (length < 0)
300 goto out; 288 goto out;
301 error = -EBADF; 289 error = -EBADF;
302 file = fget(fd); 290 file = fget(fd);
303 if (!file) 291 if (!file)
304 goto out; 292 goto out;
305 293
306 /* explicitly opened as large or we ar 294 /* explicitly opened as large or we are on 64-bit box */
307 if (file->f_flags & O_LARGEFILE) 295 if (file->f_flags & O_LARGEFILE)
308 small = 0; 296 small = 0;
309 297
310 dentry = file->f_path.dentry; !! 298 dentry = file->f_dentry;
311 inode = dentry->d_inode; 299 inode = dentry->d_inode;
312 error = -EINVAL; 300 error = -EINVAL;
313 if (!S_ISREG(inode->i_mode) || !(file- 301 if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
314 goto out_putf; 302 goto out_putf;
315 303
316 error = -EINVAL; 304 error = -EINVAL;
317 /* Cannot ftruncate over 2^31 bytes wi 305 /* Cannot ftruncate over 2^31 bytes without large file support */
318 if (small && length > MAX_NON_LFS) 306 if (small && length > MAX_NON_LFS)
319 goto out_putf; 307 goto out_putf;
320 308
321 error = -EPERM; 309 error = -EPERM;
322 if (IS_APPEND(inode)) 310 if (IS_APPEND(inode))
323 goto out_putf; 311 goto out_putf;
324 312
325 error = locks_verify_truncate(inode, f 313 error = locks_verify_truncate(inode, file, length);
326 if (!error) 314 if (!error)
327 error = do_truncate(dentry, le !! 315 error = do_truncate(dentry, length);
328 out_putf: 316 out_putf:
329 fput(file); 317 fput(file);
330 out: 318 out:
331 return error; 319 return error;
332 } 320 }
333 321
334 asmlinkage long sys_ftruncate(unsigned int fd, 322 asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
335 { 323 {
336 long ret = do_sys_ftruncate(fd, length !! 324 return do_sys_ftruncate(fd, length, 1);
337 /* avoid REGPARM breakage on x86: */ <<
338 asmlinkage_protect(2, ret, fd, length) <<
339 return ret; <<
340 } 325 }
341 326
342 /* LFS versions of truncate are only needed on 327 /* LFS versions of truncate are only needed on 32 bit machines */
343 #if BITS_PER_LONG == 32 328 #if BITS_PER_LONG == 32
344 asmlinkage long sys_truncate64(const char __us 329 asmlinkage long sys_truncate64(const char __user * path, loff_t length)
345 { 330 {
346 return do_sys_truncate(path, length); 331 return do_sys_truncate(path, length);
347 } 332 }
348 333
349 asmlinkage long sys_ftruncate64(unsigned int f 334 asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
350 { 335 {
351 long ret = do_sys_ftruncate(fd, length !! 336 return do_sys_ftruncate(fd, length, 0);
352 /* avoid REGPARM breakage on x86: */ <<
353 asmlinkage_protect(2, ret, fd, length) <<
354 return ret; <<
355 } 337 }
356 #endif 338 #endif
357 339
358 asmlinkage long sys_fallocate(int fd, int mode !! 340 #ifdef __ARCH_WANT_SYS_UTIME
>> 341
>> 342 /*
>> 343 * sys_utime() can be implemented in user-level using sys_utimes().
>> 344 * Is this for backwards compatibility? If so, why not move it
>> 345 * into the appropriate arch directory (for those architectures that
>> 346 * need it).
>> 347 */
>> 348
>> 349 /* If times==NULL, set access and modification to current time,
>> 350 * must be owner or have write permission.
>> 351 * Else, update from *times, must be owner or super user.
>> 352 */
>> 353 asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
359 { 354 {
360 struct file *file; !! 355 int error;
361 struct inode *inode; !! 356 struct nameidata nd;
362 long ret = -EINVAL; !! 357 struct inode * inode;
>> 358 struct iattr newattrs;
363 359
364 if (offset < 0 || len <= 0) !! 360 error = user_path_walk(filename, &nd);
>> 361 if (error)
365 goto out; 362 goto out;
>> 363 inode = nd.dentry->d_inode;
366 364
367 /* Return error if mode is not support !! 365 error = -EROFS;
368 ret = -EOPNOTSUPP; !! 366 if (IS_RDONLY(inode))
369 if (mode && !(mode & FALLOC_FL_KEEP_SI !! 367 goto dput_and_out;
370 goto out; <<
371 368
372 ret = -EBADF; !! 369 /* Don't worry, the checks are done in inode_change_ok() */
373 file = fget(fd); !! 370 newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
374 if (!file) !! 371 if (times) {
375 goto out; !! 372 error = -EPERM;
376 if (!(file->f_mode & FMODE_WRITE)) !! 373 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
377 goto out_fput; !! 374 goto dput_and_out;
378 /* !! 375
379 * Revalidate the write permissions, i !! 376 error = get_user(newattrs.ia_atime.tv_sec, ×->actime);
380 * changed since the files were opened !! 377 newattrs.ia_atime.tv_nsec = 0;
381 */ !! 378 if (!error)
382 ret = security_file_permission(file, M !! 379 error = get_user(newattrs.ia_mtime.tv_sec, ×->modtime);
383 if (ret) !! 380 newattrs.ia_mtime.tv_nsec = 0;
384 goto out_fput; !! 381 if (error)
>> 382 goto dput_and_out;
385 383
386 inode = file->f_path.dentry->d_inode; !! 384 newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
>> 385 } else {
>> 386 error = -EACCES;
>> 387 if (IS_IMMUTABLE(inode))
>> 388 goto dput_and_out;
>> 389
>> 390 if (current->fsuid != inode->i_uid &&
>> 391 (error = permission(inode,MAY_WRITE,&nd)) != 0)
>> 392 goto dput_and_out;
>> 393 }
>> 394 down(&inode->i_sem);
>> 395 error = notify_change(nd.dentry, &newattrs);
>> 396 up(&inode->i_sem);
>> 397 dput_and_out:
>> 398 path_release(&nd);
>> 399 out:
>> 400 return error;
>> 401 }
387 402
388 ret = -ESPIPE; !! 403 #endif
389 if (S_ISFIFO(inode->i_mode)) <<
390 goto out_fput; <<
391 404
392 ret = -ENODEV; !! 405 /* If times==NULL, set access and modification to current time,
393 /* !! 406 * must be owner or have write permission.
394 * Let individual file system decide i !! 407 * Else, update from *times, must be owner or super user.
395 * for directories or not. !! 408 */
396 */ !! 409 long do_utimes(char __user * filename, struct timeval * times)
397 if (!S_ISREG(inode->i_mode) && !S_ISDI !! 410 {
398 goto out_fput; !! 411 int error;
>> 412 struct nameidata nd;
>> 413 struct inode * inode;
>> 414 struct iattr newattrs;
399 415
400 ret = -EFBIG; !! 416 error = user_path_walk(filename, &nd);
401 /* Check for wrap through zero too */ <<
402 if (((offset + len) > inode->i_sb->s_m <<
403 goto out_fput; <<
404 417
405 if (inode->i_op && inode->i_op->falloc !! 418 if (error)
406 ret = inode->i_op->fallocate(i !! 419 goto out;
407 else !! 420 inode = nd.dentry->d_inode;
408 ret = -EOPNOTSUPP; <<
409 421
410 out_fput: !! 422 error = -EROFS;
411 fput(file); !! 423 if (IS_RDONLY(inode))
>> 424 goto dput_and_out;
>> 425
>> 426 /* Don't worry, the checks are done in inode_change_ok() */
>> 427 newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
>> 428 if (times) {
>> 429 error = -EPERM;
>> 430 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
>> 431 goto dput_and_out;
>> 432
>> 433 newattrs.ia_atime.tv_sec = times[0].tv_sec;
>> 434 newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000;
>> 435 newattrs.ia_mtime.tv_sec = times[1].tv_sec;
>> 436 newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000;
>> 437 newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
>> 438 } else {
>> 439 error = -EACCES;
>> 440 if (IS_IMMUTABLE(inode))
>> 441 goto dput_and_out;
>> 442
>> 443 if (current->fsuid != inode->i_uid &&
>> 444 (error = permission(inode,MAY_WRITE,&nd)) != 0)
>> 445 goto dput_and_out;
>> 446 }
>> 447 down(&inode->i_sem);
>> 448 error = notify_change(nd.dentry, &newattrs);
>> 449 up(&inode->i_sem);
>> 450 dput_and_out:
>> 451 path_release(&nd);
412 out: 452 out:
413 return ret; !! 453 return error;
>> 454 }
>> 455
>> 456 asmlinkage long sys_utimes(char __user * filename, struct timeval __user * utimes)
>> 457 {
>> 458 struct timeval times[2];
>> 459
>> 460 if (utimes && copy_from_user(×, utimes, sizeof(times)))
>> 461 return -EFAULT;
>> 462 return do_utimes(filename, utimes ? times : NULL);
414 } 463 }
415 464
>> 465
416 /* 466 /*
417 * access() needs to use the real uid/gid, not 467 * access() needs to use the real uid/gid, not the effective uid/gid.
418 * We do this by temporarily clearing all FS-r 468 * We do this by temporarily clearing all FS-related capabilities and
419 * switching the fsuid/fsgid around to the rea 469 * switching the fsuid/fsgid around to the real ones.
420 */ 470 */
421 asmlinkage long sys_faccessat(int dfd, const c !! 471 asmlinkage long sys_access(const char __user * filename, int mode)
422 { 472 {
423 struct nameidata nd; 473 struct nameidata nd;
424 int old_fsuid, old_fsgid; 474 int old_fsuid, old_fsgid;
425 kernel_cap_t old_cap; 475 kernel_cap_t old_cap;
426 int res; 476 int res;
427 477
428 if (mode & ~S_IRWXO) /* where's F_O 478 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
429 return -EINVAL; 479 return -EINVAL;
430 480
431 old_fsuid = current->fsuid; 481 old_fsuid = current->fsuid;
432 old_fsgid = current->fsgid; 482 old_fsgid = current->fsgid;
433 old_cap = current->cap_effective; 483 old_cap = current->cap_effective;
434 484
435 current->fsuid = current->uid; 485 current->fsuid = current->uid;
436 current->fsgid = current->gid; 486 current->fsgid = current->gid;
437 487
438 /* 488 /*
439 * Clear the capabilities if we switch 489 * Clear the capabilities if we switch to a non-root user
440 * 490 *
441 * FIXME: There is a race here against 491 * FIXME: There is a race here against sys_capset. The
442 * capabilities can change yet we will 492 * capabilities can change yet we will restore the old
443 * value below. We should hold task_c 493 * value below. We should hold task_capabilities_lock,
444 * but we cannot because user_path_wal 494 * but we cannot because user_path_walk can sleep.
445 */ 495 */
446 if (current->uid) 496 if (current->uid)
447 cap_clear(current->cap_effecti 497 cap_clear(current->cap_effective);
448 else 498 else
449 current->cap_effective = curre 499 current->cap_effective = current->cap_permitted;
450 500
451 res = __user_walk_fd(dfd, filename, LO !! 501 res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
452 if (res) !! 502 if (!res) {
453 goto out; !! 503 res = permission(nd.dentry->d_inode, mode, &nd);
454 !! 504 /* SuS v2 requires we report a read only fs too */
455 res = vfs_permission(&nd, mode); !! 505 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
456 /* SuS v2 requires we report a read on !! 506 && !special_file(nd.dentry->d_inode->i_mode))
457 if(res || !(mode & S_IWOTH) || !! 507 res = -EROFS;
458 special_file(nd.path.dentry->d_inod !! 508 path_release(&nd);
459 goto out_path_release; !! 509 }
460 <<
461 if(IS_RDONLY(nd.path.dentry->d_inode)) <<
462 res = -EROFS; <<
463 510
464 out_path_release: <<
465 path_put(&nd.path); <<
466 out: <<
467 current->fsuid = old_fsuid; 511 current->fsuid = old_fsuid;
468 current->fsgid = old_fsgid; 512 current->fsgid = old_fsgid;
469 current->cap_effective = old_cap; 513 current->cap_effective = old_cap;
470 514
471 return res; 515 return res;
472 } 516 }
473 517
474 asmlinkage long sys_access(const char __user * <<
475 { <<
476 return sys_faccessat(AT_FDCWD, filenam <<
477 } <<
478 <<
479 asmlinkage long sys_chdir(const char __user * 518 asmlinkage long sys_chdir(const char __user * filename)
480 { 519 {
481 struct nameidata nd; 520 struct nameidata nd;
482 int error; 521 int error;
483 522
484 error = __user_walk(filename, !! 523 error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
485 LOOKUP_FOLLOW|LOOK <<
486 if (error) 524 if (error)
487 goto out; 525 goto out;
488 526
489 error = vfs_permission(&nd, MAY_EXEC); !! 527 error = permission(nd.dentry->d_inode,MAY_EXEC,&nd);
490 if (error) 528 if (error)
491 goto dput_and_out; 529 goto dput_and_out;
492 530
493 set_fs_pwd(current->fs, &nd.path); !! 531 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
494 532
495 dput_and_out: 533 dput_and_out:
496 path_put(&nd.path); !! 534 path_release(&nd);
497 out: 535 out:
498 return error; 536 return error;
499 } 537 }
500 538
501 asmlinkage long sys_fchdir(unsigned int fd) 539 asmlinkage long sys_fchdir(unsigned int fd)
502 { 540 {
503 struct file *file; 541 struct file *file;
>> 542 struct dentry *dentry;
504 struct inode *inode; 543 struct inode *inode;
>> 544 struct vfsmount *mnt;
505 int error; 545 int error;
506 546
507 error = -EBADF; 547 error = -EBADF;
508 file = fget(fd); 548 file = fget(fd);
509 if (!file) 549 if (!file)
510 goto out; 550 goto out;
511 551
512 inode = file->f_path.dentry->d_inode; !! 552 dentry = file->f_dentry;
>> 553 mnt = file->f_vfsmnt;
>> 554 inode = dentry->d_inode;
513 555
514 error = -ENOTDIR; 556 error = -ENOTDIR;
515 if (!S_ISDIR(inode->i_mode)) 557 if (!S_ISDIR(inode->i_mode))
516 goto out_putf; 558 goto out_putf;
517 559
518 error = file_permission(file, MAY_EXEC !! 560 error = permission(inode, MAY_EXEC, NULL);
519 if (!error) 561 if (!error)
520 set_fs_pwd(current->fs, &file- !! 562 set_fs_pwd(current->fs, mnt, dentry);
521 out_putf: 563 out_putf:
522 fput(file); 564 fput(file);
523 out: 565 out:
524 return error; 566 return error;
525 } 567 }
526 568
527 asmlinkage long sys_chroot(const char __user * 569 asmlinkage long sys_chroot(const char __user * filename)
528 { 570 {
529 struct nameidata nd; 571 struct nameidata nd;
530 int error; 572 int error;
531 573
532 error = __user_walk(filename, LOOKUP_F 574 error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
533 if (error) 575 if (error)
534 goto out; 576 goto out;
535 577
536 error = vfs_permission(&nd, MAY_EXEC); !! 578 error = permission(nd.dentry->d_inode,MAY_EXEC,&nd);
537 if (error) 579 if (error)
538 goto dput_and_out; 580 goto dput_and_out;
539 581
540 error = -EPERM; 582 error = -EPERM;
541 if (!capable(CAP_SYS_CHROOT)) 583 if (!capable(CAP_SYS_CHROOT))
542 goto dput_and_out; 584 goto dput_and_out;
543 585
544 set_fs_root(current->fs, &nd.path); !! 586 set_fs_root(current->fs, nd.mnt, nd.dentry);
545 set_fs_altroot(); 587 set_fs_altroot();
546 error = 0; 588 error = 0;
547 dput_and_out: 589 dput_and_out:
548 path_put(&nd.path); !! 590 path_release(&nd);
549 out: 591 out:
550 return error; 592 return error;
551 } 593 }
552 594
553 asmlinkage long sys_fchmod(unsigned int fd, mo 595 asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
554 { 596 {
555 struct inode * inode; 597 struct inode * inode;
556 struct dentry * dentry; 598 struct dentry * dentry;
557 struct file * file; 599 struct file * file;
558 int err = -EBADF; 600 int err = -EBADF;
559 struct iattr newattrs; 601 struct iattr newattrs;
560 602
561 file = fget(fd); 603 file = fget(fd);
562 if (!file) 604 if (!file)
563 goto out; 605 goto out;
564 606
565 dentry = file->f_path.dentry; !! 607 dentry = file->f_dentry;
566 inode = dentry->d_inode; 608 inode = dentry->d_inode;
567 609
568 audit_inode(NULL, dentry); <<
569 <<
570 err = -EROFS; 610 err = -EROFS;
571 if (IS_RDONLY(inode)) 611 if (IS_RDONLY(inode))
572 goto out_putf; 612 goto out_putf;
573 err = -EPERM; 613 err = -EPERM;
574 if (IS_IMMUTABLE(inode) || IS_APPEND(i 614 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
575 goto out_putf; 615 goto out_putf;
576 mutex_lock(&inode->i_mutex); !! 616 down(&inode->i_sem);
577 if (mode == (mode_t) -1) 617 if (mode == (mode_t) -1)
578 mode = inode->i_mode; 618 mode = inode->i_mode;
579 newattrs.ia_mode = (mode & S_IALLUGO) 619 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
580 newattrs.ia_valid = ATTR_MODE | ATTR_C 620 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
581 err = notify_change(dentry, &newattrs) 621 err = notify_change(dentry, &newattrs);
582 mutex_unlock(&inode->i_mutex); !! 622 up(&inode->i_sem);
583 623
584 out_putf: 624 out_putf:
585 fput(file); 625 fput(file);
586 out: 626 out:
587 return err; 627 return err;
588 } 628 }
589 629
590 asmlinkage long sys_fchmodat(int dfd, const ch !! 630 asmlinkage long sys_chmod(const char __user * filename, mode_t mode)
591 mode_t mode) <<
592 { 631 {
593 struct nameidata nd; 632 struct nameidata nd;
594 struct inode * inode; 633 struct inode * inode;
595 int error; 634 int error;
596 struct iattr newattrs; 635 struct iattr newattrs;
597 636
598 error = __user_walk_fd(dfd, filename, !! 637 error = user_path_walk(filename, &nd);
599 if (error) 638 if (error)
600 goto out; 639 goto out;
601 inode = nd.path.dentry->d_inode; !! 640 inode = nd.dentry->d_inode;
602 641
603 error = -EROFS; 642 error = -EROFS;
604 if (IS_RDONLY(inode)) 643 if (IS_RDONLY(inode))
605 goto dput_and_out; 644 goto dput_and_out;
606 645
607 error = -EPERM; 646 error = -EPERM;
608 if (IS_IMMUTABLE(inode) || IS_APPEND(i 647 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
609 goto dput_and_out; 648 goto dput_and_out;
610 649
611 mutex_lock(&inode->i_mutex); !! 650 down(&inode->i_sem);
612 if (mode == (mode_t) -1) 651 if (mode == (mode_t) -1)
613 mode = inode->i_mode; 652 mode = inode->i_mode;
614 newattrs.ia_mode = (mode & S_IALLUGO) 653 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
615 newattrs.ia_valid = ATTR_MODE | ATTR_C 654 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
616 error = notify_change(nd.path.dentry, !! 655 error = notify_change(nd.dentry, &newattrs);
617 mutex_unlock(&inode->i_mutex); !! 656 up(&inode->i_sem);
618 657
619 dput_and_out: 658 dput_and_out:
620 path_put(&nd.path); !! 659 path_release(&nd);
621 out: 660 out:
622 return error; 661 return error;
623 } 662 }
624 663
625 asmlinkage long sys_chmod(const char __user *f <<
626 { <<
627 return sys_fchmodat(AT_FDCWD, filename <<
628 } <<
629 <<
630 static int chown_common(struct dentry * dentry 664 static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
631 { 665 {
632 struct inode * inode; 666 struct inode * inode;
633 int error; 667 int error;
634 struct iattr newattrs; 668 struct iattr newattrs;
635 669
636 error = -ENOENT; 670 error = -ENOENT;
637 if (!(inode = dentry->d_inode)) { 671 if (!(inode = dentry->d_inode)) {
638 printk(KERN_ERR "chown_common: 672 printk(KERN_ERR "chown_common: NULL inode\n");
639 goto out; 673 goto out;
640 } 674 }
641 error = -EROFS; 675 error = -EROFS;
642 if (IS_RDONLY(inode)) 676 if (IS_RDONLY(inode))
643 goto out; 677 goto out;
644 error = -EPERM; 678 error = -EPERM;
645 if (IS_IMMUTABLE(inode) || IS_APPEND(i 679 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
646 goto out; 680 goto out;
647 newattrs.ia_valid = ATTR_CTIME; 681 newattrs.ia_valid = ATTR_CTIME;
648 if (user != (uid_t) -1) { 682 if (user != (uid_t) -1) {
649 newattrs.ia_valid |= ATTR_UID; 683 newattrs.ia_valid |= ATTR_UID;
650 newattrs.ia_uid = user; 684 newattrs.ia_uid = user;
651 } 685 }
652 if (group != (gid_t) -1) { 686 if (group != (gid_t) -1) {
653 newattrs.ia_valid |= ATTR_GID; 687 newattrs.ia_valid |= ATTR_GID;
654 newattrs.ia_gid = group; 688 newattrs.ia_gid = group;
655 } 689 }
656 if (!S_ISDIR(inode->i_mode)) 690 if (!S_ISDIR(inode->i_mode))
657 newattrs.ia_valid |= !! 691 newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
658 ATTR_KILL_SUID | ATTR_ !! 692 down(&inode->i_sem);
659 mutex_lock(&inode->i_mutex); <<
660 error = notify_change(dentry, &newattr 693 error = notify_change(dentry, &newattrs);
661 mutex_unlock(&inode->i_mutex); !! 694 up(&inode->i_sem);
662 out: 695 out:
663 return error; 696 return error;
664 } 697 }
665 698
666 asmlinkage long sys_chown(const char __user * 699 asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group)
667 { 700 {
668 struct nameidata nd; 701 struct nameidata nd;
669 int error; 702 int error;
670 703
671 error = user_path_walk(filename, &nd); 704 error = user_path_walk(filename, &nd);
672 if (error) !! 705 if (!error) {
673 goto out; !! 706 error = chown_common(nd.dentry, user, group);
674 error = chown_common(nd.path.dentry, u !! 707 path_release(&nd);
675 path_put(&nd.path); !! 708 }
676 out: <<
677 return error; <<
678 } <<
679 <<
680 asmlinkage long sys_fchownat(int dfd, const ch <<
681 gid_t group, int <<
682 { <<
683 struct nameidata nd; <<
684 int error = -EINVAL; <<
685 int follow; <<
686 <<
687 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0 <<
688 goto out; <<
689 <<
690 follow = (flag & AT_SYMLINK_NOFOLLOW) <<
691 error = __user_walk_fd(dfd, filename, <<
692 if (error) <<
693 goto out; <<
694 error = chown_common(nd.path.dentry, u <<
695 path_put(&nd.path); <<
696 out: <<
697 return error; 709 return error;
698 } 710 }
699 711
700 asmlinkage long sys_lchown(const char __user * 712 asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group)
701 { 713 {
702 struct nameidata nd; 714 struct nameidata nd;
703 int error; 715 int error;
704 716
705 error = user_path_walk_link(filename, 717 error = user_path_walk_link(filename, &nd);
706 if (error) !! 718 if (!error) {
707 goto out; !! 719 error = chown_common(nd.dentry, user, group);
708 error = chown_common(nd.path.dentry, u !! 720 path_release(&nd);
709 path_put(&nd.path); !! 721 }
710 out: <<
711 return error; 722 return error;
712 } 723 }
713 724
714 725
715 asmlinkage long sys_fchown(unsigned int fd, ui 726 asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
716 { 727 {
717 struct file * file; 728 struct file * file;
718 int error = -EBADF; 729 int error = -EBADF;
719 struct dentry * dentry; <<
720 730
721 file = fget(fd); 731 file = fget(fd);
722 if (!file) !! 732 if (file) {
723 goto out; !! 733 error = chown_common(file->f_dentry, user, group);
724 !! 734 fput(file);
725 dentry = file->f_path.dentry; !! 735 }
726 audit_inode(NULL, dentry); <<
727 error = chown_common(dentry, user, gro <<
728 fput(file); <<
729 out: <<
730 return error; 736 return error;
731 } 737 }
732 738
733 static struct file *__dentry_open(struct dentr !! 739 /*
734 int fl !! 740 * Note that while the flag value (low two bits) for sys_open means:
735 int (* !! 741 * 00 - read-only
>> 742 * 01 - write-only
>> 743 * 10 - read-write
>> 744 * 11 - special
>> 745 * it is changed into
>> 746 * 00 - no permissions needed
>> 747 * 01 - read-permission
>> 748 * 10 - write-permission
>> 749 * 11 - read-write
>> 750 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
>> 751 * used by symlinks.
>> 752 */
>> 753 struct file *filp_open(const char * filename, int flags, int mode)
>> 754 {
>> 755 int namei_flags, error;
>> 756 struct nameidata nd;
>> 757
>> 758 namei_flags = flags;
>> 759 if ((namei_flags+1) & O_ACCMODE)
>> 760 namei_flags++;
>> 761 if (namei_flags & O_TRUNC)
>> 762 namei_flags |= 2;
>> 763
>> 764 error = open_namei(filename, namei_flags, mode, &nd);
>> 765 if (!error)
>> 766 return dentry_open(nd.dentry, nd.mnt, flags);
>> 767
>> 768 return ERR_PTR(error);
>> 769 }
>> 770
>> 771 EXPORT_SYMBOL(filp_open);
>> 772
>> 773 struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
736 { 774 {
>> 775 struct file * f;
737 struct inode *inode; 776 struct inode *inode;
738 int error; 777 int error;
739 778
>> 779 error = -ENFILE;
>> 780 f = get_empty_filp();
>> 781 if (!f)
>> 782 goto cleanup_dentry;
740 f->f_flags = flags; 783 f->f_flags = flags;
741 f->f_mode = ((flags+1) & O_ACCMODE) | !! 784 f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
742 FMODE_PREAD | <<
743 inode = dentry->d_inode; 785 inode = dentry->d_inode;
744 if (f->f_mode & FMODE_WRITE) { 786 if (f->f_mode & FMODE_WRITE) {
745 error = get_write_access(inode 787 error = get_write_access(inode);
746 if (error) 788 if (error)
747 goto cleanup_file; 789 goto cleanup_file;
748 } 790 }
749 791
750 f->f_mapping = inode->i_mapping; 792 f->f_mapping = inode->i_mapping;
751 f->f_path.dentry = dentry; !! 793 f->f_dentry = dentry;
752 f->f_path.mnt = mnt; !! 794 f->f_vfsmnt = mnt;
753 f->f_pos = 0; 795 f->f_pos = 0;
754 f->f_op = fops_get(inode->i_fop); 796 f->f_op = fops_get(inode->i_fop);
755 file_move(f, &inode->i_sb->s_files); 797 file_move(f, &inode->i_sb->s_files);
756 798
757 error = security_dentry_open(f); !! 799 if (f->f_op && f->f_op->open) {
758 if (error) !! 800 error = f->f_op->open(inode,f);
759 goto cleanup_all; <<
760 <<
761 if (!open && f->f_op) <<
762 open = f->f_op->open; <<
763 if (open) { <<
764 error = open(inode, f); <<
765 if (error) 801 if (error)
766 goto cleanup_all; 802 goto cleanup_all;
767 } 803 }
768 <<
769 f->f_flags &= ~(O_CREAT | O_EXCL | O_N 804 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
770 805
771 file_ra_state_init(&f->f_ra, f->f_mapp 806 file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
772 807
773 /* NB: we're sure to have correct a_op 808 /* NB: we're sure to have correct a_ops only after f_op->open */
774 if (f->f_flags & O_DIRECT) { 809 if (f->f_flags & O_DIRECT) {
775 if (!f->f_mapping->a_ops || !! 810 if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO) {
776 ((!f->f_mapping->a_ops->di <<
777 (!f->f_mapping->a_ops->get <<
778 fput(f); 811 fput(f);
779 f = ERR_PTR(-EINVAL); 812 f = ERR_PTR(-EINVAL);
780 } 813 }
781 } 814 }
782 815
783 return f; 816 return f;
784 817
785 cleanup_all: 818 cleanup_all:
786 fops_put(f->f_op); 819 fops_put(f->f_op);
787 if (f->f_mode & FMODE_WRITE) 820 if (f->f_mode & FMODE_WRITE)
788 put_write_access(inode); 821 put_write_access(inode);
789 file_kill(f); 822 file_kill(f);
790 f->f_path.dentry = NULL; !! 823 f->f_dentry = NULL;
791 f->f_path.mnt = NULL; !! 824 f->f_vfsmnt = NULL;
792 cleanup_file: 825 cleanup_file:
793 put_filp(f); 826 put_filp(f);
>> 827 cleanup_dentry:
794 dput(dentry); 828 dput(dentry);
795 mntput(mnt); 829 mntput(mnt);
796 return ERR_PTR(error); 830 return ERR_PTR(error);
797 } 831 }
798 832
799 /* <<
800 * Note that while the flag value (low two bit <<
801 * 00 - read-only <<
802 * 01 - write-only <<
803 * 10 - read-write <<
804 * 11 - special <<
805 * it is changed into <<
806 * 00 - no permissions needed <<
807 * 01 - read-permission <<
808 * 10 - write-permission <<
809 * 11 - read-write <<
810 * for the internal routines (ie open_namei()/ <<
811 * used by symlinks. <<
812 */ <<
813 static struct file *do_filp_open(int dfd, cons <<
814 int mode) <<
815 { <<
816 int namei_flags, error; <<
817 struct nameidata nd; <<
818 <<
819 namei_flags = flags; <<
820 if ((namei_flags+1) & O_ACCMODE) <<
821 namei_flags++; <<
822 <<
823 error = open_namei(dfd, filename, name <<
824 if (!error) <<
825 return nameidata_to_filp(&nd, <<
826 <<
827 return ERR_PTR(error); <<
828 } <<
829 <<
830 struct file *filp_open(const char *filename, i <<
831 { <<
832 return do_filp_open(AT_FDCWD, filename <<
833 } <<
834 EXPORT_SYMBOL(filp_open); <<
835 <<
836 /** <<
837 * lookup_instantiate_filp - instantiates the <<
838 * @nd: pointer to nameidata <<
839 * @dentry: pointer to dentry <<
840 * @open: open callback <<
841 * <<
842 * Helper for filesystems that want to use loo <<
843 * a fully instantiated struct file to the cal <<
844 * This function is meant to be called from wi <<
845 * lookup method. <<
846 * Beware of calling it for non-regular files! <<
847 * (e.g. in fifo_open), leaving you with paren <<
848 * leading to a deadlock, as nobody can open t <<
849 * another process to open fifo will block on <<
850 * Note that in case of error, nd->intent.open <<
851 * path information remains valid. <<
852 * If the open callback is set to NULL, then t <<
853 * filesystem callback is substituted. <<
854 */ <<
855 struct file *lookup_instantiate_filp(struct na <<
856 int (*open)(struct inode *, st <<
857 { <<
858 if (IS_ERR(nd->intent.open.file)) <<
859 goto out; <<
860 if (IS_ERR(dentry)) <<
861 goto out_err; <<
862 nd->intent.open.file = __dentry_open(d <<
863 n <<
864 n <<
865 o <<
866 out: <<
867 return nd->intent.open.file; <<
868 out_err: <<
869 release_open_intent(nd); <<
870 nd->intent.open.file = (struct file *) <<
871 goto out; <<
872 } <<
873 EXPORT_SYMBOL_GPL(lookup_instantiate_filp); <<
874 <<
875 /** <<
876 * nameidata_to_filp - convert a nameidata to <<
877 * @nd: pointer to nameidata <<
878 * @flags: open flags <<
879 * <<
880 * Note that this function destroys the origin <<
881 */ <<
882 struct file *nameidata_to_filp(struct nameidat <<
883 { <<
884 struct file *filp; <<
885 <<
886 /* Pick up the filp from the open inte <<
887 filp = nd->intent.open.file; <<
888 /* Has the filesystem initialised the <<
889 if (filp->f_path.dentry == NULL) <<
890 filp = __dentry_open(nd->path. <<
891 NULL); <<
892 else <<
893 path_put(&nd->path); <<
894 return filp; <<
895 } <<
896 <<
897 /* <<
898 * dentry_open() will have done dput(dentry) a <<
899 * error. <<
900 */ <<
901 struct file *dentry_open(struct dentry *dentry <<
902 { <<
903 int error; <<
904 struct file *f; <<
905 <<
906 /* <<
907 * We must always pass in a valid moun <<
908 * callers got away with not passing i <<
909 * the earliest possible point now to <<
910 * filesystem stack. <<
911 */ <<
912 if (!mnt) { <<
913 printk(KERN_WARNING "%s called <<
914 dump_stack(); <<
915 return ERR_PTR(-EINVAL); <<
916 } <<
917 <<
918 error = -ENFILE; <<
919 f = get_empty_filp(); <<
920 if (f == NULL) { <<
921 dput(dentry); <<
922 mntput(mnt); <<
923 return ERR_PTR(error); <<
924 } <<
925 <<
926 return __dentry_open(dentry, mnt, flag <<
927 } <<
928 EXPORT_SYMBOL(dentry_open); 833 EXPORT_SYMBOL(dentry_open);
929 834
930 /* 835 /*
931 * Find an empty file descriptor entry, and ma 836 * Find an empty file descriptor entry, and mark it busy.
932 */ 837 */
933 int get_unused_fd_flags(int flags) !! 838 int get_unused_fd(void)
934 { 839 {
935 struct files_struct * files = current- 840 struct files_struct * files = current->files;
936 int fd, error; 841 int fd, error;
937 struct fdtable *fdt; <<
938 842
939 error = -EMFILE; 843 error = -EMFILE;
940 spin_lock(&files->file_lock); 844 spin_lock(&files->file_lock);
941 845
942 repeat: 846 repeat:
943 fdt = files_fdtable(files); !! 847 fd = find_next_zero_bit(files->open_fds->fds_bits,
944 fd = find_next_zero_bit(fdt->open_fds- !! 848 files->max_fdset,
945 files->next_fd 849 files->next_fd);
946 850
947 /* 851 /*
948 * N.B. For clone tasks sharing a file 852 * N.B. For clone tasks sharing a files structure, this test
949 * will limit the total number of file 853 * will limit the total number of files that can be opened.
950 */ 854 */
951 if (fd >= current->signal->rlim[RLIMIT 855 if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
952 goto out; 856 goto out;
953 857
954 /* Do we need to expand the fd array o 858 /* Do we need to expand the fd array or fd set? */
955 error = expand_files(files, fd); 859 error = expand_files(files, fd);
956 if (error < 0) 860 if (error < 0)
957 goto out; 861 goto out;
958 862
959 if (error) { 863 if (error) {
960 /* 864 /*
961 * If we needed to expand the 865 * If we needed to expand the fs array we
962 * might have blocked - try ag 866 * might have blocked - try again.
963 */ 867 */
964 error = -EMFILE; 868 error = -EMFILE;
965 goto repeat; 869 goto repeat;
966 } 870 }
967 871
968 FD_SET(fd, fdt->open_fds); !! 872 FD_SET(fd, files->open_fds);
969 if (flags & O_CLOEXEC) !! 873 FD_CLR(fd, files->close_on_exec);
970 FD_SET(fd, fdt->close_on_exec) <<
971 else <<
972 FD_CLR(fd, fdt->close_on_exec) <<
973 files->next_fd = fd + 1; 874 files->next_fd = fd + 1;
974 #if 1 875 #if 1
975 /* Sanity check */ 876 /* Sanity check */
976 if (fdt->fd[fd] != NULL) { !! 877 if (files->fd[fd] != NULL) {
977 printk(KERN_WARNING "get_unuse 878 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
978 fdt->fd[fd] = NULL; !! 879 files->fd[fd] = NULL;
979 } 880 }
980 #endif 881 #endif
981 error = fd; 882 error = fd;
982 883
983 out: 884 out:
984 spin_unlock(&files->file_lock); 885 spin_unlock(&files->file_lock);
985 return error; 886 return error;
986 } 887 }
987 888
988 int get_unused_fd(void) <<
989 { <<
990 return get_unused_fd_flags(0); <<
991 } <<
992 <<
993 EXPORT_SYMBOL(get_unused_fd); 889 EXPORT_SYMBOL(get_unused_fd);
994 890
995 static void __put_unused_fd(struct files_struc !! 891 static inline void __put_unused_fd(struct files_struct *files, unsigned int fd)
996 { 892 {
997 struct fdtable *fdt = files_fdtable(fi !! 893 __FD_CLR(fd, files->open_fds);
998 __FD_CLR(fd, fdt->open_fds); <<
999 if (fd < files->next_fd) 894 if (fd < files->next_fd)
1000 files->next_fd = fd; 895 files->next_fd = fd;
1001 } 896 }
1002 897
1003 void put_unused_fd(unsigned int fd) !! 898 void fastcall put_unused_fd(unsigned int fd)
1004 { 899 {
1005 struct files_struct *files = current- 900 struct files_struct *files = current->files;
1006 spin_lock(&files->file_lock); 901 spin_lock(&files->file_lock);
1007 __put_unused_fd(files, fd); 902 __put_unused_fd(files, fd);
1008 spin_unlock(&files->file_lock); 903 spin_unlock(&files->file_lock);
1009 } 904 }
1010 905
1011 EXPORT_SYMBOL(put_unused_fd); 906 EXPORT_SYMBOL(put_unused_fd);
1012 907
1013 /* 908 /*
1014 * Install a file pointer in the fd array. !! 909 * Install a file pointer in the fd array.
1015 * 910 *
1016 * The VFS is full of places where we drop th 911 * The VFS is full of places where we drop the files lock between
1017 * setting the open_fds bitmap and installing 912 * setting the open_fds bitmap and installing the file in the file
1018 * array. At any such point, we are vulnerab 913 * array. At any such point, we are vulnerable to a dup2() race
1019 * installing a file in the array before us. 914 * installing a file in the array before us. We need to detect this and
1020 * fput() the struct file we are about to ove 915 * fput() the struct file we are about to overwrite in this case.
1021 * 916 *
1022 * It should never happen - if we allow dup2( 917 * It should never happen - if we allow dup2() do it, _really_ bad things
1023 * will follow. 918 * will follow.
1024 */ 919 */
1025 920
1026 void fd_install(unsigned int fd, struct file !! 921 void fastcall fd_install(unsigned int fd, struct file * file)
1027 { 922 {
1028 struct files_struct *files = current- 923 struct files_struct *files = current->files;
1029 struct fdtable *fdt; <<
1030 spin_lock(&files->file_lock); 924 spin_lock(&files->file_lock);
1031 fdt = files_fdtable(files); !! 925 if (unlikely(files->fd[fd] != NULL))
1032 BUG_ON(fdt->fd[fd] != NULL); !! 926 BUG();
1033 rcu_assign_pointer(fdt->fd[fd], file) !! 927 files->fd[fd] = file;
1034 spin_unlock(&files->file_lock); 928 spin_unlock(&files->file_lock);
1035 } 929 }
1036 930
1037 EXPORT_SYMBOL(fd_install); 931 EXPORT_SYMBOL(fd_install);
1038 932
1039 long do_sys_open(int dfd, const char __user * !! 933 asmlinkage long sys_open(const char __user * filename, int flags, int mode)
1040 { 934 {
1041 char *tmp = getname(filename); !! 935 char * tmp;
1042 int fd = PTR_ERR(tmp); !! 936 int fd, error;
1043 937
>> 938 #if BITS_PER_LONG != 32
>> 939 flags |= O_LARGEFILE;
>> 940 #endif
>> 941 tmp = getname(filename);
>> 942 fd = PTR_ERR(tmp);
1044 if (!IS_ERR(tmp)) { 943 if (!IS_ERR(tmp)) {
1045 fd = get_unused_fd_flags(flag !! 944 fd = get_unused_fd();
1046 if (fd >= 0) { 945 if (fd >= 0) {
1047 struct file *f = do_f !! 946 struct file *f = filp_open(tmp, flags, mode);
1048 if (IS_ERR(f)) { !! 947 error = PTR_ERR(f);
1049 put_unused_fd !! 948 if (IS_ERR(f))
1050 fd = PTR_ERR( !! 949 goto out_error;
1051 } else { !! 950 fd_install(fd, f);
1052 fsnotify_open <<
1053 fd_install(fd <<
1054 } <<
1055 } 951 }
>> 952 out:
1056 putname(tmp); 953 putname(tmp);
1057 } 954 }
1058 return fd; 955 return fd;
1059 } <<
1060 <<
1061 asmlinkage long sys_open(const char __user *f <<
1062 { <<
1063 long ret; <<
1064 <<
1065 if (force_o_largefile()) <<
1066 flags |= O_LARGEFILE; <<
1067 <<
1068 ret = do_sys_open(AT_FDCWD, filename, <<
1069 /* avoid REGPARM breakage on x86: */ <<
1070 asmlinkage_protect(3, ret, filename, <<
1071 return ret; <<
1072 } <<
1073 956
1074 asmlinkage long sys_openat(int dfd, const cha !! 957 out_error:
1075 int mode) !! 958 put_unused_fd(fd);
1076 { !! 959 fd = error;
1077 long ret; !! 960 goto out;
1078 <<
1079 if (force_o_largefile()) <<
1080 flags |= O_LARGEFILE; <<
1081 <<
1082 ret = do_sys_open(dfd, filename, flag <<
1083 /* avoid REGPARM breakage on x86: */ <<
1084 asmlinkage_protect(4, ret, dfd, filen <<
1085 return ret; <<
1086 } 961 }
>> 962 EXPORT_SYMBOL_GPL(sys_open);
1087 963
1088 #ifndef __alpha__ 964 #ifndef __alpha__
1089 965
1090 /* 966 /*
1091 * For backward compatibility? Maybe this sh 967 * For backward compatibility? Maybe this should be moved
1092 * into arch/i386 instead? 968 * into arch/i386 instead?
1093 */ 969 */
1094 asmlinkage long sys_creat(const char __user * 970 asmlinkage long sys_creat(const char __user * pathname, int mode)
1095 { 971 {
1096 return sys_open(pathname, O_CREAT | O 972 return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
1097 } 973 }
1098 974
1099 #endif 975 #endif
1100 976
1101 /* 977 /*
1102 * "id" is the POSIX thread ID. We use the 978 * "id" is the POSIX thread ID. We use the
1103 * files pointer for this.. 979 * files pointer for this..
1104 */ 980 */
1105 int filp_close(struct file *filp, fl_owner_t 981 int filp_close(struct file *filp, fl_owner_t id)
1106 { 982 {
1107 int retval = 0; !! 983 int retval;
>> 984
>> 985 /* Report and clear outstanding errors */
>> 986 retval = filp->f_error;
>> 987 if (retval)
>> 988 filp->f_error = 0;
1108 989
1109 if (!file_count(filp)) { 990 if (!file_count(filp)) {
1110 printk(KERN_ERR "VFS: Close: 991 printk(KERN_ERR "VFS: Close: file count is 0\n");
1111 return 0; !! 992 return retval;
1112 } 993 }
1113 994
1114 if (filp->f_op && filp->f_op->flush) !! 995 if (filp->f_op && filp->f_op->flush) {
1115 retval = filp->f_op->flush(fi !! 996 int err = filp->f_op->flush(filp);
>> 997 if (!retval)
>> 998 retval = err;
>> 999 }
1116 1000
1117 dnotify_flush(filp, id); 1001 dnotify_flush(filp, id);
1118 locks_remove_posix(filp, id); 1002 locks_remove_posix(filp, id);
1119 fput(filp); 1003 fput(filp);
1120 return retval; 1004 return retval;
1121 } 1005 }
1122 1006
1123 EXPORT_SYMBOL(filp_close); 1007 EXPORT_SYMBOL(filp_close);
1124 1008
1125 /* 1009 /*
1126 * Careful here! We test whether the file poi 1010 * Careful here! We test whether the file pointer is NULL before
1127 * releasing the fd. This ensures that one cl 1011 * releasing the fd. This ensures that one clone task can't release
1128 * an fd while another clone is opening it. 1012 * an fd while another clone is opening it.
1129 */ 1013 */
1130 asmlinkage long sys_close(unsigned int fd) 1014 asmlinkage long sys_close(unsigned int fd)
1131 { 1015 {
1132 struct file * filp; 1016 struct file * filp;
1133 struct files_struct *files = current- 1017 struct files_struct *files = current->files;
1134 struct fdtable *fdt; <<
1135 int retval; <<
1136 1018
1137 spin_lock(&files->file_lock); 1019 spin_lock(&files->file_lock);
1138 fdt = files_fdtable(files); !! 1020 if (fd >= files->max_fds)
1139 if (fd >= fdt->max_fds) <<
1140 goto out_unlock; 1021 goto out_unlock;
1141 filp = fdt->fd[fd]; !! 1022 filp = files->fd[fd];
1142 if (!filp) 1023 if (!filp)
1143 goto out_unlock; 1024 goto out_unlock;
1144 rcu_assign_pointer(fdt->fd[fd], NULL) !! 1025 files->fd[fd] = NULL;
1145 FD_CLR(fd, fdt->close_on_exec); !! 1026 FD_CLR(fd, files->close_on_exec);
1146 __put_unused_fd(files, fd); 1027 __put_unused_fd(files, fd);
1147 spin_unlock(&files->file_lock); 1028 spin_unlock(&files->file_lock);
1148 retval = filp_close(filp, files); !! 1029 return filp_close(filp, files);
1149 <<
1150 /* can't restart close syscall becaus <<
1151 if (unlikely(retval == -ERESTARTSYS | <<
1152 retval == -ERESTARTNOINT <<
1153 retval == -ERESTARTNOHAN <<
1154 retval == -ERESTART_REST <<
1155 retval = -EINTR; <<
1156 <<
1157 return retval; <<
1158 1030
1159 out_unlock: 1031 out_unlock:
1160 spin_unlock(&files->file_lock); 1032 spin_unlock(&files->file_lock);
1161 return -EBADF; 1033 return -EBADF;
1162 } 1034 }
1163 1035
1164 EXPORT_SYMBOL(sys_close); 1036 EXPORT_SYMBOL(sys_close);
1165 1037
1166 /* 1038 /*
1167 * This routine simulates a hangup on the tty 1039 * This routine simulates a hangup on the tty, to arrange that users
1168 * are given clean terminals at login time. 1040 * are given clean terminals at login time.
1169 */ 1041 */
1170 asmlinkage long sys_vhangup(void) 1042 asmlinkage long sys_vhangup(void)
1171 { 1043 {
1172 if (capable(CAP_SYS_TTY_CONFIG)) { 1044 if (capable(CAP_SYS_TTY_CONFIG)) {
1173 /* XXX: this needs locking */ <<
1174 tty_vhangup(current->signal-> 1045 tty_vhangup(current->signal->tty);
1175 return 0; 1046 return 0;
1176 } 1047 }
1177 return -EPERM; 1048 return -EPERM;
1178 } 1049 }
1179 1050
1180 /* 1051 /*
1181 * Called when an inode is about to be open. 1052 * Called when an inode is about to be open.
1182 * We use this to disallow opening large file 1053 * We use this to disallow opening large files on 32bit systems if
1183 * the caller didn't specify O_LARGEFILE. On 1054 * the caller didn't specify O_LARGEFILE. On 64bit systems we force
1184 * on this flag in sys_open. 1055 * on this flag in sys_open.
1185 */ 1056 */
1186 int generic_file_open(struct inode * inode, s 1057 int generic_file_open(struct inode * inode, struct file * filp)
1187 { 1058 {
1188 if (!(filp->f_flags & O_LARGEFILE) && 1059 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
1189 return -EOVERFLOW; !! 1060 return -EFBIG;
1190 return 0; 1061 return 0;
1191 } 1062 }
1192 1063
1193 EXPORT_SYMBOL(generic_file_open); 1064 EXPORT_SYMBOL(generic_file_open);
1194 1065
1195 /* 1066 /*
1196 * This is used by subsystems that don't want 1067 * This is used by subsystems that don't want seekable
1197 * file descriptors 1068 * file descriptors
1198 */ 1069 */
1199 int nonseekable_open(struct inode *inode, str 1070 int nonseekable_open(struct inode *inode, struct file *filp)
1200 { 1071 {
1201 filp->f_mode &= ~(FMODE_LSEEK | FMODE 1072 filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
1202 return 0; 1073 return 0;
1203 } 1074 }
1204 1075
1205 EXPORT_SYMBOL(nonseekable_open); 1076 EXPORT_SYMBOL(nonseekable_open);
1206 1077
|
This page was automatically generated by the
LXR engine.
|