This commit was manufactured by cvs2svn to create tag
[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
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         }
48         return retval;
49 }
50
51 EXPORT_SYMBOL(vfs_statfs);
52
53 static int vfs_statfs_native(struct super_block *sb, struct statfs *buf)
54 {
55         struct kstatfs st;
56         int retval;
57
58         retval = vfs_statfs(sb, &st);
59         if (retval)
60                 return retval;
61
62         if (sizeof(*buf) == sizeof(st))
63                 memcpy(buf, &st, sizeof(st));
64         else {
65                 if (sizeof buf->f_blocks == 4) {
66                         if ((st.f_blocks | st.f_bfree | st.f_bavail) &
67                             0xffffffff00000000ULL)
68                                 return -EOVERFLOW;
69                         /*
70                          * f_files and f_ffree may be -1; it's okay to stuff
71                          * that into 32 bits
72                          */
73                         if (st.f_files != -1 &&
74                             (st.f_files & 0xffffffff00000000ULL))
75                                 return -EOVERFLOW;
76                         if (st.f_ffree != -1 &&
77                             (st.f_ffree & 0xffffffff00000000ULL))
78                                 return -EOVERFLOW;
79                 }
80
81                 buf->f_type = st.f_type;
82                 buf->f_bsize = st.f_bsize;
83                 buf->f_blocks = st.f_blocks;
84                 buf->f_bfree = st.f_bfree;
85                 buf->f_bavail = st.f_bavail;
86                 buf->f_files = st.f_files;
87                 buf->f_ffree = st.f_ffree;
88                 buf->f_fsid = st.f_fsid;
89                 buf->f_namelen = st.f_namelen;
90                 buf->f_frsize = st.f_frsize;
91                 memset(buf->f_spare, 0, sizeof(buf->f_spare));
92         }
93         return 0;
94 }
95
96 static int vfs_statfs64(struct super_block *sb, struct statfs64 *buf)
97 {
98         struct kstatfs st;
99         int retval;
100
101         retval = vfs_statfs(sb, &st);
102         if (retval)
103                 return retval;
104
105         if (sizeof(*buf) == sizeof(st))
106                 memcpy(buf, &st, sizeof(st));
107         else {
108                 buf->f_type = st.f_type;
109                 buf->f_bsize = st.f_bsize;
110                 buf->f_blocks = st.f_blocks;
111                 buf->f_bfree = st.f_bfree;
112                 buf->f_bavail = st.f_bavail;
113                 buf->f_files = st.f_files;
114                 buf->f_ffree = st.f_ffree;
115                 buf->f_fsid = st.f_fsid;
116                 buf->f_namelen = st.f_namelen;
117                 buf->f_frsize = st.f_frsize;
118                 memset(buf->f_spare, 0, sizeof(buf->f_spare));
119         }
120         return 0;
121 }
122
123 asmlinkage long sys_statfs(const char __user * path, struct statfs __user * buf)
124 {
125         struct nameidata nd;
126         int error;
127
128         error = user_path_walk(path, &nd);
129         if (!error) {
130                 struct statfs tmp;
131                 error = vfs_statfs_native(nd.dentry->d_inode->i_sb, &tmp);
132                 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
133                         error = -EFAULT;
134                 path_release(&nd);
135         }
136         return error;
137 }
138
139
140 asmlinkage long sys_statfs64(const char __user *path, size_t sz, struct statfs64 __user *buf)
141 {
142         struct nameidata nd;
143         long error;
144
145         if (sz != sizeof(*buf))
146                 return -EINVAL;
147         error = user_path_walk(path, &nd);
148         if (!error) {
149                 struct statfs64 tmp;
150                 error = vfs_statfs64(nd.dentry->d_inode->i_sb, &tmp);
151                 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
152                         error = -EFAULT;
153                 path_release(&nd);
154         }
155         return error;
156 }
157
158
159 asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user * buf)
160 {
161         struct file * file;
162         struct statfs tmp;
163         int error;
164
165         error = -EBADF;
166         file = fget(fd);
167         if (!file)
168                 goto out;
169         error = vfs_statfs_native(file->f_dentry->d_inode->i_sb, &tmp);
170         if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
171                 error = -EFAULT;
172         fput(file);
173 out:
174         return error;
175 }
176
177 asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, struct statfs64 __user *buf)
178 {
179         struct file * file;
180         struct statfs64 tmp;
181         int error;
182
183         if (sz != sizeof(*buf))
184                 return -EINVAL;
185
186         error = -EBADF;
187         file = fget(fd);
188         if (!file)
189                 goto out;
190         error = vfs_statfs64(file->f_dentry->d_inode->i_sb, &tmp);
191         if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
192                 error = -EFAULT;
193         fput(file);
194 out:
195         return error;
196 }
197
198 int do_truncate(struct dentry *dentry, loff_t length)
199 {
200         int err;
201         struct iattr newattrs;
202
203         /* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
204         if (length < 0)
205                 return -EINVAL;
206
207         newattrs.ia_size = length;
208         newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
209         down(&dentry->d_inode->i_sem);
210         down_write(&dentry->d_inode->i_alloc_sem);
211         err = notify_change(dentry, &newattrs);
212         up_write(&dentry->d_inode->i_alloc_sem);
213         up(&dentry->d_inode->i_sem);
214         return err;
215 }
216
217 static inline long do_sys_truncate(const char __user * path, loff_t length)
218 {
219         struct nameidata nd;
220         struct inode * inode;
221         int error;
222
223         error = -EINVAL;
224         if (length < 0) /* sorry, but loff_t says... */
225                 goto out;
226
227         error = user_path_walk(path, &nd);
228         if (error)
229                 goto out;
230         inode = nd.dentry->d_inode;
231
232         /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
233         error = -EISDIR;
234         if (S_ISDIR(inode->i_mode))
235                 goto dput_and_out;
236
237         error = -EINVAL;
238         if (!S_ISREG(inode->i_mode))
239                 goto dput_and_out;
240
241         error = permission(inode,MAY_WRITE,&nd);
242         if (error)
243                 goto dput_and_out;
244
245         error = -EROFS;
246         if (IS_RDONLY(inode))
247                 goto dput_and_out;
248
249         error = -EPERM;
250         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
251                 goto dput_and_out;
252
253         /*
254          * Make sure that there are no leases.
255          */
256         error = break_lease(inode, FMODE_WRITE);
257         if (error)
258                 goto dput_and_out;
259
260         error = get_write_access(inode);
261         if (error)
262                 goto dput_and_out;
263
264         error = locks_verify_truncate(inode, NULL, length);
265         if (!error) {
266                 DQUOT_INIT(inode);
267                 error = do_truncate(nd.dentry, length);
268         }
269         put_write_access(inode);
270
271 dput_and_out:
272         path_release(&nd);
273 out:
274         return error;
275 }
276
277 asmlinkage long sys_truncate(const char __user * path, unsigned long length)
278 {
279         /* on 32-bit boxen it will cut the range 2^31--2^32-1 off */
280         return do_sys_truncate(path, (long)length);
281 }
282
283 static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
284 {
285         struct inode * inode;
286         struct dentry *dentry;
287         struct file * file;
288         int error;
289
290         error = -EINVAL;
291         if (length < 0)
292                 goto out;
293         error = -EBADF;
294         file = fget(fd);
295         if (!file)
296                 goto out;
297
298         /* explicitly opened as large or we are on 64-bit box */
299         if (file->f_flags & O_LARGEFILE)
300                 small = 0;
301
302         dentry = file->f_dentry;
303         inode = dentry->d_inode;
304         error = -EINVAL;
305         if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
306                 goto out_putf;
307
308         error = -EINVAL;
309         /* Cannot ftruncate over 2^31 bytes without large file support */
310         if (small && length > MAX_NON_LFS)
311                 goto out_putf;
312
313         error = -EPERM;
314         if (IS_APPEND(inode))
315                 goto out_putf;
316
317         error = locks_verify_truncate(inode, file, length);
318         if (!error)
319                 error = do_truncate(dentry, length);
320 out_putf:
321         fput(file);
322 out:
323         return error;
324 }
325
326 asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
327 {
328         return do_sys_ftruncate(fd, length, 1);
329 }
330
331 /* LFS versions of truncate are only needed on 32 bit machines */
332 #if BITS_PER_LONG == 32
333 asmlinkage long sys_truncate64(const char __user * path, loff_t length)
334 {
335         return do_sys_truncate(path, length);
336 }
337
338 asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
339 {
340         return do_sys_ftruncate(fd, length, 0);
341 }
342 #endif
343
344 #ifdef __ARCH_WANT_SYS_UTIME
345
346 /*
347  * sys_utime() can be implemented in user-level using sys_utimes().
348  * Is this for backwards compatibility?  If so, why not move it
349  * into the appropriate arch directory (for those architectures that
350  * need it).
351  */
352
353 /* If times==NULL, set access and modification to current time,
354  * must be owner or have write permission.
355  * Else, update from *times, must be owner or super user.
356  */
357 asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
358 {
359         int error;
360         struct nameidata nd;
361         struct inode * inode;
362         struct iattr newattrs;
363
364         error = user_path_walk(filename, &nd);
365         if (error)
366                 goto out;
367         inode = nd.dentry->d_inode;
368
369         error = -EROFS;
370         if (IS_RDONLY(inode))
371                 goto dput_and_out;
372
373         /* Don't worry, the checks are done in inode_change_ok() */
374         newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
375         if (times) {
376                 error = -EPERM;
377                 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
378                         goto dput_and_out;
379
380                 error = get_user(newattrs.ia_atime.tv_sec, &times->actime);
381                 newattrs.ia_atime.tv_nsec = 0;
382                 if (!error) 
383                         error = get_user(newattrs.ia_mtime.tv_sec, &times->modtime);
384                 newattrs.ia_mtime.tv_nsec = 0;
385                 if (error)
386                         goto dput_and_out;
387
388                 newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
389         } else {
390                 error = -EACCES;
391                 if (IS_IMMUTABLE(inode))
392                         goto dput_and_out;
393
394                 if (current->fsuid != inode->i_uid &&
395                     (error = permission(inode,MAY_WRITE,&nd)) != 0)
396                         goto dput_and_out;
397         }
398         down(&inode->i_sem);
399         error = notify_change(nd.dentry, &newattrs);
400         up(&inode->i_sem);
401 dput_and_out:
402         path_release(&nd);
403 out:
404         return error;
405 }
406
407 #endif
408
409 /* If times==NULL, set access and modification to current time,
410  * must be owner or have write permission.
411  * Else, update from *times, must be owner or super user.
412  */
413 long do_utimes(char __user * filename, struct timeval * times)
414 {
415         int error;
416         struct nameidata nd;
417         struct inode * inode;
418         struct iattr newattrs;
419
420         error = user_path_walk(filename, &nd);
421
422         if (error)
423                 goto out;
424         inode = nd.dentry->d_inode;
425
426         error = -EROFS;
427         if (IS_RDONLY(inode))
428                 goto dput_and_out;
429
430         /* Don't worry, the checks are done in inode_change_ok() */
431         newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
432         if (times) {
433                 error = -EPERM;
434                 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
435                         goto dput_and_out;
436
437                 newattrs.ia_atime.tv_sec = times[0].tv_sec;
438                 newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000;
439                 newattrs.ia_mtime.tv_sec = times[1].tv_sec;
440                 newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000;
441                 newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
442         } else {
443                 error = -EACCES;
444                 if (IS_IMMUTABLE(inode))
445                         goto dput_and_out;
446
447                 if (current->fsuid != inode->i_uid &&
448                     (error = permission(inode,MAY_WRITE,&nd)) != 0)
449                         goto dput_and_out;
450         }
451         down(&inode->i_sem);
452         error = notify_change(nd.dentry, &newattrs);
453         up(&inode->i_sem);
454 dput_and_out:
455         path_release(&nd);
456 out:
457         return error;
458 }
459
460 asmlinkage long sys_utimes(char __user * filename, struct timeval __user * utimes)
461 {
462         struct timeval times[2];
463
464         if (utimes && copy_from_user(&times, utimes, sizeof(times)))
465                 return -EFAULT;
466         return do_utimes(filename, utimes ? times : NULL);
467 }
468
469
470 /*
471  * access() needs to use the real uid/gid, not the effective uid/gid.
472  * We do this by temporarily clearing all FS-related capabilities and
473  * switching the fsuid/fsgid around to the real ones.
474  */
475 asmlinkage long sys_access(const char __user * filename, int mode)
476 {
477         struct nameidata nd;
478         int old_fsuid, old_fsgid;
479         kernel_cap_t old_cap;
480         int res;
481
482         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
483                 return -EINVAL;
484
485         old_fsuid = current->fsuid;
486         old_fsgid = current->fsgid;
487         old_cap = current->cap_effective;
488
489         current->fsuid = current->uid;
490         current->fsgid = current->gid;
491
492         /*
493          * Clear the capabilities if we switch to a non-root user
494          *
495          * FIXME: There is a race here against sys_capset.  The
496          * capabilities can change yet we will restore the old
497          * value below.  We should hold task_capabilities_lock,
498          * but we cannot because user_path_walk can sleep.
499          */
500         if (current->uid)
501                 cap_clear(current->cap_effective);
502         else
503                 current->cap_effective = current->cap_permitted;
504
505         res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
506         if (!res) {
507                 res = permission(nd.dentry->d_inode, mode, &nd);
508                 /* SuS v2 requires we report a read only fs too */
509                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
510                    && !special_file(nd.dentry->d_inode->i_mode))
511                         res = -EROFS;
512                 path_release(&nd);
513         }
514
515         current->fsuid = old_fsuid;
516         current->fsgid = old_fsgid;
517         current->cap_effective = old_cap;
518
519         return res;
520 }
521
522 asmlinkage long sys_chdir(const char __user * filename)
523 {
524         struct nameidata nd;
525         int error;
526
527         error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
528         if (error)
529                 goto out;
530
531         error = permission(nd.dentry->d_inode,MAY_EXEC,&nd);
532         if (error)
533                 goto dput_and_out;
534
535         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
536
537 dput_and_out:
538         path_release(&nd);
539 out:
540         return error;
541 }
542
543 asmlinkage long sys_fchdir(unsigned int fd)
544 {
545         struct file *file;
546         struct dentry *dentry;
547         struct inode *inode;
548         struct vfsmount *mnt;
549         int error;
550
551         error = -EBADF;
552         file = fget(fd);
553         if (!file)
554                 goto out;
555
556         dentry = file->f_dentry;
557         mnt = file->f_vfsmnt;
558         inode = dentry->d_inode;
559
560         error = -ENOTDIR;
561         if (!S_ISDIR(inode->i_mode))
562                 goto out_putf;
563
564         error = permission(inode, MAY_EXEC, NULL);
565         if (!error)
566                 set_fs_pwd(current->fs, mnt, dentry);
567 out_putf:
568         fput(file);
569 out:
570         return error;
571 }
572
573 asmlinkage long sys_chroot(const char __user * filename)
574 {
575         struct nameidata nd;
576         int error;
577
578         error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
579         if (error)
580                 goto out;
581
582         error = permission(nd.dentry->d_inode,MAY_EXEC,&nd);
583         if (error)
584                 goto dput_and_out;
585
586         error = -EPERM;
587         if (!capable(CAP_SYS_CHROOT))
588                 goto dput_and_out;
589
590         set_fs_root(current->fs, nd.mnt, nd.dentry);
591         set_fs_altroot();
592         error = 0;
593 dput_and_out:
594         path_release(&nd);
595 out:
596         return error;
597 }
598
599 asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
600 {
601         struct inode * inode;
602         struct dentry * dentry;
603         struct file * file;
604         int err = -EBADF;
605         struct iattr newattrs;
606
607         file = fget(fd);
608         if (!file)
609                 goto out;
610
611         dentry = file->f_dentry;
612         inode = dentry->d_inode;
613
614         err = -EPERM;
615         if (IS_BARRIER(inode) && !vx_check(0, VX_ADMIN))
616                 goto out_putf;
617         err = -EROFS;
618         if (IS_RDONLY(inode))
619                 goto out_putf;
620         err = -EPERM;
621         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
622                 goto out_putf;
623         down(&inode->i_sem);
624         if (mode == (mode_t) -1)
625                 mode = inode->i_mode;
626         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
627         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
628         err = notify_change(dentry, &newattrs);
629         up(&inode->i_sem);
630
631 out_putf:
632         fput(file);
633 out:
634         return err;
635 }
636
637 asmlinkage long sys_chmod(const char __user * filename, mode_t mode)
638 {
639         struct nameidata nd;
640         struct inode * inode;
641         int error;
642         struct iattr newattrs;
643
644         error = user_path_walk(filename, &nd);
645         if (error)
646                 goto out;
647         inode = nd.dentry->d_inode;
648
649         error = -EPERM;
650         if (IS_BARRIER(inode) && !vx_check(0, VX_ADMIN))
651                 goto dput_and_out;
652
653         error = -EROFS;
654         if (IS_RDONLY(inode))
655                 goto dput_and_out;
656
657         error = -EPERM;
658         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
659                 goto dput_and_out;
660
661         down(&inode->i_sem);
662         if (mode == (mode_t) -1)
663                 mode = inode->i_mode;
664         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
665         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
666         error = notify_change(nd.dentry, &newattrs);
667         up(&inode->i_sem);
668
669 dput_and_out:
670         path_release(&nd);
671 out:
672         return error;
673 }
674
675 static int chown_common(struct dentry * dentry, 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))
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, 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, 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, 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;
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->rlim[RLIMIT_NOFILE].rlim_cur)
868                 goto out;
869
870         /* Do we need to expand the fdset array? */
871         if (fd >= files->max_fdset) {
872                 error = expand_fdset(files, fd);
873                 if (!error) {
874                         error = -EMFILE;
875                         goto repeat;
876                 }
877                 goto out;
878         }
879         
880         /* 
881          * Check whether we need to expand the fd array.
882          */
883         if (fd >= files->max_fds) {
884                 error = expand_fd_array(files, fd);
885                 if (!error) {
886                         error = -EMFILE;
887                         goto repeat;
888                 }
889                 goto out;
890         }
891
892         FD_SET(fd, files->open_fds);
893         FD_CLR(fd, files->close_on_exec);
894         files->next_fd = fd + 1;
895         vx_openfd_inc(fd);
896 #if 1
897         /* Sanity check */
898         if (files->fd[fd] != NULL) {
899                 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
900                 files->fd[fd] = NULL;
901         }
902 #endif
903         error = fd;
904
905 out:
906         spin_unlock(&files->file_lock);
907         return error;
908 }
909
910 EXPORT_SYMBOL(get_unused_fd);
911
912 static inline void __put_unused_fd(struct files_struct *files, unsigned int fd)
913 {
914         __FD_CLR(fd, files->open_fds);
915         if (fd < files->next_fd)
916                 files->next_fd = fd;
917 }
918
919 void fastcall put_unused_fd(unsigned int fd)
920 {
921         struct files_struct *files = current->files;
922         spin_lock(&files->file_lock);
923         __put_unused_fd(files, fd);
924         spin_unlock(&files->file_lock);
925 }
926
927 EXPORT_SYMBOL(put_unused_fd);
928
929 /*
930  * Install a file pointer in the fd array.  
931  *
932  * The VFS is full of places where we drop the files lock between
933  * setting the open_fds bitmap and installing the file in the file
934  * array.  At any such point, we are vulnerable to a dup2() race
935  * installing a file in the array before us.  We need to detect this and
936  * fput() the struct file we are about to overwrite in this case.
937  *
938  * It should never happen - if we allow dup2() do it, _really_ bad things
939  * will follow.
940  */
941
942 void fastcall fd_install(unsigned int fd, struct file * file)
943 {
944         struct files_struct *files = current->files;
945         spin_lock(&files->file_lock);
946         if (unlikely(files->fd[fd] != NULL))
947                 BUG();
948         files->fd[fd] = file;
949         spin_unlock(&files->file_lock);
950 }
951
952 EXPORT_SYMBOL(fd_install);
953
954 asmlinkage long sys_open(const char __user * filename, int flags, int mode)
955 {
956         char * tmp;
957         int fd, error;
958
959 #if BITS_PER_LONG != 32
960         flags |= O_LARGEFILE;
961 #endif
962         tmp = getname(filename);
963         fd = PTR_ERR(tmp);
964         if (!IS_ERR(tmp)) {
965                 fd = get_unused_fd();
966                 if (fd >= 0) {
967                         struct file *f = filp_open(tmp, flags, mode);
968                         error = PTR_ERR(f);
969                         if (IS_ERR(f))
970                                 goto out_error;
971                         fd_install(fd, f);
972                 }
973 out:
974                 putname(tmp);
975         }
976         return fd;
977
978 out_error:
979         put_unused_fd(fd);
980         fd = error;
981         goto out;
982 }
983
984 #ifndef __alpha__
985
986 /*
987  * For backward compatibility?  Maybe this should be moved
988  * into arch/i386 instead?
989  */
990 asmlinkage long sys_creat(const char __user * pathname, int mode)
991 {
992         return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
993 }
994
995 #endif
996
997 /*
998  * "id" is the POSIX thread ID. We use the
999  * files pointer for this..
1000  */
1001 int filp_close(struct file *filp, fl_owner_t id)
1002 {
1003         int retval;
1004
1005         /* Report and clear outstanding errors */
1006         retval = filp->f_error;
1007         if (retval)
1008                 filp->f_error = 0;
1009
1010         if (!file_count(filp)) {
1011                 printk(KERN_ERR "VFS: Close: file count is 0\n");
1012                 return retval;
1013         }
1014
1015         if (filp->f_op && filp->f_op->flush) {
1016                 int err = filp->f_op->flush(filp);
1017                 if (!retval)
1018                         retval = err;
1019         }
1020
1021         dnotify_flush(filp, id);
1022         locks_remove_posix(filp, id);
1023         fput(filp);
1024         return retval;
1025 }
1026
1027 EXPORT_SYMBOL(filp_close);
1028
1029 /*
1030  * Careful here! We test whether the file pointer is NULL before
1031  * releasing the fd. This ensures that one clone task can't release
1032  * an fd while another clone is opening it.
1033  */
1034 asmlinkage long sys_close(unsigned int fd)
1035 {
1036         struct file * filp;
1037         struct files_struct *files = current->files;
1038
1039         spin_lock(&files->file_lock);
1040         if (fd >= files->max_fds)
1041                 goto out_unlock;
1042         filp = files->fd[fd];
1043         if (!filp)
1044                 goto out_unlock;
1045         files->fd[fd] = NULL;
1046         FD_CLR(fd, files->close_on_exec);
1047         __put_unused_fd(files, fd);
1048         spin_unlock(&files->file_lock);
1049         vx_openfd_dec(fd);
1050         return filp_close(filp, files);
1051
1052 out_unlock:
1053         spin_unlock(&files->file_lock);
1054         return -EBADF;
1055 }
1056
1057
1058 /*
1059  * This routine simulates a hangup on the tty, to arrange that users
1060  * are given clean terminals at login time.
1061  */
1062 asmlinkage long sys_vhangup(void)
1063 {
1064         if (capable(CAP_SYS_TTY_CONFIG)) {
1065                 tty_vhangup(current->signal->tty);
1066                 return 0;
1067         }
1068         return -EPERM;
1069 }
1070
1071 /*
1072  * Called when an inode is about to be open.
1073  * We use this to disallow opening large files on 32bit systems if
1074  * the caller didn't specify O_LARGEFILE.  On 64bit systems we force
1075  * on this flag in sys_open.
1076  */
1077 int generic_file_open(struct inode * inode, struct file * filp)
1078 {
1079         if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
1080                 return -EFBIG;
1081         return 0;
1082 }
1083
1084 EXPORT_SYMBOL(generic_file_open);