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