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/iobuf.h> 18 19 #include <asm/uaccess.h> 20 21 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) 22 23 int vfs_statfs(struct super_block *sb, struct statfs *buf) 24 { 25 int retval = -ENODEV; 26 27 if (sb) { 28 retval = -ENOSYS; 29 if (sb->s_op && sb->s_op->statfs) { 30 memset(buf, 0, sizeof(struct statfs)); 31 lock_kernel(); 32 retval = sb->s_op->statfs(sb, buf); 33 unlock_kernel(); 34 } 35 } 36 return retval; 37 } 38 39 40 asmlinkage long sys_statfs(const char * path, struct statfs * buf) 41 { 42 struct nameidata nd; 43 int error; 44 45 error = user_path_walk(path, &nd); 46 if (!error) { 47 struct statfs tmp; 48 error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); 49 if (!error && copy_to_user(buf, &tmp, sizeof(struct statfs))) 50 error = -EFAULT; 51 path_release(&nd); 52 } 53 return error; 54 } 55 56 asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf) 57 { 58 struct file * file; 59 struct statfs tmp; 60 int error; 61 62 error = -EBADF; 63 file = fget(fd); 64 if (!file) 65 goto out; 66 error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp); 67 if (!error && copy_to_user(buf, &tmp, sizeof(struct statfs))) 68 error = -EFAULT; 69 fput(file); 70 out: 71 return error; 72 } 73 74 int do_truncate(struct dentry *dentry, loff_t length) 75 { 76 struct inode *inode = dentry->d_inode; 77 int error; 78 struct iattr newattrs; 79 80 /* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */ 81 if (length < 0) 82 return -EINVAL; 83 84 down(&inode->i_sem); 85 newattrs.ia_size = length; 86 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; 87 error = notify_change(dentry, &newattrs); 88 up(&inode->i_sem); 89 return error; 90 } 91 92 static inline long do_sys_truncate(const char * path, loff_t length) 93 { 94 struct nameidata nd; 95 struct inode * inode; 96 int error; 97 98 error = -EINVAL; 99 if (length < 0) /* sorry, but loff_t says... */ 100 goto out; 101 102 error = user_path_walk(path, &nd); 103 if (error) 104 goto out; 105 inode = nd.dentry->d_inode; 106 107 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */ 108 error = -EISDIR; 109 if (S_ISDIR(inode->i_mode)) 110 goto dput_and_out; 111 112 error = -EINVAL; 113 if (!S_ISREG(inode->i_mode)) 114 goto dput_and_out; 115 116 error = permission(inode,MAY_WRITE); 117 if (error) 118 goto dput_and_out; 119 120 error = -EROFS; 121 if (IS_RDONLY(inode)) 122 goto dput_and_out; 123 124 error = -EPERM; 125 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) 126 goto dput_and_out; 127 128 /* 129 * Make sure that there are no leases. 130 */ 131 error = get_lease(inode, FMODE_WRITE); 132 if (error) 133 goto dput_and_out; 134 135 error = get_write_access(inode); 136 if (error) 137 goto dput_and_out; 138 139 error = locks_verify_truncate(inode, NULL, length); 140 if (!error) { 141 DQUOT_INIT(inode); 142 error = do_truncate(nd.dentry, length); 143 } 144 put_write_access(inode); 145 146 dput_and_out: 147 path_release(&nd); 148 out: 149 return error; 150 } 151 152 asmlinkage long sys_truncate(const char * path, unsigned long length) 153 { 154 /* on 32-bit boxen it will cut the range 2^31--2^32-1 off */ 155 return do_sys_truncate(path, (long)length); 156 } 157 158 static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small) 159 { 160 struct inode * inode; 161 struct dentry *dentry; 162 struct file * file; 163 int error; 164 165 error = -EINVAL; 166 if (length < 0) 167 goto out; 168 error = -EBADF; 169 file = fget(fd); 170 if (!file) 171 goto out; 172 173 /* explicitly opened as large or we are on 64-bit box */ 174 if (file->f_flags & O_LARGEFILE) 175 small = 0; 176 177 dentry = file->f_dentry; 178 inode = dentry->d_inode; 179 error = -EINVAL; 180 if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE)) 181 goto out_putf; 182 183 error = -EINVAL; 184 /* Cannot ftruncate over 2^31 bytes without large file support */ 185 if (small && length > MAX_NON_LFS) 186 goto out_putf; 187 188 error = -EPERM; 189 if (IS_APPEND(inode)) 190 goto out_putf; 191 192 error = locks_verify_truncate(inode, file, length); 193 if (!error) 194 error = do_truncate(dentry, length); 195 out_putf: 196 fput(file); 197 out: 198 return error; 199 } 200 201 asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length) 202 { 203 return do_sys_ftruncate(fd, length, 1); 204 } 205 206 /* LFS versions of truncate are only needed on 32 bit machines */ 207 #if BITS_PER_LONG == 32 208 asmlinkage long sys_truncate64(const char * path, loff_t length) 209 { 210 return do_sys_truncate(path, length); 211 } 212 213 asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) 214 { 215 return do_sys_ftruncate(fd, length, 0); 216 } 217 #endif 218 219 #if !(defined(__alpha__) || defined(__ia64__)) 220 221 /* 222 * sys_utime() can be implemented in user-level using sys_utimes(). 223 * Is this for backwards compatibility? If so, why not move it 224 * into the appropriate arch directory (for those architectures that 225 * need it). 226 */ 227 228 /* If times==NULL, set access and modification to current time, 229 * must be owner or have write permission. 230 * Else, update from *times, must be owner or super user. 231 */ 232 asmlinkage long sys_utime(char * filename, struct utimbuf * times) 233 { 234 int error; 235 struct nameidata nd; 236 struct inode * inode; 237 struct iattr newattrs; 238 239 error = user_path_walk(filename, &nd); 240 if (error) 241 goto out; 242 inode = nd.dentry->d_inode; 243 244 error = -EROFS; 245 if (IS_RDONLY(inode)) 246 goto dput_and_out; 247 248 /* Don't worry, the checks are done in inode_change_ok() */ 249 newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; 250 if (times) { 251 error = get_user(newattrs.ia_atime, ×->actime); 252 if (!error) 253 error = get_user(newattrs.ia_mtime, ×->modtime); 254 if (error) 255 goto dput_and_out; 256 257 newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; 258 } else { 259 if (current->fsuid != inode->i_uid && 260 (error = permission(inode,MAY_WRITE)) != 0) 261 goto dput_and_out; 262 } 263 error = notify_change(nd.dentry, &newattrs); 264 dput_and_out: 265 path_release(&nd); 266 out: 267 return error; 268 } 269 270 #endif 271 272 /* If times==NULL, set access and modification to current time, 273 * must be owner or have write permission. 274 * Else, update from *times, must be owner or super user. 275 */ 276 asmlinkage long sys_utimes(char * filename, struct timeval * utimes) 277 { 278 int error; 279 struct nameidata nd; 280 struct inode * inode; 281 struct iattr newattrs; 282 283 error = user_path_walk(filename, &nd); 284 285 if (error) 286 goto out; 287 inode = nd.dentry->d_inode; 288 289 error = -EROFS; 290 if (IS_RDONLY(inode)) 291 goto dput_and_out; 292 293 /* Don't worry, the checks are done in inode_change_ok() */ 294 newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; 295 if (utimes) { 296 struct timeval times[2]; 297 error = -EFAULT; 298 if (copy_from_user(×, utimes, sizeof(times))) 299 goto dput_and_out; 300 newattrs.ia_atime = times[0].tv_sec; 301 newattrs.ia_mtime = times[1].tv_sec; 302 newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; 303 } else { 304 if ((error = permission(inode,MAY_WRITE)) != 0) 305 goto dput_and_out; 306 } 307 error = notify_change(nd.dentry, &newattrs); 308 dput_and_out: 309 path_release(&nd); 310 out: 311 return error; 312 } 313 314 /* 315 * access() needs to use the real uid/gid, not the effective uid/gid. 316 * We do this by temporarily clearing all FS-related capabilities and 317 * switching the fsuid/fsgid around to the real ones. 318 */ 319 asmlinkage long sys_access(const char * filename, int mode) 320 { 321 struct nameidata nd; 322 int old_fsuid, old_fsgid; 323 kernel_cap_t old_cap; 324 int res; 325 326 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ 327 return -EINVAL; 328 329 old_fsuid = current->fsuid; 330 old_fsgid = current->fsgid; 331 old_cap = current->cap_effective; 332 333 current->fsuid = current->uid; 334 current->fsgid = current->gid; 335 336 /* Clear the capabilities if we switch to a non-root user */ 337 if (current->uid) 338 cap_clear(current->cap_effective); 339 else 340 current->cap_effective = current->cap_permitted; 341 342 res = user_path_walk(filename, &nd); 343 if (!res) { 344 res = permission(nd.dentry->d_inode, mode); 345 /* SuS v2 requires we report a read only fs too */ 346 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) 347 && !special_file(nd.dentry->d_inode->i_mode)) 348 res = -EROFS; 349 path_release(&nd); 350 } 351 352 current->fsuid = old_fsuid; 353 current->fsgid = old_fsgid; 354 current->cap_effective = old_cap; 355 356 return res; 357 } 358 359 asmlinkage long sys_chdir(const char * filename) 360 { 361 int error; 362 struct nameidata nd; 363 char *name; 364 365 name = getname(filename); 366 error = PTR_ERR(name); 367 if (IS_ERR(name)) 368 goto out; 369 370 error = 0; 371 if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd)) 372 error = path_walk(name, &nd); 373 putname(name); 374 if (error) 375 goto out; 376 377 error = permission(nd.dentry->d_inode,MAY_EXEC); 378 if (error) 379 goto dput_and_out; 380 381 set_fs_pwd(current->fs, nd.mnt, nd.dentry); 382 383 dput_and_out: 384 path_release(&nd); 385 out: 386 return error; 387 } 388 389 asmlinkage long sys_fchdir(unsigned int fd) 390 { 391 struct file *file; 392 struct dentry *dentry; 393 struct inode *inode; 394 struct vfsmount *mnt; 395 int error; 396 397 error = -EBADF; 398 file = fget(fd); 399 if (!file) 400 goto out; 401 402 dentry = file->f_dentry; 403 mnt = file->f_vfsmnt; 404 inode = dentry->d_inode; 405 406 error = -ENOTDIR; 407 if (!S_ISDIR(inode->i_mode)) 408 goto out_putf; 409 410 error = permission(inode, MAY_EXEC); 411 if (!error) 412 set_fs_pwd(current->fs, mnt, dentry); 413 out_putf: 414 fput(file); 415 out: 416 return error; 417 } 418 419 asmlinkage long sys_chroot(const char * filename) 420 { 421 int error; 422 struct nameidata nd; 423 char *name; 424 425 name = getname(filename); 426 error = PTR_ERR(name); 427 if (IS_ERR(name)) 428 goto out; 429 430 path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW | 431 LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); 432 error = path_walk(name, &nd); 433 putname(name); 434 if (error) 435 goto out; 436 437 error = permission(nd.dentry->d_inode,MAY_EXEC); 438 if (error) 439 goto dput_and_out; 440 441 error = -EPERM; 442 if (!capable(CAP_SYS_CHROOT)) 443 goto dput_and_out; 444 445 set_fs_root(current->fs, nd.mnt, nd.dentry); 446 set_fs_altroot(); 447 error = 0; 448 dput_and_out: 449 path_release(&nd); 450 out: 451 return error; 452 } 453 454 asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) 455 { 456 struct inode * inode; 457 struct dentry * dentry; 458 struct file * file; 459 int err = -EBADF; 460 struct iattr newattrs; 461 462 file = fget(fd); 463 if (!file) 464 goto out; 465 466 dentry = file->f_dentry; 467 inode = dentry->d_inode; 468 469 err = -EROFS; 470 if (IS_RDONLY(inode)) 471 goto out_putf; 472 err = -EPERM; 473 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) 474 goto out_putf; 475 if (mode == (mode_t) -1) 476 mode = inode->i_mode; 477 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); 478 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; 479 err = notify_change(dentry, &newattrs); 480 481 out_putf: 482 fput(file); 483 out: 484 return err; 485 } 486 487 asmlinkage long sys_chmod(const char * filename, mode_t mode) 488 { 489 struct nameidata nd; 490 struct inode * inode; 491 int error; 492 struct iattr newattrs; 493 494 error = user_path_walk(filename, &nd); 495 if (error) 496 goto out; 497 inode = nd.dentry->d_inode; 498 499 error = -EROFS; 500 if (IS_RDONLY(inode)) 501 goto dput_and_out; 502 503 error = -EPERM; 504 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) 505 goto dput_and_out; 506 507 if (mode == (mode_t) -1) 508 mode = inode->i_mode; 509 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); 510 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; 511 error = notify_change(nd.dentry, &newattrs); 512 513 dput_and_out: 514 path_release(&nd); 515 out: 516 return error; 517 } 518 519 static int chown_common(struct dentry * dentry, uid_t user, gid_t group) 520 { 521 struct inode * inode; 522 int error; 523 struct iattr newattrs; 524 525 error = -ENOENT; 526 if (!(inode = dentry->d_inode)) { 527 printk(KERN_ERR "chown_common: NULL inode\n"); 528 goto out; 529 } 530 error = -EROFS; 531 if (IS_RDONLY(inode)) 532 goto out; 533 error = -EPERM; 534 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) 535 goto out; 536 if (user == (uid_t) -1) 537 user = inode->i_uid; 538 if (group == (gid_t) -1) 539 group = inode->i_gid; 540 newattrs.ia_mode = inode->i_mode; 541 newattrs.ia_uid = user; 542 newattrs.ia_gid = group; 543 newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME; 544 /* 545 * If the user or group of a non-directory has been changed by a 546 * non-root user, remove the setuid bit. 547 * 19981026 David C Niemi <niemi@tux.org> 548 * 549 * Changed this to apply to all users, including root, to avoid 550 * some races. This is the behavior we had in 2.0. The check for 551 * non-root was definitely wrong for 2.2 anyway, as it should 552 * have been using CAP_FSETID rather than fsuid -- 19990830 SD. 553 */ 554 if ((inode->i_mode & S_ISUID) == S_ISUID && 555 !S_ISDIR(inode->i_mode)) 556 { 557 newattrs.ia_mode &= ~S_ISUID; 558 newattrs.ia_valid |= ATTR_MODE; 559 } 560 /* 561 * Likewise, if the user or group of a non-directory has been changed 562 * by a non-root user, remove the setgid bit UNLESS there is no group 563 * execute bit (this would be a file marked for mandatory locking). 564 * 19981026 David C Niemi <niemi@tux.org> 565 * 566 * Removed the fsuid check (see the comment above) -- 19990830 SD. 567 */ 568 if (((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) 569 && !S_ISDIR(inode->i_mode)) 570 { 571 newattrs.ia_mode &= ~S_ISGID; 572 newattrs.ia_valid |= ATTR_MODE; 573 } 574 error = notify_change(dentry, &newattrs); 575 out: 576 return error; 577 } 578 579 asmlinkage long sys_chown(const char * filename, uid_t user, gid_t group) 580 { 581 struct nameidata nd; 582 int error; 583 584 error = user_path_walk(filename, &nd); 585 if (!error) { 586 error = chown_common(nd.dentry, user, group); 587 path_release(&nd); 588 } 589 return error; 590 } 591 592 asmlinkage long sys_lchown(const char * filename, uid_t user, gid_t group) 593 { 594 struct nameidata nd; 595 int error; 596 597 error = user_path_walk_link(filename, &nd); 598 if (!error) { 599 error = chown_common(nd.dentry, user, group); 600 path_release(&nd); 601 } 602 return error; 603 } 604 605 606 asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group) 607 { 608 struct file * file; 609 int error = -EBADF; 610 611 file = fget(fd); 612 if (file) { 613 error = chown_common(file->f_dentry, user, group); 614 fput(file); 615 } 616 return error; 617 } 618 619 /* 620 * Note that while the flag value (low two bits) for sys_open means: 621 * 00 - read-only 622 * 01 - write-only 623 * 10 - read-write 624 * 11 - special 625 * it is changed into 626 * 00 - no permissions needed 627 * 01 - read-permission 628 * 10 - write-permission 629 * 11 - read-write 630 * for the internal routines (ie open_namei()/follow_link() etc). 00 is 631 * used by symlinks. 632 */ 633 struct file *filp_open(const char * filename, int flags, int mode) 634 { 635 int namei_flags, error; 636 struct nameidata nd; 637 638 namei_flags = flags; 639 if ((namei_flags+1) & O_ACCMODE) 640 namei_flags++; 641 if (namei_flags & O_TRUNC) 642 namei_flags |= 2; 643 644 error = open_namei(filename, namei_flags, mode, &nd); 645 if (!error) 646 return dentry_open(nd.dentry, nd.mnt, flags); 647 648 return ERR_PTR(error); 649 } 650 651 struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) 652 { 653 struct file * f; 654 struct inode *inode; 655 static LIST_HEAD(kill_list); 656 int error; 657 658 error = -ENFILE; 659 f = get_empty_filp(); 660 if (!f) 661 goto cleanup_dentry; 662 f->f_flags = flags; 663 f->f_mode = (flags+1) & O_ACCMODE; 664 inode = dentry->d_inode; 665 if (f->f_mode & FMODE_WRITE) { 666 error = get_write_access(inode); 667 if (error) 668 goto cleanup_file; 669 } 670 671 f->f_dentry = dentry; 672 f->f_vfsmnt = mnt; 673 f->f_pos = 0; 674 f->f_reada = 0; 675 f->f_op = fops_get(inode->i_fop); 676 file_move(f, &inode->i_sb->s_files); 677 678 /* preallocate kiobuf for O_DIRECT */ 679 f->f_iobuf = NULL; 680 f->f_iobuf_lock = 0; 681 if (f->f_flags & O_DIRECT) { 682 error = alloc_kiovec(1, &f->f_iobuf); 683 if (error) 684 goto cleanup_all; 685 } 686 687 if (f->f_op && f->f_op->open) { 688 error = f->f_op->open(inode,f); 689 if (error) 690 goto cleanup_all; 691 } 692 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); 693 694 return f; 695 696 cleanup_all: 697 if (f->f_iobuf) 698 free_kiovec(1, &f->f_iobuf); 699 fops_put(f->f_op); 700 if (f->f_mode & FMODE_WRITE) 701 put_write_access(inode); 702 file_move(f, &kill_list); /* out of the way.. */ 703 f->f_dentry = NULL; 704 f->f_vfsmnt = NULL; 705 cleanup_file: 706 put_filp(f); 707 cleanup_dentry: 708 dput(dentry); 709 mntput(mnt); 710 return ERR_PTR(error); 711 } 712 713 /* 714 * Find an empty file descriptor entry, and mark it busy. 715 */ 716 int get_unused_fd(void) 717 { 718 struct files_struct * files = current->files; 719 int fd, error; 720 721 error = -EMFILE; 722 write_lock(&files->file_lock); 723 724 repeat: 725 fd = find_next_zero_bit(files->open_fds, 726 files->max_fdset, 727 files->next_fd); 728 729 /* 730 * N.B. For clone tasks sharing a files structure, this test 731 * will limit the total number of files that can be opened. 732 */ 733 if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur) 734 goto out; 735 736 /* Do we need to expand the fdset array? */ 737 if (fd >= files->max_fdset) { 738 error = expand_fdset(files, fd); 739 if (!error) { 740 error = -EMFILE; 741 goto repeat; 742 } 743 goto out; 744 } 745 746 /* 747 * Check whether we need to expand the fd array. 748 */ 749 if (fd >= files->max_fds) { 750 error = expand_fd_array(files, fd); 751 if (!error) { 752 error = -EMFILE; 753 goto repeat; 754 } 755 goto out; 756 } 757 758 FD_SET(fd, files->open_fds); 759 FD_CLR(fd, files->close_on_exec); 760 files->next_fd = fd + 1; 761 #if 1 762 /* Sanity check */ 763 if (files->fd[fd] != NULL) { 764 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); 765 files->fd[fd] = NULL; 766 } 767 #endif 768 error = fd; 769 770 out: 771 write_unlock(&files->file_lock); 772 return error; 773 } 774 775 asmlinkage long sys_open(const char * filename, int flags, int mode) 776 { 777 char * tmp; 778 int fd, error; 779 780 #if BITS_PER_LONG != 32 781 flags |= O_LARGEFILE; 782 #endif 783 tmp = getname(filename); 784 fd = PTR_ERR(tmp); 785 if (!IS_ERR(tmp)) { 786 fd = get_unused_fd(); 787 if (fd >= 0) { 788 struct file *f = filp_open(tmp, flags, mode); 789 error = PTR_ERR(f); 790 if (IS_ERR(f)) 791 goto out_error; 792 fd_install(fd, f); 793 } 794 out: 795 putname(tmp); 796 } 797 return fd; 798 799 out_error: 800 put_unused_fd(fd); 801 fd = error; 802 goto out; 803 } 804 805 #ifndef __alpha__ 806 807 /* 808 * For backward compatibility? Maybe this should be moved 809 * into arch/i386 instead? 810 */ 811 asmlinkage long sys_creat(const char * pathname, int mode) 812 { 813 return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); 814 } 815 816 #endif 817 818 /* 819 * "id" is the POSIX thread ID. We use the 820 * files pointer for this.. 821 */ 822 int filp_close(struct file *filp, fl_owner_t id) 823 { 824 int retval; 825 826 if (!file_count(filp)) { 827 printk(KERN_ERR "VFS: Close: file count is 0\n"); 828 return 0; 829 } 830 retval = 0; 831 if (filp->f_op && filp->f_op->flush) { 832 lock_kernel(); 833 retval = filp->f_op->flush(filp); 834 unlock_kernel(); 835 } 836 fcntl_dirnotify(0, filp, 0); 837 locks_remove_posix(filp, id); 838 fput(filp); 839 return retval; 840 } 841 842 /* 843 * Careful here! We test whether the file pointer is NULL before 844 * releasing the fd. This ensures that one clone task can't release 845 * an fd while another clone is opening it. 846 */ 847 asmlinkage long sys_close(unsigned int fd) 848 { 849 struct file * filp; 850 struct files_struct *files = current->files; 851 852 write_lock(&files->file_lock); 853 if (fd >= files->max_fds) 854 goto out_unlock; 855 filp = files->fd[fd]; 856 if (!filp) 857 goto out_unlock; 858 files->fd[fd] = NULL; 859 FD_CLR(fd, files->close_on_exec); 860 __put_unused_fd(files, fd); 861 write_unlock(&files->file_lock); 862 return filp_close(filp, files); 863 864 out_unlock: 865 write_unlock(&files->file_lock); 866 return -EBADF; 867 } 868 869 /* 870 * This routine simulates a hangup on the tty, to arrange that users 871 * are given clean terminals at login time. 872 */ 873 asmlinkage long sys_vhangup(void) 874 { 875 if (capable(CAP_SYS_TTY_CONFIG)) { 876 tty_vhangup(current->tty); 877 return 0; 878 } 879 return -EPERM; 880 } 881 882 /* 883 * Called when an inode is about to be open. 884 * We use this to disallow opening RW large files on 32bit systems if 885 * the caller didn't specify O_LARGEFILE. On 64bit systems we force 886 * on this flag in sys_open. 887 */ 888 int generic_file_open(struct inode * inode, struct file * filp) 889 { 890 if (!(filp->f_flags & O_LARGEFILE) && inode->i_size > MAX_NON_LFS) 891 return -EFBIG; 892 return 0; 893 } 894 895 EXPORT_SYMBOL(generic_file_open); 896