4 * Copyright (C) 1991, 1992 Linus Torvalds
8 #include <linux/types.h>
9 #include <linux/utime.h>
10 #include <linux/errno.h>
11 #include <linux/fcntl.h>
12 #include <linux/stat.h>
13 #include <linux/string.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/signal.h>
17 #include <linux/tty.h>
18 #include <linux/time.h>
20 #include <linux/file.h>
21 #include <linux/smp.h>
22 #include <linux/smp_lock.h>
23 #include <linux/quotaops.h>
25 #include <asm/uaccess.h>
26 #include <asm/bitops.h>
28 asmlinkage
int sys_statfs(const char * path
, struct statfs
* buf
)
30 struct dentry
* dentry
;
35 error
= PTR_ERR(dentry
);
36 if (!IS_ERR(dentry
)) {
37 struct inode
* inode
= dentry
->d_inode
;
40 if (inode
->i_sb
->s_op
->statfs
)
41 error
= inode
->i_sb
->s_op
->statfs(inode
->i_sb
, buf
, sizeof(struct statfs
));
49 asmlinkage
int sys_fstatfs(unsigned int fd
, struct statfs
* buf
)
53 struct dentry
* dentry
;
54 struct super_block
* sb
;
63 if (!(dentry
= file
->f_dentry
))
65 if (!(inode
= dentry
->d_inode
))
68 if (!(sb
= inode
->i_sb
))
72 error
= sb
->s_op
->statfs(sb
, buf
, sizeof(struct statfs
));
80 int do_truncate(struct dentry
*dentry
, unsigned long length
)
82 struct inode
*inode
= dentry
->d_inode
;
84 struct iattr newattrs
;
87 newattrs
.ia_size
= length
;
88 newattrs
.ia_valid
= ATTR_SIZE
| ATTR_CTIME
;
89 error
= notify_change(dentry
, &newattrs
);
91 /* truncate virtual mappings of this file */
92 vmtruncate(inode
, length
);
93 if (inode
->i_op
&& inode
->i_op
->truncate
)
94 inode
->i_op
->truncate(inode
);
100 asmlinkage
int sys_truncate(const char * path
, unsigned long length
)
102 struct dentry
* dentry
;
103 struct inode
* inode
;
107 dentry
= namei(path
);
109 error
= PTR_ERR(dentry
);
112 inode
= dentry
->d_inode
;
115 if (S_ISDIR(inode
->i_mode
))
118 error
= permission(inode
,MAY_WRITE
);
123 if (IS_RDONLY(inode
))
127 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
130 error
= get_write_access(inode
);
134 error
= locks_verify_area(FLOCK_VERIFY_WRITE
, inode
, NULL
,
135 length
< inode
->i_size
? length
: inode
->i_size
,
136 abs(inode
->i_size
- length
));
139 error
= do_truncate(dentry
, length
);
141 put_write_access(inode
);
149 asmlinkage
int sys_ftruncate(unsigned int fd
, unsigned long length
)
151 struct inode
* inode
;
152 struct dentry
*dentry
;
162 if (!(dentry
= file
->f_dentry
))
164 if (!(inode
= dentry
->d_inode
))
167 if (S_ISDIR(inode
->i_mode
) || !(file
->f_mode
& FMODE_WRITE
))
170 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
172 error
= locks_verify_area(FLOCK_VERIFY_WRITE
, inode
, file
,
173 length
<inode
->i_size
? length
: inode
->i_size
,
174 abs(inode
->i_size
- length
));
176 error
= do_truncate(dentry
, length
);
187 * sys_utime() can be implemented in user-level using sys_utimes().
188 * Is this for backwards compatibility? If so, why not move it
189 * into the appropriate arch directory (for those architectures that
193 /* If times==NULL, set access and modification to current time,
194 * must be owner or have write permission.
195 * Else, update from *times, must be owner or super user.
197 asmlinkage
int sys_utime(char * filename
, struct utimbuf
* times
)
200 struct dentry
* dentry
;
201 struct inode
* inode
;
202 struct iattr newattrs
;
205 dentry
= namei(filename
);
207 error
= PTR_ERR(dentry
);
210 inode
= dentry
->d_inode
;
213 if (IS_RDONLY(inode
))
216 /* Don't worry, the checks are done in inode_change_ok() */
217 newattrs
.ia_valid
= ATTR_CTIME
| ATTR_MTIME
| ATTR_ATIME
;
219 error
= get_user(newattrs
.ia_atime
, ×
->actime
);
221 error
= get_user(newattrs
.ia_mtime
, ×
->modtime
);
225 newattrs
.ia_valid
|= ATTR_ATIME_SET
| ATTR_MTIME_SET
;
227 if (current
->fsuid
!= inode
->i_uid
&&
228 (error
= permission(inode
,MAY_WRITE
)) != 0)
231 error
= notify_change(dentry
, &newattrs
);
241 /* If times==NULL, set access and modification to current time,
242 * must be owner or have write permission.
243 * Else, update from *times, must be owner or super user.
245 asmlinkage
int sys_utimes(char * filename
, struct timeval
* utimes
)
248 struct dentry
* dentry
;
249 struct inode
* inode
;
250 struct iattr newattrs
;
253 dentry
= namei(filename
);
255 error
= PTR_ERR(dentry
);
258 inode
= dentry
->d_inode
;
261 if (IS_RDONLY(inode
))
264 /* Don't worry, the checks are done in inode_change_ok() */
265 newattrs
.ia_valid
= ATTR_CTIME
| ATTR_MTIME
| ATTR_ATIME
;
267 struct timeval times
[2];
269 if (copy_from_user(×
, utimes
, sizeof(times
)))
271 newattrs
.ia_atime
= times
[0].tv_sec
;
272 newattrs
.ia_mtime
= times
[1].tv_sec
;
273 newattrs
.ia_valid
|= ATTR_ATIME_SET
| ATTR_MTIME_SET
;
275 if ((error
= permission(inode
,MAY_WRITE
)) != 0)
278 error
= notify_change(dentry
, &newattrs
);
287 * access() needs to use the real uid/gid, not the effective uid/gid.
288 * We do this by temporarily clearing all FS-related capabilities and
289 * switching the fsuid/fsgid around to the real ones.
291 asmlinkage
int sys_access(const char * filename
, int mode
)
293 struct dentry
* dentry
;
294 int old_fsuid
, old_fsgid
;
295 kernel_cap_t old_cap
;
299 if (mode
!= (mode
& S_IRWXO
)) /* where's F_OK, X_OK, W_OK, R_OK? */
301 old_fsuid
= current
->fsuid
;
302 old_fsgid
= current
->fsgid
;
303 old_cap
= current
->cap_effective
;
305 current
->fsuid
= current
->uid
;
306 current
->fsgid
= current
->gid
;
308 /* Clear the capabilities if we switch to a non-root user */
310 cap_clear(current
->cap_effective
);
312 dentry
= namei(filename
);
313 res
= PTR_ERR(dentry
);
314 if (!IS_ERR(dentry
)) {
315 res
= permission(dentry
->d_inode
, mode
);
319 current
->fsuid
= old_fsuid
;
320 current
->fsgid
= old_fsgid
;
321 current
->cap_effective
= old_cap
;
327 asmlinkage
int sys_chdir(const char * filename
)
331 struct dentry
*dentry
, *tmp
;
335 dentry
= namei(filename
);
336 error
= PTR_ERR(dentry
);
340 inode
= dentry
->d_inode
;
343 if (!S_ISDIR(inode
->i_mode
))
346 error
= permission(inode
,MAY_EXEC
);
350 /* exchange dentries */
351 tmp
= current
->fs
->pwd
;
352 current
->fs
->pwd
= dentry
;
362 asmlinkage
int sys_fchdir(unsigned int fd
)
365 struct dentry
*dentry
;
377 if (!(dentry
= file
->f_dentry
))
379 if (!(inode
= dentry
->d_inode
))
383 if (!S_ISDIR(inode
->i_mode
))
386 error
= permission(inode
, MAY_EXEC
);
388 struct dentry
*tmp
= current
->fs
->pwd
;
389 current
->fs
->pwd
= dget(dentry
);
399 asmlinkage
int sys_chroot(const char * filename
)
403 struct dentry
*dentry
, *tmp
;
407 dentry
= namei(filename
);
408 error
= PTR_ERR(dentry
);
412 inode
= dentry
->d_inode
;
415 if (!S_ISDIR(inode
->i_mode
))
418 error
= permission(inode
,MAY_EXEC
);
423 if (!capable(CAP_SYS_CHROOT
))
426 /* exchange dentries */
427 tmp
= current
->fs
->root
;
428 current
->fs
->root
= dentry
;
439 asmlinkage
int sys_fchmod(unsigned int fd
, mode_t mode
)
441 struct inode
* inode
;
442 struct dentry
* dentry
;
445 struct iattr newattrs
;
453 if (!(dentry
= file
->f_dentry
))
455 if (!(inode
= dentry
->d_inode
))
459 if (IS_RDONLY(inode
))
462 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
464 if (mode
== (mode_t
) -1)
465 mode
= inode
->i_mode
;
466 newattrs
.ia_mode
= (mode
& S_IALLUGO
) | (inode
->i_mode
& ~S_IALLUGO
);
467 newattrs
.ia_valid
= ATTR_MODE
| ATTR_CTIME
;
468 err
= notify_change(dentry
, &newattrs
);
477 asmlinkage
int sys_chmod(const char * filename
, mode_t mode
)
479 struct dentry
* dentry
;
480 struct inode
* inode
;
482 struct iattr newattrs
;
485 dentry
= namei(filename
);
487 error
= PTR_ERR(dentry
);
490 inode
= dentry
->d_inode
;
493 if (IS_RDONLY(inode
))
497 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
500 if (mode
== (mode_t
) -1)
501 mode
= inode
->i_mode
;
502 newattrs
.ia_mode
= (mode
& S_IALLUGO
) | (inode
->i_mode
& ~S_IALLUGO
);
503 newattrs
.ia_valid
= ATTR_MODE
| ATTR_CTIME
;
504 error
= notify_change(dentry
, &newattrs
);
513 static int chown_common(struct dentry
* dentry
, uid_t user
, gid_t group
)
515 struct inode
* inode
;
517 struct iattr newattrs
;
520 if (!(inode
= dentry
->d_inode
)) {
521 printk("chown_common: NULL inode\n");
525 if (IS_RDONLY(inode
))
528 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
530 if (user
== (uid_t
) -1)
532 if (group
== (gid_t
) -1)
533 group
= inode
->i_gid
;
534 newattrs
.ia_mode
= inode
->i_mode
;
535 newattrs
.ia_uid
= user
;
536 newattrs
.ia_gid
= group
;
537 newattrs
.ia_valid
= ATTR_UID
| ATTR_GID
| ATTR_CTIME
;
539 * If the owner has been changed, remove the setuid bit
541 if (inode
->i_mode
& S_ISUID
) {
542 newattrs
.ia_mode
&= ~S_ISUID
;
543 newattrs
.ia_valid
|= ATTR_MODE
;
546 * If the group has been changed, remove the setgid bit
548 * Don't remove the setgid bit if no group execute bit.
549 * This is a file marked for mandatory locking.
551 if (((inode
->i_mode
& (S_ISGID
| S_IXGRP
)) == (S_ISGID
| S_IXGRP
))) {
552 newattrs
.ia_mode
&= ~S_ISGID
;
553 newattrs
.ia_valid
|= ATTR_MODE
;
555 error
= DQUOT_TRANSFER(dentry
, &newattrs
);
560 asmlinkage
int sys_chown(const char * filename
, uid_t user
, gid_t group
)
562 struct dentry
* dentry
;
566 dentry
= namei(filename
);
568 error
= PTR_ERR(dentry
);
569 if (!IS_ERR(dentry
)) {
570 error
= chown_common(dentry
, user
, group
);
577 asmlinkage
int sys_lchown(const char * filename
, uid_t user
, gid_t group
)
579 struct dentry
* dentry
;
583 dentry
= lnamei(filename
);
585 error
= PTR_ERR(dentry
);
586 if (!IS_ERR(dentry
)) {
587 error
= chown_common(dentry
, user
, group
);
595 asmlinkage
int sys_fchown(unsigned int fd
, uid_t user
, gid_t group
)
597 struct dentry
* dentry
;
606 if ((dentry
= file
->f_dentry
) != NULL
)
607 error
= chown_common(dentry
, user
, group
);
616 * Note that while the flag value (low two bits) for sys_open means:
622 * 00 - no permissions needed
623 * 01 - read-permission
624 * 10 - write-permission
626 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
629 static int do_open(const char * filename
, int flags
, int mode
, int fd
)
631 struct inode
* inode
;
632 struct dentry
* dentry
;
637 f
= get_empty_filp();
640 f
->f_flags
= flag
= flags
;
641 f
->f_mode
= (flag
+1) & O_ACCMODE
;
646 dentry
= open_namei(filename
,flag
,mode
);
647 error
= PTR_ERR(dentry
);
650 inode
= dentry
->d_inode
;
651 if (f
->f_mode
& FMODE_WRITE
) {
652 error
= get_write_access(inode
);
657 f
->f_dentry
= dentry
;
662 f
->f_op
= inode
->i_op
->default_file_ops
;
663 if (f
->f_op
&& f
->f_op
->open
) {
664 error
= f
->f_op
->open(inode
,f
);
668 f
->f_flags
&= ~(O_CREAT
| O_EXCL
| O_NOCTTY
| O_TRUNC
);
674 if (f
->f_mode
& FMODE_WRITE
)
675 put_write_access(inode
);
686 * Find an empty file descriptor entry, and mark it busy.
688 int get_unused_fd(void)
690 struct files_struct
* files
= current
->files
;
694 fd
= find_first_zero_bit(&files
->open_fds
, NR_OPEN
);
696 * N.B. For clone tasks sharing a files structure, this test
697 * will limit the total number of files that can be opened.
699 if (fd
>= current
->rlim
[RLIMIT_NOFILE
].rlim_cur
)
702 /* Check here for fd > files->max_fds to do dynamic expansion */
704 FD_SET(fd
, &files
->open_fds
);
705 FD_CLR(fd
, &files
->close_on_exec
);
708 if (files
->fd
[fd
] != NULL
) {
709 printk("get_unused_fd: slot %d not NULL!\n", fd
);
710 files
->fd
[fd
] = NULL
;
719 inline void put_unused_fd(unsigned int fd
)
721 FD_CLR(fd
, ¤t
->files
->open_fds
);
724 asmlinkage
int sys_open(const char * filename
, int flags
, int mode
)
730 fd
= get_unused_fd();
734 tmp
= getname(filename
);
735 error
= PTR_ERR(tmp
);
738 error
= do_open(tmp
, flags
, mode
, fd
);
755 * For backward compatibility? Maybe this should be moved
756 * into arch/i386 instead?
758 asmlinkage
int sys_creat(const char * pathname
, int mode
)
763 ret
= sys_open(pathname
, O_CREAT
| O_WRONLY
| O_TRUNC
, mode
);
771 * Called when retiring the last use of a file pointer.
773 void __fput(struct file
*filp
)
775 struct dentry
* dentry
= filp
->f_dentry
;
776 struct inode
* inode
= dentry
->d_inode
;
778 if (filp
->f_op
&& filp
->f_op
->release
)
779 filp
->f_op
->release(inode
, filp
);
780 filp
->f_dentry
= NULL
;
781 if (filp
->f_mode
& FMODE_WRITE
)
782 put_write_access(inode
);
787 * "id" is the POSIX thread ID. We use the
788 * files pointer for this..
790 int close_fp(struct file
*filp
, fl_owner_t id
)
793 struct dentry
*dentry
= filp
->f_dentry
;
795 if (filp
->f_count
== 0) {
796 printk("VFS: Close: file count is 0\n");
800 locks_remove_posix(filp
, id
);
802 if (filp
->f_op
&& filp
->f_op
->flush
)
803 retval
= filp
->f_op
->flush(filp
);
809 * Careful here! We test whether the file pointer is NULL before
810 * releasing the fd. This ensures that one clone task can't release
811 * an fd while another clone is opening it.
813 asmlinkage
int sys_close(unsigned int fd
)
822 struct files_struct
* files
= current
->files
;
823 files
->fd
[fd
] = NULL
;
825 FD_CLR(fd
, &files
->close_on_exec
);
826 error
= close_fp(filp
, files
);
833 * This routine simulates a hangup on the tty, to arrange that users
834 * are given clean terminals at login time.
836 asmlinkage
int sys_vhangup(void)
841 if (!capable(CAP_SYS_TTY_CONFIG
))
843 /* If there is a controlling tty, hang it up */
845 tty_vhangup(current
->tty
);