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 | ||
