diff options
Diffstat (limited to 'fs/open.c')
| -rw-r--r-- | fs/open.c | 123 |
1 files changed, 89 insertions, 34 deletions
| @@ -16,9 +16,11 @@ | |||
| 16 | #include <linux/tty.h> | 16 | #include <linux/tty.h> |
| 17 | #include <linux/namei.h> | 17 | #include <linux/namei.h> |
| 18 | #include <linux/backing-dev.h> | 18 | #include <linux/backing-dev.h> |
| 19 | #include <linux/capability.h> | ||
| 19 | #include <linux/security.h> | 20 | #include <linux/security.h> |
| 20 | #include <linux/mount.h> | 21 | #include <linux/mount.h> |
| 21 | #include <linux/vfs.h> | 22 | #include <linux/vfs.h> |
| 23 | #include <linux/fcntl.h> | ||
| 22 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
| 23 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
| 24 | #include <linux/personality.h> | 26 | #include <linux/personality.h> |
| @@ -194,7 +196,8 @@ out: | |||
| 194 | return error; | 196 | return error; |
| 195 | } | 197 | } |
| 196 | 198 | ||
| 197 | int do_truncate(struct dentry *dentry, loff_t length, struct file *filp) | 199 | int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, |
| 200 | struct file *filp) | ||
| 198 | { | 201 | { |
| 199 | int err; | 202 | int err; |
| 200 | struct iattr newattrs; | 203 | struct iattr newattrs; |
| @@ -204,19 +207,19 @@ int do_truncate(struct dentry *dentry, loff_t length, struct file *filp) | |||
| 204 | return -EINVAL; | 207 | return -EINVAL; |
| 205 | 208 | ||
| 206 | newattrs.ia_size = length; | 209 | newattrs.ia_size = length; |
| 207 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; | 210 | newattrs.ia_valid = ATTR_SIZE | time_attrs; |
| 208 | if (filp) { | 211 | if (filp) { |
| 209 | newattrs.ia_file = filp; | 212 | newattrs.ia_file = filp; |
| 210 | newattrs.ia_valid |= ATTR_FILE; | 213 | newattrs.ia_valid |= ATTR_FILE; |
| 211 | } | 214 | } |
| 212 | 215 | ||
| 213 | down(&dentry->d_inode->i_sem); | 216 | mutex_lock(&dentry->d_inode->i_mutex); |
| 214 | err = notify_change(dentry, &newattrs); | 217 | err = notify_change(dentry, &newattrs); |
| 215 | up(&dentry->d_inode->i_sem); | 218 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 216 | return err; | 219 | return err; |
| 217 | } | 220 | } |
| 218 | 221 | ||
| 219 | static inline long do_sys_truncate(const char __user * path, loff_t length) | 222 | static long do_sys_truncate(const char __user * path, loff_t length) |
| 220 | { | 223 | { |
| 221 | struct nameidata nd; | 224 | struct nameidata nd; |
| 222 | struct inode * inode; | 225 | struct inode * inode; |
| @@ -266,7 +269,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length) | |||
| 266 | error = locks_verify_truncate(inode, NULL, length); | 269 | error = locks_verify_truncate(inode, NULL, length); |
| 267 | if (!error) { | 270 | if (!error) { |
| 268 | DQUOT_INIT(inode); | 271 | DQUOT_INIT(inode); |
| 269 | error = do_truncate(nd.dentry, length, NULL); | 272 | error = do_truncate(nd.dentry, length, 0, NULL); |
| 270 | } | 273 | } |
| 271 | put_write_access(inode); | 274 | put_write_access(inode); |
| 272 | 275 | ||
| @@ -282,7 +285,7 @@ asmlinkage long sys_truncate(const char __user * path, unsigned long length) | |||
| 282 | return do_sys_truncate(path, (long)length); | 285 | return do_sys_truncate(path, (long)length); |
| 283 | } | 286 | } |
| 284 | 287 | ||
| 285 | static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small) | 288 | static long do_sys_ftruncate(unsigned int fd, loff_t length, int small) |
| 286 | { | 289 | { |
| 287 | struct inode * inode; | 290 | struct inode * inode; |
| 288 | struct dentry *dentry; | 291 | struct dentry *dentry; |
| @@ -318,7 +321,7 @@ static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small) | |||
| 318 | 321 | ||
| 319 | error = locks_verify_truncate(inode, file, length); | 322 | error = locks_verify_truncate(inode, file, length); |
| 320 | if (!error) | 323 | if (!error) |
| 321 | error = do_truncate(dentry, length, file); | 324 | error = do_truncate(dentry, length, 0, file); |
| 322 | out_putf: | 325 | out_putf: |
| 323 | fput(file); | 326 | fput(file); |
| 324 | out: | 327 | out: |
| @@ -381,7 +384,7 @@ asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times) | |||
| 381 | 384 | ||
| 382 | error = get_user(newattrs.ia_atime.tv_sec, ×->actime); | 385 | error = get_user(newattrs.ia_atime.tv_sec, ×->actime); |
| 383 | newattrs.ia_atime.tv_nsec = 0; | 386 | newattrs.ia_atime.tv_nsec = 0; |
| 384 | if (!error) | 387 | if (!error) |
| 385 | error = get_user(newattrs.ia_mtime.tv_sec, ×->modtime); | 388 | error = get_user(newattrs.ia_mtime.tv_sec, ×->modtime); |
| 386 | newattrs.ia_mtime.tv_nsec = 0; | 389 | newattrs.ia_mtime.tv_nsec = 0; |
| 387 | if (error) | 390 | if (error) |
| @@ -397,9 +400,9 @@ asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times) | |||
| 397 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) | 400 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) |
| 398 | goto dput_and_out; | 401 | goto dput_and_out; |
| 399 | } | 402 | } |
| 400 | down(&inode->i_sem); | 403 | mutex_lock(&inode->i_mutex); |
| 401 | error = notify_change(nd.dentry, &newattrs); | 404 | error = notify_change(nd.dentry, &newattrs); |
| 402 | up(&inode->i_sem); | 405 | mutex_unlock(&inode->i_mutex); |
| 403 | dput_and_out: | 406 | dput_and_out: |
| 404 | path_release(&nd); | 407 | path_release(&nd); |
| 405 | out: | 408 | out: |
| @@ -412,14 +415,14 @@ out: | |||
| 412 | * must be owner or have write permission. | 415 | * must be owner or have write permission. |
| 413 | * Else, update from *times, must be owner or super user. | 416 | * Else, update from *times, must be owner or super user. |
| 414 | */ | 417 | */ |
| 415 | long do_utimes(char __user * filename, struct timeval * times) | 418 | long do_utimes(int dfd, char __user *filename, struct timeval *times) |
| 416 | { | 419 | { |
| 417 | int error; | 420 | int error; |
| 418 | struct nameidata nd; | 421 | struct nameidata nd; |
| 419 | struct inode * inode; | 422 | struct inode * inode; |
| 420 | struct iattr newattrs; | 423 | struct iattr newattrs; |
| 421 | 424 | ||
| 422 | error = user_path_walk(filename, &nd); | 425 | error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); |
| 423 | 426 | ||
| 424 | if (error) | 427 | if (error) |
| 425 | goto out; | 428 | goto out; |
| @@ -450,22 +453,27 @@ long do_utimes(char __user * filename, struct timeval * times) | |||
| 450 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) | 453 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) |
| 451 | goto dput_and_out; | 454 | goto dput_and_out; |
| 452 | } | 455 | } |
| 453 | down(&inode->i_sem); | 456 | mutex_lock(&inode->i_mutex); |
| 454 | error = notify_change(nd.dentry, &newattrs); | 457 | error = notify_change(nd.dentry, &newattrs); |
| 455 | up(&inode->i_sem); | 458 | mutex_unlock(&inode->i_mutex); |
| 456 | dput_and_out: | 459 | dput_and_out: |
| 457 | path_release(&nd); | 460 | path_release(&nd); |
| 458 | out: | 461 | out: |
| 459 | return error; | 462 | return error; |
| 460 | } | 463 | } |
| 461 | 464 | ||
| 462 | asmlinkage long sys_utimes(char __user * filename, struct timeval __user * utimes) | 465 | asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes) |
| 463 | { | 466 | { |
| 464 | struct timeval times[2]; | 467 | struct timeval times[2]; |
| 465 | 468 | ||
| 466 | if (utimes && copy_from_user(×, utimes, sizeof(times))) | 469 | if (utimes && copy_from_user(×, utimes, sizeof(times))) |
| 467 | return -EFAULT; | 470 | return -EFAULT; |
| 468 | return do_utimes(filename, utimes ? times : NULL); | 471 | return do_utimes(dfd, filename, utimes ? times : NULL); |
| 472 | } | ||
| 473 | |||
| 474 | asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes) | ||
| 475 | { | ||
| 476 | return sys_futimesat(AT_FDCWD, filename, utimes); | ||
| 469 | } | 477 | } |
| 470 | 478 | ||
| 471 | 479 | ||
| @@ -474,7 +482,7 @@ asmlinkage long sys_utimes(char __user * filename, struct timeval __user * utime | |||
| 474 | * We do this by temporarily clearing all FS-related capabilities and | 482 | * We do this by temporarily clearing all FS-related capabilities and |
| 475 | * switching the fsuid/fsgid around to the real ones. | 483 | * switching the fsuid/fsgid around to the real ones. |
| 476 | */ | 484 | */ |
| 477 | asmlinkage long sys_access(const char __user * filename, int mode) | 485 | asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) |
| 478 | { | 486 | { |
| 479 | struct nameidata nd; | 487 | struct nameidata nd; |
| 480 | int old_fsuid, old_fsgid; | 488 | int old_fsuid, old_fsgid; |
| @@ -504,7 +512,7 @@ asmlinkage long sys_access(const char __user * filename, int mode) | |||
| 504 | else | 512 | else |
| 505 | current->cap_effective = current->cap_permitted; | 513 | current->cap_effective = current->cap_permitted; |
| 506 | 514 | ||
| 507 | res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); | 515 | res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); |
| 508 | if (!res) { | 516 | if (!res) { |
| 509 | res = vfs_permission(&nd, mode); | 517 | res = vfs_permission(&nd, mode); |
| 510 | /* SuS v2 requires we report a read only fs too */ | 518 | /* SuS v2 requires we report a read only fs too */ |
| @@ -521,6 +529,11 @@ asmlinkage long sys_access(const char __user * filename, int mode) | |||
| 521 | return res; | 529 | return res; |
| 522 | } | 530 | } |
| 523 | 531 | ||
| 532 | asmlinkage long sys_access(const char __user *filename, int mode) | ||
| 533 | { | ||
| 534 | return sys_faccessat(AT_FDCWD, filename, mode); | ||
| 535 | } | ||
| 536 | |||
| 524 | asmlinkage long sys_chdir(const char __user * filename) | 537 | asmlinkage long sys_chdir(const char __user * filename) |
| 525 | { | 538 | { |
| 526 | struct nameidata nd; | 539 | struct nameidata nd; |
| @@ -619,13 +632,13 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) | |||
| 619 | err = -EPERM; | 632 | err = -EPERM; |
| 620 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 633 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
| 621 | goto out_putf; | 634 | goto out_putf; |
| 622 | down(&inode->i_sem); | 635 | mutex_lock(&inode->i_mutex); |
| 623 | if (mode == (mode_t) -1) | 636 | if (mode == (mode_t) -1) |
| 624 | mode = inode->i_mode; | 637 | mode = inode->i_mode; |
| 625 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); | 638 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); |
| 626 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; | 639 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
| 627 | err = notify_change(dentry, &newattrs); | 640 | err = notify_change(dentry, &newattrs); |
| 628 | up(&inode->i_sem); | 641 | mutex_unlock(&inode->i_mutex); |
| 629 | 642 | ||
| 630 | out_putf: | 643 | out_putf: |
| 631 | fput(file); | 644 | fput(file); |
| @@ -633,14 +646,15 @@ out: | |||
| 633 | return err; | 646 | return err; |
| 634 | } | 647 | } |
| 635 | 648 | ||
| 636 | asmlinkage long sys_chmod(const char __user * filename, mode_t mode) | 649 | asmlinkage long sys_fchmodat(int dfd, const char __user *filename, |
| 650 | mode_t mode) | ||
| 637 | { | 651 | { |
| 638 | struct nameidata nd; | 652 | struct nameidata nd; |
| 639 | struct inode * inode; | 653 | struct inode * inode; |
| 640 | int error; | 654 | int error; |
| 641 | struct iattr newattrs; | 655 | struct iattr newattrs; |
| 642 | 656 | ||
| 643 | error = user_path_walk(filename, &nd); | 657 | error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); |
| 644 | if (error) | 658 | if (error) |
| 645 | goto out; | 659 | goto out; |
| 646 | inode = nd.dentry->d_inode; | 660 | inode = nd.dentry->d_inode; |
| @@ -653,13 +667,13 @@ asmlinkage long sys_chmod(const char __user * filename, mode_t mode) | |||
| 653 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 667 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
| 654 | goto dput_and_out; | 668 | goto dput_and_out; |
| 655 | 669 | ||
| 656 | down(&inode->i_sem); | 670 | mutex_lock(&inode->i_mutex); |
| 657 | if (mode == (mode_t) -1) | 671 | if (mode == (mode_t) -1) |
| 658 | mode = inode->i_mode; | 672 | mode = inode->i_mode; |
| 659 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); | 673 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); |
| 660 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; | 674 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
| 661 | error = notify_change(nd.dentry, &newattrs); | 675 | error = notify_change(nd.dentry, &newattrs); |
| 662 | up(&inode->i_sem); | 676 | mutex_unlock(&inode->i_mutex); |
| 663 | 677 | ||
| 664 | dput_and_out: | 678 | dput_and_out: |
| 665 | path_release(&nd); | 679 | path_release(&nd); |
| @@ -667,6 +681,11 @@ out: | |||
| 667 | return error; | 681 | return error; |
| 668 | } | 682 | } |
| 669 | 683 | ||
| 684 | asmlinkage long sys_chmod(const char __user *filename, mode_t mode) | ||
| 685 | { | ||
| 686 | return sys_fchmodat(AT_FDCWD, filename, mode); | ||
| 687 | } | ||
| 688 | |||
| 670 | static int chown_common(struct dentry * dentry, uid_t user, gid_t group) | 689 | static int chown_common(struct dentry * dentry, uid_t user, gid_t group) |
| 671 | { | 690 | { |
| 672 | struct inode * inode; | 691 | struct inode * inode; |
| @@ -695,9 +714,9 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group) | |||
| 695 | } | 714 | } |
| 696 | if (!S_ISDIR(inode->i_mode)) | 715 | if (!S_ISDIR(inode->i_mode)) |
| 697 | newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID; | 716 | newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID; |
| 698 | down(&inode->i_sem); | 717 | mutex_lock(&inode->i_mutex); |
| 699 | error = notify_change(dentry, &newattrs); | 718 | error = notify_change(dentry, &newattrs); |
| 700 | up(&inode->i_sem); | 719 | mutex_unlock(&inode->i_mutex); |
| 701 | out: | 720 | out: |
| 702 | return error; | 721 | return error; |
| 703 | } | 722 | } |
| @@ -715,6 +734,26 @@ asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group) | |||
| 715 | return error; | 734 | return error; |
| 716 | } | 735 | } |
| 717 | 736 | ||
| 737 | asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, | ||
| 738 | gid_t group, int flag) | ||
| 739 | { | ||
| 740 | struct nameidata nd; | ||
| 741 | int error = -EINVAL; | ||
| 742 | int follow; | ||
| 743 | |||
| 744 | if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) | ||
| 745 | goto out; | ||
| 746 | |||
| 747 | follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; | ||
| 748 | error = __user_walk_fd(dfd, filename, follow, &nd); | ||
| 749 | if (!error) { | ||
| 750 | error = chown_common(nd.dentry, user, group); | ||
| 751 | path_release(&nd); | ||
| 752 | } | ||
| 753 | out: | ||
| 754 | return error; | ||
| 755 | } | ||
| 756 | |||
| 718 | asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group) | 757 | asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group) |
| 719 | { | 758 | { |
| 720 | struct nameidata nd; | 759 | struct nameidata nd; |
| @@ -818,7 +857,8 @@ cleanup_file: | |||
| 818 | * for the internal routines (ie open_namei()/follow_link() etc). 00 is | 857 | * for the internal routines (ie open_namei()/follow_link() etc). 00 is |
| 819 | * used by symlinks. | 858 | * used by symlinks. |
| 820 | */ | 859 | */ |
| 821 | struct file *filp_open(const char * filename, int flags, int mode) | 860 | static struct file *do_filp_open(int dfd, const char *filename, int flags, |
| 861 | int mode) | ||
| 822 | { | 862 | { |
| 823 | int namei_flags, error; | 863 | int namei_flags, error; |
| 824 | struct nameidata nd; | 864 | struct nameidata nd; |
| @@ -827,12 +867,17 @@ struct file *filp_open(const char * filename, int flags, int mode) | |||
| 827 | if ((namei_flags+1) & O_ACCMODE) | 867 | if ((namei_flags+1) & O_ACCMODE) |
| 828 | namei_flags++; | 868 | namei_flags++; |
| 829 | 869 | ||
| 830 | error = open_namei(filename, namei_flags, mode, &nd); | 870 | error = open_namei(dfd, filename, namei_flags, mode, &nd); |
| 831 | if (!error) | 871 | if (!error) |
| 832 | return nameidata_to_filp(&nd, flags); | 872 | return nameidata_to_filp(&nd, flags); |
| 833 | 873 | ||
| 834 | return ERR_PTR(error); | 874 | return ERR_PTR(error); |
| 835 | } | 875 | } |
| 876 | |||
| 877 | struct file *filp_open(const char *filename, int flags, int mode) | ||
| 878 | { | ||
| 879 | return do_filp_open(AT_FDCWD, filename, flags, mode); | ||
| 880 | } | ||
| 836 | EXPORT_SYMBOL(filp_open); | 881 | EXPORT_SYMBOL(filp_open); |
| 837 | 882 | ||
| 838 | /** | 883 | /** |
| @@ -970,7 +1015,7 @@ out: | |||
| 970 | 1015 | ||
| 971 | EXPORT_SYMBOL(get_unused_fd); | 1016 | EXPORT_SYMBOL(get_unused_fd); |
| 972 | 1017 | ||
| 973 | static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) | 1018 | static void __put_unused_fd(struct files_struct *files, unsigned int fd) |
| 974 | { | 1019 | { |
| 975 | struct fdtable *fdt = files_fdtable(files); | 1020 | struct fdtable *fdt = files_fdtable(files); |
| 976 | __FD_CLR(fd, fdt->open_fds); | 1021 | __FD_CLR(fd, fdt->open_fds); |
| @@ -989,7 +1034,7 @@ void fastcall put_unused_fd(unsigned int fd) | |||
| 989 | EXPORT_SYMBOL(put_unused_fd); | 1034 | EXPORT_SYMBOL(put_unused_fd); |
| 990 | 1035 | ||
| 991 | /* | 1036 | /* |
| 992 | * Install a file pointer in the fd array. | 1037 | * Install a file pointer in the fd array. |
| 993 | * | 1038 | * |
| 994 | * The VFS is full of places where we drop the files lock between | 1039 | * The VFS is full of places where we drop the files lock between |
| 995 | * setting the open_fds bitmap and installing the file in the file | 1040 | * setting the open_fds bitmap and installing the file in the file |
| @@ -1014,7 +1059,7 @@ void fastcall fd_install(unsigned int fd, struct file * file) | |||
| 1014 | 1059 | ||
| 1015 | EXPORT_SYMBOL(fd_install); | 1060 | EXPORT_SYMBOL(fd_install); |
| 1016 | 1061 | ||
| 1017 | long do_sys_open(const char __user *filename, int flags, int mode) | 1062 | long do_sys_open(int dfd, const char __user *filename, int flags, int mode) |
| 1018 | { | 1063 | { |
| 1019 | char *tmp = getname(filename); | 1064 | char *tmp = getname(filename); |
| 1020 | int fd = PTR_ERR(tmp); | 1065 | int fd = PTR_ERR(tmp); |
| @@ -1022,7 +1067,7 @@ long do_sys_open(const char __user *filename, int flags, int mode) | |||
| 1022 | if (!IS_ERR(tmp)) { | 1067 | if (!IS_ERR(tmp)) { |
| 1023 | fd = get_unused_fd(); | 1068 | fd = get_unused_fd(); |
| 1024 | if (fd >= 0) { | 1069 | if (fd >= 0) { |
| 1025 | struct file *f = filp_open(tmp, flags, mode); | 1070 | struct file *f = do_filp_open(dfd, tmp, flags, mode); |
| 1026 | if (IS_ERR(f)) { | 1071 | if (IS_ERR(f)) { |
| 1027 | put_unused_fd(fd); | 1072 | put_unused_fd(fd); |
| 1028 | fd = PTR_ERR(f); | 1073 | fd = PTR_ERR(f); |
| @@ -1041,10 +1086,20 @@ asmlinkage long sys_open(const char __user *filename, int flags, int mode) | |||
| 1041 | if (force_o_largefile()) | 1086 | if (force_o_largefile()) |
| 1042 | flags |= O_LARGEFILE; | 1087 | flags |= O_LARGEFILE; |
| 1043 | 1088 | ||
| 1044 | return do_sys_open(filename, flags, mode); | 1089 | return do_sys_open(AT_FDCWD, filename, flags, mode); |
| 1045 | } | 1090 | } |
| 1046 | EXPORT_SYMBOL_GPL(sys_open); | 1091 | EXPORT_SYMBOL_GPL(sys_open); |
| 1047 | 1092 | ||
| 1093 | asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, | ||
| 1094 | int mode) | ||
| 1095 | { | ||
| 1096 | if (force_o_largefile()) | ||
| 1097 | flags |= O_LARGEFILE; | ||
| 1098 | |||
| 1099 | return do_sys_open(dfd, filename, flags, mode); | ||
| 1100 | } | ||
| 1101 | EXPORT_SYMBOL_GPL(sys_openat); | ||
| 1102 | |||
| 1048 | #ifndef __alpha__ | 1103 | #ifndef __alpha__ |
| 1049 | 1104 | ||
| 1050 | /* | 1105 | /* |
