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>
13 #include <linux/module.h>
14 #include <linux/slab.h>
16 #include <asm/uaccess.h>
18 int vfs_statfs(struct super_block
*sb
, struct statfs
*buf
)
24 if (sb
->s_op
&& sb
->s_op
->statfs
) {
25 memset(buf
, 0, sizeof(struct statfs
));
27 retval
= sb
->s_op
->statfs(sb
, buf
);
35 asmlinkage
long sys_statfs(const char * path
, struct statfs
* buf
)
40 error
= user_path_walk(path
, &nd
);
43 error
= vfs_statfs(nd
.dentry
->d_inode
->i_sb
, &tmp
);
44 if (!error
&& copy_to_user(buf
, &tmp
, sizeof(struct statfs
)))
51 asmlinkage
long sys_fstatfs(unsigned int fd
, struct statfs
* buf
)
61 error
= vfs_statfs(file
->f_dentry
->d_inode
->i_sb
, &tmp
);
62 if (!error
&& copy_to_user(buf
, &tmp
, sizeof(struct statfs
)))
69 int do_truncate(struct dentry
*dentry
, loff_t length
)
71 struct inode
*inode
= dentry
->d_inode
;
73 struct iattr newattrs
;
75 /* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
80 newattrs
.ia_size
= length
;
81 newattrs
.ia_valid
= ATTR_SIZE
| ATTR_CTIME
;
82 error
= notify_change(dentry
, &newattrs
);
87 static inline long do_sys_truncate(const char * path
, loff_t length
)
94 if (length
< 0) /* sorry, but loff_t says... */
97 error
= user_path_walk(path
, &nd
);
100 inode
= nd
.dentry
->d_inode
;
103 if (S_ISDIR(inode
->i_mode
))
106 error
= permission(inode
,MAY_WRITE
);
111 if (IS_RDONLY(inode
))
115 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
118 error
= get_write_access(inode
);
122 error
= locks_verify_truncate(inode
, NULL
, length
);
125 error
= do_truncate(nd
.dentry
, length
);
127 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
))
163 error
= locks_verify_truncate(inode
, file
, length
);
165 error
= do_truncate(dentry
, length
);
172 asmlinkage
long sys_ftruncate(unsigned int fd
, unsigned long length
)
174 return do_sys_ftruncate(fd
, length
);
177 /* LFS versions of truncate are only needed on 32 bit machines */
178 #if BITS_PER_LONG == 32
179 asmlinkage
long sys_truncate64(const char * path
, loff_t length
)
181 return do_sys_truncate(path
, length
);
184 asmlinkage
long sys_ftruncate64(unsigned int fd
, loff_t length
)
186 return do_sys_ftruncate(fd
, length
);
190 #if !(defined(__alpha__) || defined(__ia64__))
193 * sys_utime() can be implemented in user-level using sys_utimes().
194 * Is this for backwards compatibility? If so, why not move it
195 * into the appropriate arch directory (for those architectures that
199 /* If times==NULL, set access and modification to current time,
200 * must be owner or have write permission.
201 * Else, update from *times, must be owner or super user.
203 asmlinkage
long sys_utime(char * filename
, struct utimbuf
* times
)
207 struct inode
* inode
;
208 struct iattr newattrs
;
210 error
= user_path_walk(filename
, &nd
);
213 inode
= nd
.dentry
->d_inode
;
216 if (IS_RDONLY(inode
))
219 /* Don't worry, the checks are done in inode_change_ok() */
220 newattrs
.ia_valid
= ATTR_CTIME
| ATTR_MTIME
| ATTR_ATIME
;
222 error
= get_user(newattrs
.ia_atime
, ×
->actime
);
224 error
= get_user(newattrs
.ia_mtime
, ×
->modtime
);
228 newattrs
.ia_valid
|= ATTR_ATIME_SET
| ATTR_MTIME_SET
;
230 if (current
->fsuid
!= inode
->i_uid
&&
231 (error
= permission(inode
,MAY_WRITE
)) != 0)
234 error
= notify_change(nd
.dentry
, &newattrs
);
243 /* If times==NULL, set access and modification to current time,
244 * must be owner or have write permission.
245 * Else, update from *times, must be owner or super user.
247 asmlinkage
long sys_utimes(char * filename
, struct timeval
* utimes
)
251 struct inode
* inode
;
252 struct iattr newattrs
;
254 error
= user_path_walk(filename
, &nd
);
258 inode
= nd
.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(nd
.dentry
, &newattrs
);
286 * access() needs to use the real uid/gid, not the effective uid/gid.
287 * We do this by temporarily clearing all FS-related capabilities and
288 * switching the fsuid/fsgid around to the real ones.
290 asmlinkage
long sys_access(const char * filename
, int mode
)
293 int old_fsuid
, old_fsgid
;
294 kernel_cap_t old_cap
;
297 if (mode
& ~S_IRWXO
) /* where's F_OK, X_OK, W_OK, R_OK? */
300 old_fsuid
= current
->fsuid
;
301 old_fsgid
= current
->fsgid
;
302 old_cap
= current
->cap_effective
;
304 current
->fsuid
= current
->uid
;
305 current
->fsgid
= current
->gid
;
307 /* Clear the capabilities if we switch to a non-root user */
309 cap_clear(current
->cap_effective
);
311 current
->cap_effective
= current
->cap_permitted
;
313 res
= user_path_walk(filename
, &nd
);
315 res
= permission(nd
.dentry
->d_inode
, mode
);
316 /* SuS v2 requires we report a read only fs too */
317 if(!res
&& (mode
& S_IWOTH
) && IS_RDONLY(nd
.dentry
->d_inode
))
322 current
->fsuid
= old_fsuid
;
323 current
->fsgid
= old_fsgid
;
324 current
->cap_effective
= old_cap
;
329 asmlinkage
long sys_chdir(const char * filename
)
335 name
= getname(filename
);
336 error
= PTR_ERR(name
);
341 if (path_init(name
,LOOKUP_POSITIVE
|LOOKUP_FOLLOW
|LOOKUP_DIRECTORY
,&nd
))
342 error
= path_walk(name
, &nd
);
347 error
= permission(nd
.dentry
->d_inode
,MAY_EXEC
);
351 set_fs_pwd(current
->fs
, nd
.mnt
, nd
.dentry
);
359 asmlinkage
long sys_fchdir(unsigned int fd
)
362 struct dentry
*dentry
;
364 struct vfsmount
*mnt
;
372 dentry
= file
->f_dentry
;
373 mnt
= file
->f_vfsmnt
;
374 inode
= dentry
->d_inode
;
377 if (!S_ISDIR(inode
->i_mode
))
380 error
= permission(inode
, MAY_EXEC
);
382 set_fs_pwd(current
->fs
, mnt
, dentry
);
389 asmlinkage
long sys_chroot(const char * filename
)
395 name
= getname(filename
);
396 error
= PTR_ERR(name
);
400 path_init(name
, LOOKUP_POSITIVE
| LOOKUP_FOLLOW
|
401 LOOKUP_DIRECTORY
| LOOKUP_NOALT
, &nd
);
402 error
= path_walk(name
, &nd
);
407 error
= permission(nd
.dentry
->d_inode
,MAY_EXEC
);
412 if (!capable(CAP_SYS_CHROOT
))
415 set_fs_root(current
->fs
, nd
.mnt
, nd
.dentry
);
424 asmlinkage
long sys_fchmod(unsigned int fd
, mode_t mode
)
426 struct inode
* inode
;
427 struct dentry
* dentry
;
430 struct iattr newattrs
;
436 dentry
= file
->f_dentry
;
437 inode
= dentry
->d_inode
;
440 if (IS_RDONLY(inode
))
443 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
445 if (mode
== (mode_t
) -1)
446 mode
= inode
->i_mode
;
447 newattrs
.ia_mode
= (mode
& S_IALLUGO
) | (inode
->i_mode
& ~S_IALLUGO
);
448 newattrs
.ia_valid
= ATTR_MODE
| ATTR_CTIME
;
449 err
= notify_change(dentry
, &newattrs
);
457 asmlinkage
long sys_chmod(const char * filename
, mode_t mode
)
460 struct inode
* inode
;
462 struct iattr newattrs
;
464 error
= user_path_walk(filename
, &nd
);
467 inode
= nd
.dentry
->d_inode
;
470 if (IS_RDONLY(inode
))
474 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
477 if (mode
== (mode_t
) -1)
478 mode
= inode
->i_mode
;
479 newattrs
.ia_mode
= (mode
& S_IALLUGO
) | (inode
->i_mode
& ~S_IALLUGO
);
480 newattrs
.ia_valid
= ATTR_MODE
| ATTR_CTIME
;
481 error
= notify_change(nd
.dentry
, &newattrs
);
489 static int chown_common(struct dentry
* dentry
, uid_t user
, gid_t group
)
491 struct inode
* inode
;
493 struct iattr newattrs
;
496 if (!(inode
= dentry
->d_inode
)) {
497 printk("chown_common: NULL inode\n");
501 if (IS_RDONLY(inode
))
504 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
506 if (user
== (uid_t
) -1)
508 if (group
== (gid_t
) -1)
509 group
= inode
->i_gid
;
510 newattrs
.ia_mode
= inode
->i_mode
;
511 newattrs
.ia_uid
= user
;
512 newattrs
.ia_gid
= group
;
513 newattrs
.ia_valid
= ATTR_UID
| ATTR_GID
| ATTR_CTIME
;
515 * If the user or group of a non-directory has been changed by a
516 * non-root user, remove the setuid bit.
517 * 19981026 David C Niemi <niemi@tux.org>
519 * Changed this to apply to all users, including root, to avoid
520 * some races. This is the behavior we had in 2.0. The check for
521 * non-root was definitely wrong for 2.2 anyway, as it should
522 * have been using CAP_FSETID rather than fsuid -- 19990830 SD.
524 if ((inode
->i_mode
& S_ISUID
) == S_ISUID
&&
525 !S_ISDIR(inode
->i_mode
))
527 newattrs
.ia_mode
&= ~S_ISUID
;
528 newattrs
.ia_valid
|= ATTR_MODE
;
531 * Likewise, if the user or group of a non-directory has been changed
532 * by a non-root user, remove the setgid bit UNLESS there is no group
533 * execute bit (this would be a file marked for mandatory locking).
534 * 19981026 David C Niemi <niemi@tux.org>
536 * Removed the fsuid check (see the comment above) -- 19990830 SD.
538 if (((inode
->i_mode
& (S_ISGID
| S_IXGRP
)) == (S_ISGID
| S_IXGRP
))
539 && !S_ISDIR(inode
->i_mode
))
541 newattrs
.ia_mode
&= ~S_ISGID
;
542 newattrs
.ia_valid
|= ATTR_MODE
;
544 error
= DQUOT_TRANSFER(dentry
, &newattrs
);
549 asmlinkage
long sys_chown(const char * filename
, uid_t user
, gid_t group
)
554 error
= user_path_walk(filename
, &nd
);
556 error
= chown_common(nd
.dentry
, user
, group
);
562 asmlinkage
long sys_lchown(const char * filename
, uid_t user
, gid_t group
)
567 error
= user_path_walk_link(filename
, &nd
);
569 error
= chown_common(nd
.dentry
, user
, group
);
576 asmlinkage
long sys_fchown(unsigned int fd
, uid_t user
, gid_t group
)
583 error
= chown_common(file
->f_dentry
, user
, group
);
590 * Note that while the flag value (low two bits) for sys_open means:
596 * 00 - no permissions needed
597 * 01 - read-permission
598 * 10 - write-permission
600 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
603 struct file
*filp_open(const char * filename
, int flags
, int mode
)
605 int namei_flags
, error
;
609 if ((namei_flags
+1) & O_ACCMODE
)
611 if (namei_flags
& O_TRUNC
)
614 error
= open_namei(filename
, namei_flags
, mode
, &nd
);
616 return dentry_open(nd
.dentry
, nd
.mnt
, flags
);
618 return ERR_PTR(error
);
621 struct file
*dentry_open(struct dentry
*dentry
, struct vfsmount
*mnt
, int flags
)
628 f
= get_empty_filp();
632 f
->f_mode
= (flags
+1) & O_ACCMODE
;
633 inode
= dentry
->d_inode
;
634 if (f
->f_mode
& FMODE_WRITE
) {
635 error
= get_write_access(inode
);
640 f
->f_dentry
= dentry
;
644 f
->f_op
= fops_get(inode
->i_fop
);
646 file_move(f
, &inode
->i_sb
->s_files
);
647 if (f
->f_op
&& f
->f_op
->open
) {
648 error
= f
->f_op
->open(inode
,f
);
652 f
->f_flags
&= ~(O_CREAT
| O_EXCL
| O_NOCTTY
| O_TRUNC
);
658 if (f
->f_mode
& FMODE_WRITE
)
659 put_write_access(inode
);
667 return ERR_PTR(error
);
671 * Find an empty file descriptor entry, and mark it busy.
673 int get_unused_fd(void)
675 struct files_struct
* files
= current
->files
;
679 write_lock(&files
->file_lock
);
682 fd
= find_next_zero_bit(files
->open_fds
,
683 current
->files
->max_fdset
,
687 * N.B. For clone tasks sharing a files structure, this test
688 * will limit the total number of files that can be opened.
690 if (fd
>= current
->rlim
[RLIMIT_NOFILE
].rlim_cur
)
693 /* Do we need to expand the fdset array? */
694 if (fd
>= current
->files
->max_fdset
) {
695 error
= expand_fdset(files
, fd
);
704 * Check whether we need to expand the fd array.
706 if (fd
>= files
->max_fds
) {
707 error
= expand_fd_array(files
, fd
);
715 FD_SET(fd
, files
->open_fds
);
716 FD_CLR(fd
, files
->close_on_exec
);
717 files
->next_fd
= fd
+ 1;
720 if (files
->fd
[fd
] != NULL
) {
721 printk("get_unused_fd: slot %d not NULL!\n", fd
);
722 files
->fd
[fd
] = NULL
;
728 write_unlock(&files
->file_lock
);
732 asmlinkage
long sys_open(const char * filename
, int flags
, int mode
)
737 #if BITS_PER_LONG != 32
738 flags
|= O_LARGEFILE
;
740 tmp
= getname(filename
);
743 fd
= get_unused_fd();
745 struct file
*f
= filp_open(tmp
, flags
, mode
);
765 * For backward compatibility? Maybe this should be moved
766 * into arch/i386 instead?
768 asmlinkage
long sys_creat(const char * pathname
, int mode
)
770 return sys_open(pathname
, O_CREAT
| O_WRONLY
| O_TRUNC
, mode
);
776 * "id" is the POSIX thread ID. We use the
777 * files pointer for this..
779 int filp_close(struct file
*filp
, fl_owner_t id
)
783 if (!file_count(filp
)) {
784 printk("VFS: Close: file count is 0\n");
788 if (filp
->f_op
&& filp
->f_op
->flush
) {
790 retval
= filp
->f_op
->flush(filp
);
793 locks_remove_posix(filp
, id
);
799 * Careful here! We test whether the file pointer is NULL before
800 * releasing the fd. This ensures that one clone task can't release
801 * an fd while another clone is opening it.
803 * The "release" argument tells us whether or not to mark the fd as free
804 * or not in the open-files bitmap. dup2 uses this to retain the fd
807 int do_close(struct files_struct
*files
, unsigned int fd
, int release
)
813 write_lock(&files
->file_lock
);
814 filp
= frip(files
, fd
);
817 FD_CLR(fd
, files
->close_on_exec
);
819 __put_unused_fd(files
, fd
);
820 write_unlock(&files
->file_lock
);
821 error
= filp_close(filp
, files
);
825 write_unlock(&files
->file_lock
);
829 asmlinkage
long sys_close(unsigned int fd
)
831 return do_close(current
->files
, fd
, 1);
835 * This routine simulates a hangup on the tty, to arrange that users
836 * are given clean terminals at login time.
838 asmlinkage
long sys_vhangup(void)
840 if (capable(CAP_SYS_TTY_CONFIG
)) {
841 tty_vhangup(current
->tty
);