diff options
Diffstat (limited to 'fs/xfs/xfs_iops.c')
-rw-r--r-- | fs/xfs/xfs_iops.c | 145 |
1 files changed, 65 insertions, 80 deletions
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 104455b8046c..9ddfb8190ca1 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -123,7 +123,7 @@ xfs_vn_mknod( | |||
123 | { | 123 | { |
124 | struct inode *inode; | 124 | struct inode *inode; |
125 | struct xfs_inode *ip = NULL; | 125 | struct xfs_inode *ip = NULL; |
126 | struct posix_acl *default_acl = NULL; | 126 | struct posix_acl *default_acl, *acl; |
127 | struct xfs_name name; | 127 | struct xfs_name name; |
128 | int error; | 128 | int error; |
129 | 129 | ||
@@ -139,14 +139,9 @@ xfs_vn_mknod( | |||
139 | rdev = 0; | 139 | rdev = 0; |
140 | } | 140 | } |
141 | 141 | ||
142 | if (IS_POSIXACL(dir)) { | 142 | error = posix_acl_create(dir, &mode, &default_acl, &acl); |
143 | default_acl = xfs_get_acl(dir, ACL_TYPE_DEFAULT); | 143 | if (error) |
144 | if (IS_ERR(default_acl)) | 144 | return error; |
145 | return PTR_ERR(default_acl); | ||
146 | |||
147 | if (!default_acl) | ||
148 | mode &= ~current_umask(); | ||
149 | } | ||
150 | 145 | ||
151 | xfs_dentry_to_name(&name, dentry, mode); | 146 | xfs_dentry_to_name(&name, dentry, mode); |
152 | error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip); | 147 | error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip); |
@@ -159,22 +154,30 @@ xfs_vn_mknod( | |||
159 | if (unlikely(error)) | 154 | if (unlikely(error)) |
160 | goto out_cleanup_inode; | 155 | goto out_cleanup_inode; |
161 | 156 | ||
157 | #ifdef CONFIG_XFS_POSIX_ACL | ||
162 | if (default_acl) { | 158 | if (default_acl) { |
163 | error = -xfs_inherit_acl(inode, default_acl); | 159 | error = xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); |
164 | default_acl = NULL; | 160 | if (error) |
165 | if (unlikely(error)) | ||
166 | goto out_cleanup_inode; | 161 | goto out_cleanup_inode; |
167 | } | 162 | } |
168 | 163 | if (acl) { | |
164 | error = xfs_set_acl(inode, acl, ACL_TYPE_ACCESS); | ||
165 | if (error) | ||
166 | goto out_cleanup_inode; | ||
167 | } | ||
168 | #endif | ||
169 | 169 | ||
170 | d_instantiate(dentry, inode); | 170 | d_instantiate(dentry, inode); |
171 | out_free_acl: | ||
172 | if (default_acl) | ||
173 | posix_acl_release(default_acl); | ||
174 | if (acl) | ||
175 | posix_acl_release(acl); | ||
171 | return -error; | 176 | return -error; |
172 | 177 | ||
173 | out_cleanup_inode: | 178 | out_cleanup_inode: |
174 | xfs_cleanup_inode(dir, inode, dentry); | 179 | xfs_cleanup_inode(dir, inode, dentry); |
175 | out_free_acl: | 180 | goto out_free_acl; |
176 | posix_acl_release(default_acl); | ||
177 | return -error; | ||
178 | } | 181 | } |
179 | 182 | ||
180 | STATIC int | 183 | STATIC int |
@@ -391,18 +394,6 @@ xfs_vn_follow_link( | |||
391 | return NULL; | 394 | return NULL; |
392 | } | 395 | } |
393 | 396 | ||
394 | STATIC void | ||
395 | xfs_vn_put_link( | ||
396 | struct dentry *dentry, | ||
397 | struct nameidata *nd, | ||
398 | void *p) | ||
399 | { | ||
400 | char *s = nd_get_link(nd); | ||
401 | |||
402 | if (!IS_ERR(s)) | ||
403 | kfree(s); | ||
404 | } | ||
405 | |||
406 | STATIC int | 397 | STATIC int |
407 | xfs_vn_getattr( | 398 | xfs_vn_getattr( |
408 | struct vfsmount *mnt, | 399 | struct vfsmount *mnt, |
@@ -459,14 +450,12 @@ xfs_vn_getattr( | |||
459 | 450 | ||
460 | static void | 451 | static void |
461 | xfs_setattr_mode( | 452 | xfs_setattr_mode( |
462 | struct xfs_trans *tp, | ||
463 | struct xfs_inode *ip, | 453 | struct xfs_inode *ip, |
464 | struct iattr *iattr) | 454 | struct iattr *iattr) |
465 | { | 455 | { |
466 | struct inode *inode = VFS_I(ip); | 456 | struct inode *inode = VFS_I(ip); |
467 | umode_t mode = iattr->ia_mode; | 457 | umode_t mode = iattr->ia_mode; |
468 | 458 | ||
469 | ASSERT(tp); | ||
470 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 459 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
471 | 460 | ||
472 | ip->i_d.di_mode &= S_IFMT; | 461 | ip->i_d.di_mode &= S_IFMT; |
@@ -476,6 +465,32 @@ xfs_setattr_mode( | |||
476 | inode->i_mode |= mode & ~S_IFMT; | 465 | inode->i_mode |= mode & ~S_IFMT; |
477 | } | 466 | } |
478 | 467 | ||
468 | static void | ||
469 | xfs_setattr_time( | ||
470 | struct xfs_inode *ip, | ||
471 | struct iattr *iattr) | ||
472 | { | ||
473 | struct inode *inode = VFS_I(ip); | ||
474 | |||
475 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | ||
476 | |||
477 | if (iattr->ia_valid & ATTR_ATIME) { | ||
478 | inode->i_atime = iattr->ia_atime; | ||
479 | ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; | ||
480 | ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec; | ||
481 | } | ||
482 | if (iattr->ia_valid & ATTR_CTIME) { | ||
483 | inode->i_ctime = iattr->ia_ctime; | ||
484 | ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; | ||
485 | ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec; | ||
486 | } | ||
487 | if (iattr->ia_valid & ATTR_MTIME) { | ||
488 | inode->i_mtime = iattr->ia_mtime; | ||
489 | ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; | ||
490 | ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; | ||
491 | } | ||
492 | } | ||
493 | |||
479 | int | 494 | int |
480 | xfs_setattr_nonsize( | 495 | xfs_setattr_nonsize( |
481 | struct xfs_inode *ip, | 496 | struct xfs_inode *ip, |
@@ -630,30 +645,10 @@ xfs_setattr_nonsize( | |||
630 | } | 645 | } |
631 | } | 646 | } |
632 | 647 | ||
633 | /* | ||
634 | * Change file access modes. | ||
635 | */ | ||
636 | if (mask & ATTR_MODE) | 648 | if (mask & ATTR_MODE) |
637 | xfs_setattr_mode(tp, ip, iattr); | 649 | xfs_setattr_mode(ip, iattr); |
638 | 650 | if (mask & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME)) | |
639 | /* | 651 | xfs_setattr_time(ip, iattr); |
640 | * Change file access or modified times. | ||
641 | */ | ||
642 | if (mask & ATTR_ATIME) { | ||
643 | inode->i_atime = iattr->ia_atime; | ||
644 | ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; | ||
645 | ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec; | ||
646 | } | ||
647 | if (mask & ATTR_CTIME) { | ||
648 | inode->i_ctime = iattr->ia_ctime; | ||
649 | ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; | ||
650 | ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec; | ||
651 | } | ||
652 | if (mask & ATTR_MTIME) { | ||
653 | inode->i_mtime = iattr->ia_mtime; | ||
654 | ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; | ||
655 | ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; | ||
656 | } | ||
657 | 652 | ||
658 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 653 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
659 | 654 | ||
@@ -684,7 +679,7 @@ xfs_setattr_nonsize( | |||
684 | * Posix ACL code seems to care about this issue either. | 679 | * Posix ACL code seems to care about this issue either. |
685 | */ | 680 | */ |
686 | if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { | 681 | if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { |
687 | error = -xfs_acl_chmod(inode); | 682 | error = -posix_acl_chmod(inode, inode->i_mode); |
688 | if (error) | 683 | if (error) |
689 | return XFS_ERROR(error); | 684 | return XFS_ERROR(error); |
690 | } | 685 | } |
@@ -710,7 +705,6 @@ xfs_setattr_size( | |||
710 | { | 705 | { |
711 | struct xfs_mount *mp = ip->i_mount; | 706 | struct xfs_mount *mp = ip->i_mount; |
712 | struct inode *inode = VFS_I(ip); | 707 | struct inode *inode = VFS_I(ip); |
713 | int mask = iattr->ia_valid; | ||
714 | xfs_off_t oldsize, newsize; | 708 | xfs_off_t oldsize, newsize; |
715 | struct xfs_trans *tp; | 709 | struct xfs_trans *tp; |
716 | int error; | 710 | int error; |
@@ -731,8 +725,8 @@ xfs_setattr_size( | |||
731 | 725 | ||
732 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); | 726 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); |
733 | ASSERT(S_ISREG(ip->i_d.di_mode)); | 727 | ASSERT(S_ISREG(ip->i_d.di_mode)); |
734 | ASSERT((mask & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| | 728 | ASSERT((iattr->ia_valid & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| |
735 | ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); | 729 | ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); |
736 | 730 | ||
737 | oldsize = inode->i_size; | 731 | oldsize = inode->i_size; |
738 | newsize = iattr->ia_size; | 732 | newsize = iattr->ia_size; |
@@ -741,7 +735,7 @@ xfs_setattr_size( | |||
741 | * Short circuit the truncate case for zero length files. | 735 | * Short circuit the truncate case for zero length files. |
742 | */ | 736 | */ |
743 | if (newsize == 0 && oldsize == 0 && ip->i_d.di_nextents == 0) { | 737 | if (newsize == 0 && oldsize == 0 && ip->i_d.di_nextents == 0) { |
744 | if (!(mask & (ATTR_CTIME|ATTR_MTIME))) | 738 | if (!(iattr->ia_valid & (ATTR_CTIME|ATTR_MTIME))) |
745 | return 0; | 739 | return 0; |
746 | 740 | ||
747 | /* | 741 | /* |
@@ -829,10 +823,11 @@ xfs_setattr_size( | |||
829 | * these flags set. For all other operations the VFS set these flags | 823 | * these flags set. For all other operations the VFS set these flags |
830 | * explicitly if it wants a timestamp update. | 824 | * explicitly if it wants a timestamp update. |
831 | */ | 825 | */ |
832 | if (newsize != oldsize && (!(mask & (ATTR_CTIME | ATTR_MTIME)))) { | 826 | if (newsize != oldsize && |
827 | !(iattr->ia_valid & (ATTR_CTIME | ATTR_MTIME))) { | ||
833 | iattr->ia_ctime = iattr->ia_mtime = | 828 | iattr->ia_ctime = iattr->ia_mtime = |
834 | current_fs_time(inode->i_sb); | 829 | current_fs_time(inode->i_sb); |
835 | mask |= ATTR_CTIME | ATTR_MTIME; | 830 | iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME; |
836 | } | 831 | } |
837 | 832 | ||
838 | /* | 833 | /* |
@@ -868,22 +863,10 @@ xfs_setattr_size( | |||
868 | xfs_inode_clear_eofblocks_tag(ip); | 863 | xfs_inode_clear_eofblocks_tag(ip); |
869 | } | 864 | } |
870 | 865 | ||
871 | /* | 866 | if (iattr->ia_valid & ATTR_MODE) |
872 | * Change file access modes. | 867 | xfs_setattr_mode(ip, iattr); |
873 | */ | 868 | if (iattr->ia_valid & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME)) |
874 | if (mask & ATTR_MODE) | 869 | xfs_setattr_time(ip, iattr); |
875 | xfs_setattr_mode(tp, ip, iattr); | ||
876 | |||
877 | if (mask & ATTR_CTIME) { | ||
878 | inode->i_ctime = iattr->ia_ctime; | ||
879 | ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; | ||
880 | ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec; | ||
881 | } | ||
882 | if (mask & ATTR_MTIME) { | ||
883 | inode->i_mtime = iattr->ia_mtime; | ||
884 | ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; | ||
885 | ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; | ||
886 | } | ||
887 | 870 | ||
888 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 871 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
889 | 872 | ||
@@ -1053,6 +1036,7 @@ xfs_vn_fiemap( | |||
1053 | 1036 | ||
1054 | static const struct inode_operations xfs_inode_operations = { | 1037 | static const struct inode_operations xfs_inode_operations = { |
1055 | .get_acl = xfs_get_acl, | 1038 | .get_acl = xfs_get_acl, |
1039 | .set_acl = xfs_set_acl, | ||
1056 | .getattr = xfs_vn_getattr, | 1040 | .getattr = xfs_vn_getattr, |
1057 | .setattr = xfs_vn_setattr, | 1041 | .setattr = xfs_vn_setattr, |
1058 | .setxattr = generic_setxattr, | 1042 | .setxattr = generic_setxattr, |
@@ -1080,6 +1064,7 @@ static const struct inode_operations xfs_dir_inode_operations = { | |||
1080 | .mknod = xfs_vn_mknod, | 1064 | .mknod = xfs_vn_mknod, |
1081 | .rename = xfs_vn_rename, | 1065 | .rename = xfs_vn_rename, |
1082 | .get_acl = xfs_get_acl, | 1066 | .get_acl = xfs_get_acl, |
1067 | .set_acl = xfs_set_acl, | ||
1083 | .getattr = xfs_vn_getattr, | 1068 | .getattr = xfs_vn_getattr, |
1084 | .setattr = xfs_vn_setattr, | 1069 | .setattr = xfs_vn_setattr, |
1085 | .setxattr = generic_setxattr, | 1070 | .setxattr = generic_setxattr, |
@@ -1106,6 +1091,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { | |||
1106 | .mknod = xfs_vn_mknod, | 1091 | .mknod = xfs_vn_mknod, |
1107 | .rename = xfs_vn_rename, | 1092 | .rename = xfs_vn_rename, |
1108 | .get_acl = xfs_get_acl, | 1093 | .get_acl = xfs_get_acl, |
1094 | .set_acl = xfs_set_acl, | ||
1109 | .getattr = xfs_vn_getattr, | 1095 | .getattr = xfs_vn_getattr, |
1110 | .setattr = xfs_vn_setattr, | 1096 | .setattr = xfs_vn_setattr, |
1111 | .setxattr = generic_setxattr, | 1097 | .setxattr = generic_setxattr, |
@@ -1118,8 +1104,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { | |||
1118 | static const struct inode_operations xfs_symlink_inode_operations = { | 1104 | static const struct inode_operations xfs_symlink_inode_operations = { |
1119 | .readlink = generic_readlink, | 1105 | .readlink = generic_readlink, |
1120 | .follow_link = xfs_vn_follow_link, | 1106 | .follow_link = xfs_vn_follow_link, |
1121 | .put_link = xfs_vn_put_link, | 1107 | .put_link = kfree_put_link, |
1122 | .get_acl = xfs_get_acl, | ||
1123 | .getattr = xfs_vn_getattr, | 1108 | .getattr = xfs_vn_getattr, |
1124 | .setattr = xfs_vn_setattr, | 1109 | .setattr = xfs_vn_setattr, |
1125 | .setxattr = generic_setxattr, | 1110 | .setxattr = generic_setxattr, |