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