aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_iops.c')
-rw-r--r--fs/xfs/xfs_iops.c145
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
180STATIC int 183STATIC int
@@ -391,18 +394,6 @@ xfs_vn_follow_link(
391 return NULL; 394 return NULL;
392} 395}
393 396
394STATIC void
395xfs_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
406STATIC int 397STATIC int
407xfs_vn_getattr( 398xfs_vn_getattr(
408 struct vfsmount *mnt, 399 struct vfsmount *mnt,
@@ -459,14 +450,12 @@ xfs_vn_getattr(
459 450
460static void 451static void
461xfs_setattr_mode( 452xfs_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
468static void
469xfs_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
479int 494int
480xfs_setattr_nonsize( 495xfs_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
1054static const struct inode_operations xfs_inode_operations = { 1037static 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 = {
1118static const struct inode_operations xfs_symlink_inode_operations = { 1104static 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,