diff options
Diffstat (limited to 'fs/jfs/xattr.c')
-rw-r--r-- | fs/jfs/xattr.c | 94 |
1 files changed, 77 insertions, 17 deletions
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 554ec739e49b..23aa5066b5a4 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/xattr.h> | 21 | #include <linux/xattr.h> |
22 | #include <linux/posix_acl_xattr.h> | 22 | #include <linux/posix_acl_xattr.h> |
23 | #include <linux/quotaops.h> | 23 | #include <linux/quotaops.h> |
24 | #include <linux/security.h> | ||
24 | #include "jfs_incore.h" | 25 | #include "jfs_incore.h" |
25 | #include "jfs_superblock.h" | 26 | #include "jfs_superblock.h" |
26 | #include "jfs_dmap.h" | 27 | #include "jfs_dmap.h" |
@@ -633,12 +634,12 @@ static void ea_release(struct inode *inode, struct ea_buffer *ea_buf) | |||
633 | } | 634 | } |
634 | } | 635 | } |
635 | 636 | ||
636 | static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) | 637 | static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf, |
638 | int new_size) | ||
637 | { | 639 | { |
638 | struct jfs_inode_info *ji = JFS_IP(inode); | 640 | struct jfs_inode_info *ji = JFS_IP(inode); |
639 | unsigned long old_blocks, new_blocks; | 641 | unsigned long old_blocks, new_blocks; |
640 | int rc = 0; | 642 | int rc = 0; |
641 | tid_t tid; | ||
642 | 643 | ||
643 | if (new_size == 0) { | 644 | if (new_size == 0) { |
644 | ea_release(inode, ea_buf); | 645 | ea_release(inode, ea_buf); |
@@ -664,9 +665,6 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) | |||
664 | if (rc) | 665 | if (rc) |
665 | return rc; | 666 | return rc; |
666 | 667 | ||
667 | tid = txBegin(inode->i_sb, 0); | ||
668 | down(&ji->commit_sem); | ||
669 | |||
670 | old_blocks = new_blocks = 0; | 668 | old_blocks = new_blocks = 0; |
671 | 669 | ||
672 | if (ji->ea.flag & DXD_EXTENT) { | 670 | if (ji->ea.flag & DXD_EXTENT) { |
@@ -695,11 +693,8 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) | |||
695 | DQUOT_FREE_BLOCK(inode, old_blocks); | 693 | DQUOT_FREE_BLOCK(inode, old_blocks); |
696 | 694 | ||
697 | inode->i_ctime = CURRENT_TIME; | 695 | inode->i_ctime = CURRENT_TIME; |
698 | rc = txCommit(tid, 1, &inode, 0); | ||
699 | txEnd(tid); | ||
700 | up(&ji->commit_sem); | ||
701 | 696 | ||
702 | return rc; | 697 | return 0; |
703 | } | 698 | } |
704 | 699 | ||
705 | /* | 700 | /* |
@@ -810,8 +805,8 @@ static int can_set_xattr(struct inode *inode, const char *name, | |||
810 | return permission(inode, MAY_WRITE, NULL); | 805 | return permission(inode, MAY_WRITE, NULL); |
811 | } | 806 | } |
812 | 807 | ||
813 | int __jfs_setxattr(struct inode *inode, const char *name, const void *value, | 808 | int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, |
814 | size_t value_len, int flags) | 809 | const void *value, size_t value_len, int flags) |
815 | { | 810 | { |
816 | struct jfs_ea_list *ealist; | 811 | struct jfs_ea_list *ealist; |
817 | struct jfs_ea *ea, *old_ea = NULL, *next_ea = NULL; | 812 | struct jfs_ea *ea, *old_ea = NULL, *next_ea = NULL; |
@@ -825,9 +820,6 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value, | |||
825 | int rc; | 820 | int rc; |
826 | int length; | 821 | int length; |
827 | 822 | ||
828 | if ((rc = can_set_xattr(inode, name, value, value_len))) | ||
829 | return rc; | ||
830 | |||
831 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { | 823 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { |
832 | os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1, | 824 | os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1, |
833 | GFP_KERNEL); | 825 | GFP_KERNEL); |
@@ -939,7 +931,7 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value, | |||
939 | 931 | ||
940 | ealist->size = cpu_to_le32(new_size); | 932 | ealist->size = cpu_to_le32(new_size); |
941 | 933 | ||
942 | rc = ea_put(inode, &ea_buf, new_size); | 934 | rc = ea_put(tid, inode, &ea_buf, new_size); |
943 | 935 | ||
944 | goto out; | 936 | goto out; |
945 | release: | 937 | release: |
@@ -955,12 +947,29 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value, | |||
955 | int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 947 | int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
956 | size_t value_len, int flags) | 948 | size_t value_len, int flags) |
957 | { | 949 | { |
950 | struct inode *inode = dentry->d_inode; | ||
951 | struct jfs_inode_info *ji = JFS_IP(inode); | ||
952 | int rc; | ||
953 | tid_t tid; | ||
954 | |||
955 | if ((rc = can_set_xattr(inode, name, value, value_len))) | ||
956 | return rc; | ||
957 | |||
958 | if (value == NULL) { /* empty EA, do not remove */ | 958 | if (value == NULL) { /* empty EA, do not remove */ |
959 | value = ""; | 959 | value = ""; |
960 | value_len = 0; | 960 | value_len = 0; |
961 | } | 961 | } |
962 | 962 | ||
963 | return __jfs_setxattr(dentry->d_inode, name, value, value_len, flags); | 963 | tid = txBegin(inode->i_sb, 0); |
964 | down(&ji->commit_sem); | ||
965 | rc = __jfs_setxattr(tid, dentry->d_inode, name, value, value_len, | ||
966 | flags); | ||
967 | if (!rc) | ||
968 | rc = txCommit(tid, 1, &inode, 0); | ||
969 | txEnd(tid); | ||
970 | up(&ji->commit_sem); | ||
971 | |||
972 | return rc; | ||
964 | } | 973 | } |
965 | 974 | ||
966 | static int can_get_xattr(struct inode *inode, const char *name) | 975 | static int can_get_xattr(struct inode *inode, const char *name) |
@@ -1122,5 +1131,56 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size) | |||
1122 | 1131 | ||
1123 | int jfs_removexattr(struct dentry *dentry, const char *name) | 1132 | int jfs_removexattr(struct dentry *dentry, const char *name) |
1124 | { | 1133 | { |
1125 | return __jfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); | 1134 | struct inode *inode = dentry->d_inode; |
1135 | struct jfs_inode_info *ji = JFS_IP(inode); | ||
1136 | int rc; | ||
1137 | tid_t tid; | ||
1138 | |||
1139 | if ((rc = can_set_xattr(inode, name, NULL, 0))) | ||
1140 | return rc; | ||
1141 | |||
1142 | tid = txBegin(inode->i_sb, 0); | ||
1143 | down(&ji->commit_sem); | ||
1144 | rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE); | ||
1145 | if (!rc) | ||
1146 | rc = txCommit(tid, 1, &inode, 0); | ||
1147 | txEnd(tid); | ||
1148 | up(&ji->commit_sem); | ||
1149 | |||
1150 | return rc; | ||
1151 | } | ||
1152 | |||
1153 | #ifdef CONFIG_JFS_SECURITY | ||
1154 | int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir) | ||
1155 | { | ||
1156 | int rc; | ||
1157 | size_t len; | ||
1158 | void *value; | ||
1159 | char *suffix; | ||
1160 | char *name; | ||
1161 | |||
1162 | rc = security_inode_init_security(inode, dir, &suffix, &value, &len); | ||
1163 | if (rc) { | ||
1164 | if (rc == -EOPNOTSUPP) | ||
1165 | return 0; | ||
1166 | return rc; | ||
1167 | } | ||
1168 | name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 1 + strlen(suffix), | ||
1169 | GFP_NOFS); | ||
1170 | if (!name) { | ||
1171 | rc = -ENOMEM; | ||
1172 | goto kmalloc_failed; | ||
1173 | } | ||
1174 | strcpy(name, XATTR_SECURITY_PREFIX); | ||
1175 | strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); | ||
1176 | |||
1177 | rc = __jfs_setxattr(tid, inode, name, value, len, 0); | ||
1178 | |||
1179 | kfree(name); | ||
1180 | kmalloc_failed: | ||
1181 | kfree(suffix); | ||
1182 | kfree(value); | ||
1183 | |||
1184 | return rc; | ||
1126 | } | 1185 | } |
1186 | #endif | ||