4 * Copyright (C) 1991, 1992 Linus Torvalds
7 #include <linux/string.h>
9 #include <linux/utime.h>
10 #include <linux/file.h>
11 #include <linux/smp_lock.h>
12 #include <linux/quotaops.h>
14 #include <asm/uaccess.h>
16 int vfs_statfs(struct super_block
*sb
, struct statfs
*buf
)
22 if (sb
->s_op
&& sb
->s_op
->statfs
) {
23 memset(buf
, 0, sizeof(struct statfs
));
25 retval
= sb
->s_op
->statfs(sb
, buf
);
33 asmlinkage
long sys_statfs(const char * path
, struct statfs
* buf
)
38 error
= user_path_walk(path
, &nd
);
41 error
= vfs_statfs(nd
.dentry
->d_inode
->i_sb
, &tmp
);
42 if (!error
&& copy_to_user(buf
, &tmp
, sizeof(struct statfs
)))
49 asmlinkage
long sys_fstatfs(unsigned int fd
, struct statfs
* buf
)
59 error
= vfs_statfs(file
->f_dentry
->d_inode
->i_sb
, &tmp
);
60 if (!error
&& copy_to_user(buf
, &tmp
, sizeof(struct statfs
)))
67 int do_truncate(struct dentry
*dentry
, loff_t length
)
69 struct inode
*inode
= dentry
->d_inode
;
71 struct iattr newattrs
;
73 /* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
78 newattrs
.ia_size
= length
;
79 newattrs
.ia_valid
= ATTR_SIZE
| ATTR_CTIME
;
80 error
= notify_change(dentry
, &newattrs
);
85 static inline long do_sys_truncate(const char * path
, loff_t length
)
92 if (length
< 0) /* sorry, but loff_t says... */
95 error
= user_path_walk(path
, &nd
);
98 inode
= nd
.dentry
->d_inode
;
101 if (S_ISDIR(inode
->i_mode
))
104 error
= permission(inode
,MAY_WRITE
);
109 if (IS_RDONLY(inode
))
113 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
117 error
= get_write_access(inode
);
121 error
= locks_verify_truncate(inode
, NULL
, length
);
124 error
= do_truncate(nd
.dentry
, length
);
126 put_write_access(inode
);
135 asmlinkage
long sys_truncate(const char * path
, unsigned long length
)
137 return do_sys_truncate(path
, length
);
140 static inline long do_sys_ftruncate(unsigned int fd
, loff_t length
)
142 struct inode
* inode
;
143 struct dentry
*dentry
;
154 dentry
= file
->f_dentry
;
155 inode
= dentry
->d_inode
;
157 if (S_ISDIR(inode
->i_mode
) || !(file
->f_mode
& FMODE_WRITE
))
160 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
164 error
= locks_verify_truncate(inode
, file
, length
);
166 error
= do_truncate(dentry
, length
);
174 asmlinkage
long sys_ftruncate(unsigned int fd
, unsigned long length
)
176 return do_sys_ftruncate(fd
, length
);
179 /* LFS versions of truncate are only needed on 32 bit machines */
180 #if BITS_PER_LONG == 32
181 asmlinkage
long sys_truncate64(const char * path
, loff_t length
)
183 return do_sys_truncate(path
, length
);
186 asmlinkage
long sys_ftruncate64(unsigned int fd
, loff_t length
)
188 return do_sys_ftruncate(fd
, length
);
192 #if !(defined(__alpha__) || defined(__ia64__))
195 * sys_utime() can be implemented in user-level using sys_utimes().
196 * Is this for backwards compatibility? If so, why not move it
197 * into the appropriate arch directory (for those architectures that
201 /* If times==NULL, set access and modification to current time,
202 * must be owner or have write permission.
203 * Else, update from *times, must be owner or super user.
205 asmlinkage
long sys_utime(char * filename
, struct utimbuf
* times
)
209 struct inode
* inode
;
210 struct iattr newattrs
;
212 error
= user_path_walk(filename
, &nd
);
215 inode
= nd
.dentry
->d_inode
;
218 if (IS_RDONLY(inode
))
221 /* Don't worry, the checks are done in inode_change_ok() */
222 newattrs
.ia_valid
= ATTR_CTIME
| ATTR_MTIME
| ATTR_ATIME
;
224 error
= get_user(newattrs
.ia_atime
, ×
->actime
);
226 error
= get_user(newattrs
.ia_mtime
, ×
->modtime
);
230 newattrs
.ia_valid
|= ATTR_ATIME_SET
| ATTR_MTIME_SET
;
232 if (current
->fsuid
!= inode
->i_uid
&&
233 (error
= permission(inode
,MAY_WRITE
)) != 0)
236 error
= notify_change(nd
.dentry
, &newattrs
);
245 /* If times==NULL, set access and modification to current time,
246 * must be owner or have write permission.
247 * Else, update from *times, must be owner or super user.
249 asmlinkage
long sys_utimes(char * filename
, struct timeval
* utimes
)
253 struct inode
* inode
;
254 struct iattr newattrs
;
256 error
= user_path_walk(filename
, &nd
);
260 inode
= nd
.dentry
->d_inode
;
263 if (IS_RDONLY(inode
))
266 /* Don't worry, the checks are done in inode_change_ok() */
267 newattrs
.ia_valid
= ATTR_CTIME
| ATTR_MTIME
| ATTR_ATIME
;
269 struct timeval times
[2];
271 if (copy_from_user(×
, utimes
, sizeof(times
)))
273 newattrs
.ia_atime
= times
[0].tv_sec
;
274 newattrs
.ia_mtime
= times
[1].tv_sec
;
275 newattrs
.ia_valid
|= ATTR_ATIME_SET
| ATTR_MTIME_SET
;
277 if ((error
= permission(inode
,MAY_WRITE
)) != 0)
280 error
= notify_change(nd
.dentry
, &newattrs
);
288 * access() needs to use the real uid/gid, not the effective uid/gid.
289 * We do this by temporarily clearing all FS-related capabilities and
290 * switching the fsuid/fsgid around to the real ones.
292 asmlinkage
long sys_access(const char * filename
, int mode
)
295 int old_fsuid
, old_fsgid
;
296 kernel_cap_t old_cap
;
299 if (mode
& ~S_IRWXO
) /* where's F_OK, X_OK, W_OK, R_OK? */
302 old_fsuid
= current
->fsuid
;
303 old_fsgid
= current
->fsgid
;
304 old_cap
= current
->cap_effective
;
306 current
->fsuid
= current
->uid
;
307 current
->fsgid
= current
->gid
;
309 /* Clear the capabilities if we switch to a non-root user */
311 cap_clear(current
->cap_effective
);
313 current
->cap_effective
= current
->cap_permitted
;
315 res
= user_path_walk(filename
, &nd
);
317 res
= permission(nd
.dentry
->d_inode
, mode
);
318 /* SuS v2 requires we report a read only fs too */
319 if(!res
&& (mode
& S_IWOTH
) && IS_RDONLY(nd
.dentry
->d_inode
))
324 current
->fsuid
= old_fsuid
;
325 current
->fsgid
= old_fsgid
;
326 current
->cap_effective
= old_cap
;
331 asmlinkage
long sys_chdir(const char * filename
)
339 name
= getname(filename
);
340 error
= PTR_ERR(name
);
345 if (path_init(name
,LOOKUP_POSITIVE
|LOOKUP_FOLLOW
|LOOKUP_DIRECTORY
,&nd
))
346 error
= path_walk(name
, &nd
);
351 error
= permission(nd
.dentry
->d_inode
,MAY_EXEC
);
355 set_fs_pwd(current
->fs
, nd
.mnt
, nd
.dentry
);
364 asmlinkage
long sys_fchdir(unsigned int fd
)
367 struct dentry
*dentry
;
369 struct vfsmount
*mnt
;
377 dentry
= file
->f_dentry
;
378 mnt
= file
->f_vfsmnt
;
379 inode
= dentry
->d_inode
;
382 if (!S_ISDIR(inode
->i_mode
))
386 error
= permission(inode
, MAY_EXEC
);
388 set_fs_pwd(current
->fs
, mnt
, dentry
);
396 asmlinkage
long sys_chroot(const char * filename
)
404 name
= getname(filename
);
405 error
= PTR_ERR(name
);
409 path_init(name
, LOOKUP_POSITIVE
| LOOKUP_FOLLOW
|
410 LOOKUP_DIRECTORY
| LOOKUP_NOALT
, &nd
);
411 error
= path_walk(name
, &nd
);
416 error
= permission(nd
.dentry
->d_inode
,MAY_EXEC
);
421 if (!capable(CAP_SYS_CHROOT
))
424 set_fs_root(current
->fs
, nd
.mnt
, nd
.dentry
);
434 asmlinkage
long sys_fchmod(unsigned int fd
, mode_t mode
)
436 struct inode
* inode
;
437 struct dentry
* dentry
;
440 struct iattr newattrs
;
446 dentry
= file
->f_dentry
;
447 inode
= dentry
->d_inode
;
450 if (IS_RDONLY(inode
))
453 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
455 if (mode
== (mode_t
) -1)
456 mode
= inode
->i_mode
;
457 newattrs
.ia_mode
= (mode
& S_IALLUGO
) | (inode
->i_mode
& ~S_IALLUGO
);
458 newattrs
.ia_valid
= ATTR_MODE
| ATTR_CTIME
;
460 err
= notify_change(dentry
, &newattrs
);
469 asmlinkage
long sys_chmod(const char * filename
, mode_t mode
)
472 struct inode
* inode
;
474 struct iattr newattrs
;
476 error
= user_path_walk(filename
, &nd
);
479 inode
= nd
.dentry
->d_inode
;
482 if (IS_RDONLY(inode
))
486 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
489 if (mode
== (mode_t
) -1)
490 mode
= inode
->i_mode
;
491 newattrs
.ia_mode
= (mode
& S_IALLUGO
) | (inode
->i_mode
& ~S_IALLUGO
);
492 newattrs
.ia_valid
= ATTR_MODE
| ATTR_CTIME
;
493 error
= notify_change(nd
.dentry
, &newattrs
);
501 static int chown_common(struct dentry
* dentry
, uid_t user
, gid_t group
)
503 struct inode
* inode
;
505 struct iattr newattrs
;
508 if (!(inode
= dentry
->d_inode
)) {
509 printk("chown_common: NULL inode\n");
513 if (IS_RDONLY(inode
))
516 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
518 if (user
== (uid_t
) -1)
520 if (group
== (gid_t
) -1)
521 group
= inode
->i_gid
;
522 newattrs
.ia_mode
= inode
->i_mode
;
523 newattrs
.ia_uid
= user
;
524 newattrs
.ia_gid
= group
;
525 newattrs
.ia_valid
= ATTR_UID
| ATTR_GID
| ATTR_CTIME
;
527 * If the user or group of a non-directory has been changed by a
528 * non-root user, remove the setuid bit.
529 * 19981026 David C Niemi <niemi@tux.org>
531 * Changed this to apply to all users, including root, to avoid
532 * some races. This is the behavior we had in 2.0. The check for
533 * non-root was definitely wrong for 2.2 anyway, as it should
534 * have been using CAP_FSETID rather than fsuid -- 19990830 SD.
536 if ((inode
->i_mode
& S_ISUID
) == S_ISUID
&&
537 !S_ISDIR(inode
->i_mode
))
539 newattrs
.ia_mode
&= ~S_ISUID
;
540 newattrs
.ia_valid
|= ATTR_MODE
;
543 * Likewise, if the user or group of a non-directory has been changed
544 * by a non-root user, remove the setgid bit UNLESS there is no group
545 * execute bit (this would be a file marked for mandatory locking).
546 * 19981026 David C Niemi <niemi@tux.org>
548 * Removed the fsuid check (see the comment above) -- 19990830 SD.
550 if (((inode
->i_mode
& (S_ISGID
| S_IXGRP
)) == (S_ISGID
| S_IXGRP
))
551 && !S_ISDIR(inode
->i_mode
))
553 newattrs
.ia_mode
&= ~S_ISGID
;
554 newattrs
.ia_valid
|= ATTR_MODE
;
556 error
= DQUOT_TRANSFER(dentry
, &newattrs
);
561 asmlinkage
long sys_chown(const char * filename
, uid_t user
, gid_t group
)
566 error
= user_path_walk(filename
, &nd
);
568 error
= chown_common(nd
.dentry
, user
, group
);
574 asmlinkage
long sys_lchown(const char * filename
, uid_t user
, gid_t group
)
579 error
= user_path_walk_link(filename
, &nd
);
581 error
= chown_common(nd
.dentry
, user
, group
);
588 asmlinkage
long sys_fchown(unsigned int fd
, uid_t user
, gid_t group
)
595 error
= chown_common(file
->f_dentry
, user
, group
);
602 * Note that while the flag value (low two bits) for sys_open means:
608 * 00 - no permissions needed
609 * 01 - read-permission
610 * 10 - write-permission
612 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
615 struct file
*filp_open(const char * filename
, int flags
, int mode
)
617 int namei_flags
, error
;
621 if ((namei_flags
+1) & O_ACCMODE
)
623 if (namei_flags
& O_TRUNC
)
626 error
= open_namei(filename
, namei_flags
, mode
, &nd
);
628 return dentry_open(nd
.dentry
, nd
.mnt
, flags
);
630 return ERR_PTR(error
);
633 struct file
*dentry_open(struct dentry
*dentry
, struct vfsmount
*mnt
, int flags
)
640 f
= get_empty_filp();
644 f
->f_mode
= (flags
+1) & O_ACCMODE
;
645 inode
= dentry
->d_inode
;
646 if (f
->f_mode
& FMODE_WRITE
) {
647 error
= get_write_access(inode
);
652 f
->f_dentry
= dentry
;
656 f
->f_op
= inode
->i_fop
;
658 file_move(f
, &inode
->i_sb
->s_files
);
659 if (f
->f_op
&& f
->f_op
->open
) {
660 error
= f
->f_op
->open(inode
,f
);
664 f
->f_flags
&= ~(O_CREAT
| O_EXCL
| O_NOCTTY
| O_TRUNC
);
669 if (f
->f_mode
& FMODE_WRITE
)
670 put_write_access(inode
);
678 return ERR_PTR(error
);
682 * Find an empty file descriptor entry, and mark it busy.
684 int get_unused_fd(void)
686 struct files_struct
* files
= current
->files
;
690 write_lock(&files
->file_lock
);
693 fd
= find_next_zero_bit(files
->open_fds
,
694 current
->files
->max_fdset
,
698 * N.B. For clone tasks sharing a files structure, this test
699 * will limit the total number of files that can be opened.
701 if (fd
>= current
->rlim
[RLIMIT_NOFILE
].rlim_cur
)
704 /* Do we need to expand the fdset array? */
705 if (fd
>= current
->files
->max_fdset
) {
706 error
= expand_fdset(files
, fd
);
715 * Check whether we need to expand the fd array.
717 if (fd
>= files
->max_fds
) {
718 error
= expand_fd_array(files
, fd
);
726 FD_SET(fd
, files
->open_fds
);
727 FD_CLR(fd
, files
->close_on_exec
);
728 files
->next_fd
= fd
+ 1;
731 if (files
->fd
[fd
] != NULL
) {
732 printk("get_unused_fd: slot %d not NULL!\n", fd
);
733 files
->fd
[fd
] = NULL
;
739 write_unlock(&files
->file_lock
);
743 inline void __put_unused_fd(struct files_struct
*files
, unsigned int fd
)
745 FD_CLR(fd
, files
->open_fds
);
746 if (fd
< files
->next_fd
)
750 inline void put_unused_fd(unsigned int fd
)
752 struct files_struct
*files
= current
->files
;
754 write_lock(&files
->file_lock
);
755 __put_unused_fd(files
, fd
);
756 write_unlock(&files
->file_lock
);
759 asmlinkage
long sys_open(const char * filename
, int flags
, int mode
)
764 #if BITS_PER_LONG != 32
765 flags
|= O_LARGEFILE
;
767 tmp
= getname(filename
);
770 fd
= get_unused_fd();
774 f
= filp_open(tmp
, flags
, mode
);
795 * For backward compatibility? Maybe this should be moved
796 * into arch/i386 instead?
798 asmlinkage
long sys_creat(const char * pathname
, int mode
)
800 return sys_open(pathname
, O_CREAT
| O_WRONLY
| O_TRUNC
, mode
);
806 * "id" is the POSIX thread ID. We use the
807 * files pointer for this..
809 int filp_close(struct file
*filp
, fl_owner_t id
)
813 if (!file_count(filp
)) {
814 printk("VFS: Close: file count is 0\n");
818 if (filp
->f_op
&& filp
->f_op
->flush
)
819 retval
= filp
->f_op
->flush(filp
);
820 locks_remove_posix(filp
, id
);
826 * Careful here! We test whether the file pointer is NULL before
827 * releasing the fd. This ensures that one clone task can't release
828 * an fd while another clone is opening it.
830 * The "release" argument tells us whether or not to mark the fd as free
831 * or not in the open-files bitmap. dup2 uses this to retain the fd
834 int do_close(unsigned int fd
, int release
)
838 struct files_struct
* files
= current
->files
;
841 write_lock(&files
->file_lock
);
842 filp
= frip(files
, fd
);
845 FD_CLR(fd
, files
->close_on_exec
);
847 __put_unused_fd(files
, fd
);
848 write_unlock(&files
->file_lock
);
850 error
= filp_close(filp
, files
);
855 write_unlock(&files
->file_lock
);
859 asmlinkage
long sys_close(unsigned int fd
)
861 return do_close(fd
, 1);
865 * This routine simulates a hangup on the tty, to arrange that users
866 * are given clean terminals at login time.
868 asmlinkage
long sys_vhangup(void)
870 if (capable(CAP_SYS_TTY_CONFIG
)) {
871 tty_vhangup(current
->tty
);