diff options
author | Dave Kleikamp <shaggy@austin.ibm.com> | 2005-09-01 10:02:43 -0400 |
---|---|---|
committer | Dave Kleikamp <shaggy@austin.ibm.com> | 2005-09-01 10:02:43 -0400 |
commit | 4f4b401bfaa97edbea41a1fcab794148e7ac0421 (patch) | |
tree | d58dcf9d90e15364398a3a4584f2892439295b64 | |
parent | b1b5d7f9b7ac6a8e3452ac43a53eebf69fdf5a77 (diff) |
JFS: allow extended attributes to be set within a existing transaction
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
-rw-r--r-- | fs/jfs/acl.c | 24 | ||||
-rw-r--r-- | fs/jfs/jfs_acl.h | 12 | ||||
-rw-r--r-- | fs/jfs/jfs_xattr.h | 4 | ||||
-rw-r--r-- | fs/jfs/namei.c | 63 | ||||
-rw-r--r-- | fs/jfs/xattr.c | 58 |
5 files changed, 112 insertions, 49 deletions
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index e892dab40c26..461e4934ca7c 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/quotaops.h> | 23 | #include <linux/quotaops.h> |
24 | #include <linux/posix_acl_xattr.h> | 24 | #include <linux/posix_acl_xattr.h> |
25 | #include "jfs_incore.h" | 25 | #include "jfs_incore.h" |
26 | #include "jfs_txnmgr.h" | ||
26 | #include "jfs_xattr.h" | 27 | #include "jfs_xattr.h" |
27 | #include "jfs_acl.h" | 28 | #include "jfs_acl.h" |
28 | 29 | ||
@@ -75,7 +76,8 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type) | |||
75 | return acl; | 76 | return acl; |
76 | } | 77 | } |
77 | 78 | ||
78 | static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | 79 | static int jfs_set_acl(tid_t tid, struct inode *inode, int type, |
80 | struct posix_acl *acl) | ||
79 | { | 81 | { |
80 | char *ea_name; | 82 | char *ea_name; |
81 | struct jfs_inode_info *ji = JFS_IP(inode); | 83 | struct jfs_inode_info *ji = JFS_IP(inode); |
@@ -110,7 +112,7 @@ static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
110 | if (rc < 0) | 112 | if (rc < 0) |
111 | goto out; | 113 | goto out; |
112 | } | 114 | } |
113 | rc = __jfs_setxattr(inode, ea_name, value, size, 0); | 115 | rc = __jfs_setxattr(tid, inode, ea_name, value, size, 0); |
114 | out: | 116 | out: |
115 | kfree(value); | 117 | kfree(value); |
116 | 118 | ||
@@ -143,7 +145,7 @@ int jfs_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
143 | return generic_permission(inode, mask, jfs_check_acl); | 145 | return generic_permission(inode, mask, jfs_check_acl); |
144 | } | 146 | } |
145 | 147 | ||
146 | int jfs_init_acl(struct inode *inode, struct inode *dir) | 148 | int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) |
147 | { | 149 | { |
148 | struct posix_acl *acl = NULL; | 150 | struct posix_acl *acl = NULL; |
149 | struct posix_acl *clone; | 151 | struct posix_acl *clone; |
@@ -159,7 +161,7 @@ int jfs_init_acl(struct inode *inode, struct inode *dir) | |||
159 | 161 | ||
160 | if (acl) { | 162 | if (acl) { |
161 | if (S_ISDIR(inode->i_mode)) { | 163 | if (S_ISDIR(inode->i_mode)) { |
162 | rc = jfs_set_acl(inode, ACL_TYPE_DEFAULT, acl); | 164 | rc = jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, acl); |
163 | if (rc) | 165 | if (rc) |
164 | goto cleanup; | 166 | goto cleanup; |
165 | } | 167 | } |
@@ -173,7 +175,8 @@ int jfs_init_acl(struct inode *inode, struct inode *dir) | |||
173 | if (rc >= 0) { | 175 | if (rc >= 0) { |
174 | inode->i_mode = mode; | 176 | inode->i_mode = mode; |
175 | if (rc > 0) | 177 | if (rc > 0) |
176 | rc = jfs_set_acl(inode, ACL_TYPE_ACCESS, clone); | 178 | rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, |
179 | clone); | ||
177 | } | 180 | } |
178 | posix_acl_release(clone); | 181 | posix_acl_release(clone); |
179 | cleanup: | 182 | cleanup: |
@@ -202,8 +205,15 @@ static int jfs_acl_chmod(struct inode *inode) | |||
202 | return -ENOMEM; | 205 | return -ENOMEM; |
203 | 206 | ||
204 | rc = posix_acl_chmod_masq(clone, inode->i_mode); | 207 | rc = posix_acl_chmod_masq(clone, inode->i_mode); |
205 | if (!rc) | 208 | if (!rc) { |
206 | rc = jfs_set_acl(inode, ACL_TYPE_ACCESS, clone); | 209 | tid_t tid = txBegin(inode->i_sb, 0); |
210 | down(&JFS_IP(inode)->commit_sem); | ||
211 | rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, clone); | ||
212 | if (!rc) | ||
213 | rc = txCommit(tid, 1, &inode, 0); | ||
214 | txEnd(tid); | ||
215 | up(&JFS_IP(inode)->commit_sem); | ||
216 | } | ||
207 | 217 | ||
208 | posix_acl_release(clone); | 218 | posix_acl_release(clone); |
209 | return rc; | 219 | return rc; |
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h index a3acd3eec059..a76293767c73 100644 --- a/fs/jfs/jfs_acl.h +++ b/fs/jfs/jfs_acl.h | |||
@@ -21,8 +21,16 @@ | |||
21 | #ifdef CONFIG_JFS_POSIX_ACL | 21 | #ifdef CONFIG_JFS_POSIX_ACL |
22 | 22 | ||
23 | int jfs_permission(struct inode *, int, struct nameidata *); | 23 | int jfs_permission(struct inode *, int, struct nameidata *); |
24 | int jfs_init_acl(struct inode *, struct inode *); | 24 | int jfs_init_acl(tid_t, struct inode *, struct inode *); |
25 | int jfs_setattr(struct dentry *, struct iattr *); | 25 | int jfs_setattr(struct dentry *, struct iattr *); |
26 | 26 | ||
27 | #endif /* CONFIG_JFS_POSIX_ACL */ | 27 | #else |
28 | |||
29 | static inline int jfs_init_acl(tid_t tid, struct inode *inode, | ||
30 | struct inode *dir) | ||
31 | { | ||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | #endif | ||
28 | #endif /* _H_JFS_ACL */ | 36 | #endif /* _H_JFS_ACL */ |
diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h index a1052f3f0bee..116a73ce3076 100644 --- a/fs/jfs/jfs_xattr.h +++ b/fs/jfs/jfs_xattr.h | |||
@@ -52,8 +52,8 @@ struct jfs_ea_list { | |||
52 | #define END_EALIST(ealist) \ | 52 | #define END_EALIST(ealist) \ |
53 | ((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist))) | 53 | ((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist))) |
54 | 54 | ||
55 | extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t, | 55 | extern int __jfs_setxattr(tid_t, struct inode *, const char *, const void *, |
56 | int); | 56 | size_t, int); |
57 | extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t, | 57 | extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t, |
58 | int); | 58 | int); |
59 | extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t); | 59 | extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t); |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 49ccde3937f9..f23f9c2aa525 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -39,6 +39,24 @@ struct dentry_operations jfs_ci_dentry_operations; | |||
39 | static s64 commitZeroLink(tid_t, struct inode *); | 39 | static s64 commitZeroLink(tid_t, struct inode *); |
40 | 40 | ||
41 | /* | 41 | /* |
42 | * NAME: free_ea_wmap(inode) | ||
43 | * | ||
44 | * FUNCTION: free uncommitted extended attributes from working map | ||
45 | * | ||
46 | */ | ||
47 | static inline void free_ea_wmap(struct inode *inode) | ||
48 | { | ||
49 | dxd_t *ea = &JFS_IP(inode)->ea; | ||
50 | |||
51 | if (ea->flag & DXD_EXTENT) { | ||
52 | /* free EA pages from cache */ | ||
53 | invalidate_dxd_metapages(inode, *ea); | ||
54 | dbFree(inode, addressDXD(ea), lengthDXD(ea)); | ||
55 | } | ||
56 | ea->flag = 0; | ||
57 | } | ||
58 | |||
59 | /* | ||
42 | * NAME: jfs_create(dip, dentry, mode) | 60 | * NAME: jfs_create(dip, dentry, mode) |
43 | * | 61 | * |
44 | * FUNCTION: create a regular file in the parent directory <dip> | 62 | * FUNCTION: create a regular file in the parent directory <dip> |
@@ -89,8 +107,13 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, | |||
89 | down(&JFS_IP(dip)->commit_sem); | 107 | down(&JFS_IP(dip)->commit_sem); |
90 | down(&JFS_IP(ip)->commit_sem); | 108 | down(&JFS_IP(ip)->commit_sem); |
91 | 109 | ||
110 | rc = jfs_init_acl(tid, ip, dip); | ||
111 | if (rc) | ||
112 | goto out3; | ||
113 | |||
92 | if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { | 114 | if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { |
93 | jfs_err("jfs_create: dtSearch returned %d", rc); | 115 | jfs_err("jfs_create: dtSearch returned %d", rc); |
116 | txAbort(tid, 0); | ||
94 | goto out3; | 117 | goto out3; |
95 | } | 118 | } |
96 | 119 | ||
@@ -139,6 +162,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, | |||
139 | up(&JFS_IP(dip)->commit_sem); | 162 | up(&JFS_IP(dip)->commit_sem); |
140 | up(&JFS_IP(ip)->commit_sem); | 163 | up(&JFS_IP(ip)->commit_sem); |
141 | if (rc) { | 164 | if (rc) { |
165 | free_ea_wmap(ip); | ||
142 | ip->i_nlink = 0; | 166 | ip->i_nlink = 0; |
143 | iput(ip); | 167 | iput(ip); |
144 | } else | 168 | } else |
@@ -147,11 +171,6 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, | |||
147 | out2: | 171 | out2: |
148 | free_UCSname(&dname); | 172 | free_UCSname(&dname); |
149 | 173 | ||
150 | #ifdef CONFIG_JFS_POSIX_ACL | ||
151 | if (rc == 0) | ||
152 | jfs_init_acl(ip, dip); | ||
153 | #endif | ||
154 | |||
155 | out1: | 174 | out1: |
156 | 175 | ||
157 | jfs_info("jfs_create: rc:%d", rc); | 176 | jfs_info("jfs_create: rc:%d", rc); |
@@ -216,8 +235,13 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
216 | down(&JFS_IP(dip)->commit_sem); | 235 | down(&JFS_IP(dip)->commit_sem); |
217 | down(&JFS_IP(ip)->commit_sem); | 236 | down(&JFS_IP(ip)->commit_sem); |
218 | 237 | ||
238 | rc = jfs_init_acl(tid, ip, dip); | ||
239 | if (rc) | ||
240 | goto out3; | ||
241 | |||
219 | if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { | 242 | if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { |
220 | jfs_err("jfs_mkdir: dtSearch returned %d", rc); | 243 | jfs_err("jfs_mkdir: dtSearch returned %d", rc); |
244 | txAbort(tid, 0); | ||
221 | goto out3; | 245 | goto out3; |
222 | } | 246 | } |
223 | 247 | ||
@@ -267,6 +291,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
267 | up(&JFS_IP(dip)->commit_sem); | 291 | up(&JFS_IP(dip)->commit_sem); |
268 | up(&JFS_IP(ip)->commit_sem); | 292 | up(&JFS_IP(ip)->commit_sem); |
269 | if (rc) { | 293 | if (rc) { |
294 | free_ea_wmap(ip); | ||
270 | ip->i_nlink = 0; | 295 | ip->i_nlink = 0; |
271 | iput(ip); | 296 | iput(ip); |
272 | } else | 297 | } else |
@@ -275,10 +300,6 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
275 | out2: | 300 | out2: |
276 | free_UCSname(&dname); | 301 | free_UCSname(&dname); |
277 | 302 | ||
278 | #ifdef CONFIG_JFS_POSIX_ACL | ||
279 | if (rc == 0) | ||
280 | jfs_init_acl(ip, dip); | ||
281 | #endif | ||
282 | 303 | ||
283 | out1: | 304 | out1: |
284 | 305 | ||
@@ -1000,6 +1021,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
1000 | up(&JFS_IP(dip)->commit_sem); | 1021 | up(&JFS_IP(dip)->commit_sem); |
1001 | up(&JFS_IP(ip)->commit_sem); | 1022 | up(&JFS_IP(ip)->commit_sem); |
1002 | if (rc) { | 1023 | if (rc) { |
1024 | free_ea_wmap(ip); | ||
1003 | ip->i_nlink = 0; | 1025 | ip->i_nlink = 0; |
1004 | iput(ip); | 1026 | iput(ip); |
1005 | } else | 1027 | } else |
@@ -1008,11 +1030,6 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
1008 | out2: | 1030 | out2: |
1009 | free_UCSname(&dname); | 1031 | free_UCSname(&dname); |
1010 | 1032 | ||
1011 | #ifdef CONFIG_JFS_POSIX_ACL | ||
1012 | if (rc == 0) | ||
1013 | jfs_init_acl(ip, dip); | ||
1014 | #endif | ||
1015 | |||
1016 | out1: | 1033 | out1: |
1017 | jfs_info("jfs_symlink: rc:%d", rc); | 1034 | jfs_info("jfs_symlink: rc:%d", rc); |
1018 | return rc; | 1035 | return rc; |
@@ -1328,17 +1345,25 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1328 | down(&JFS_IP(dir)->commit_sem); | 1345 | down(&JFS_IP(dir)->commit_sem); |
1329 | down(&JFS_IP(ip)->commit_sem); | 1346 | down(&JFS_IP(ip)->commit_sem); |
1330 | 1347 | ||
1331 | if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) | 1348 | rc = jfs_init_acl(tid, ip, dir); |
1349 | if (rc) | ||
1332 | goto out3; | 1350 | goto out3; |
1333 | 1351 | ||
1352 | if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) { | ||
1353 | txAbort(tid, 0); | ||
1354 | goto out3; | ||
1355 | } | ||
1356 | |||
1334 | tblk = tid_to_tblock(tid); | 1357 | tblk = tid_to_tblock(tid); |
1335 | tblk->xflag |= COMMIT_CREATE; | 1358 | tblk->xflag |= COMMIT_CREATE; |
1336 | tblk->ino = ip->i_ino; | 1359 | tblk->ino = ip->i_ino; |
1337 | tblk->u.ixpxd = JFS_IP(ip)->ixpxd; | 1360 | tblk->u.ixpxd = JFS_IP(ip)->ixpxd; |
1338 | 1361 | ||
1339 | ino = ip->i_ino; | 1362 | ino = ip->i_ino; |
1340 | if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) | 1363 | if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) { |
1364 | txAbort(tid, 0); | ||
1341 | goto out3; | 1365 | goto out3; |
1366 | } | ||
1342 | 1367 | ||
1343 | ip->i_op = &jfs_file_inode_operations; | 1368 | ip->i_op = &jfs_file_inode_operations; |
1344 | jfs_ip->dev = new_encode_dev(rdev); | 1369 | jfs_ip->dev = new_encode_dev(rdev); |
@@ -1360,6 +1385,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1360 | up(&JFS_IP(ip)->commit_sem); | 1385 | up(&JFS_IP(ip)->commit_sem); |
1361 | up(&JFS_IP(dir)->commit_sem); | 1386 | up(&JFS_IP(dir)->commit_sem); |
1362 | if (rc) { | 1387 | if (rc) { |
1388 | free_ea_wmap(ip); | ||
1363 | ip->i_nlink = 0; | 1389 | ip->i_nlink = 0; |
1364 | iput(ip); | 1390 | iput(ip); |
1365 | } else | 1391 | } else |
@@ -1368,11 +1394,6 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1368 | out1: | 1394 | out1: |
1369 | free_UCSname(&dname); | 1395 | free_UCSname(&dname); |
1370 | 1396 | ||
1371 | #ifdef CONFIG_JFS_POSIX_ACL | ||
1372 | if (rc == 0) | ||
1373 | jfs_init_acl(ip, dir); | ||
1374 | #endif | ||
1375 | |||
1376 | out: | 1397 | out: |
1377 | jfs_info("jfs_mknod: returning %d", rc); | 1398 | jfs_info("jfs_mknod: returning %d", rc); |
1378 | return rc; | 1399 | return rc; |
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 554ec739e49b..35674b2a0e6c 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c | |||
@@ -633,12 +633,12 @@ static void ea_release(struct inode *inode, struct ea_buffer *ea_buf) | |||
633 | } | 633 | } |
634 | } | 634 | } |
635 | 635 | ||
636 | static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) | 636 | static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf, |
637 | int new_size) | ||
637 | { | 638 | { |
638 | struct jfs_inode_info *ji = JFS_IP(inode); | 639 | struct jfs_inode_info *ji = JFS_IP(inode); |
639 | unsigned long old_blocks, new_blocks; | 640 | unsigned long old_blocks, new_blocks; |
640 | int rc = 0; | 641 | int rc = 0; |
641 | tid_t tid; | ||
642 | 642 | ||
643 | if (new_size == 0) { | 643 | if (new_size == 0) { |
644 | ea_release(inode, ea_buf); | 644 | ea_release(inode, ea_buf); |
@@ -664,9 +664,6 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) | |||
664 | if (rc) | 664 | if (rc) |
665 | return rc; | 665 | return rc; |
666 | 666 | ||
667 | tid = txBegin(inode->i_sb, 0); | ||
668 | down(&ji->commit_sem); | ||
669 | |||
670 | old_blocks = new_blocks = 0; | 667 | old_blocks = new_blocks = 0; |
671 | 668 | ||
672 | if (ji->ea.flag & DXD_EXTENT) { | 669 | if (ji->ea.flag & DXD_EXTENT) { |
@@ -695,11 +692,8 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) | |||
695 | DQUOT_FREE_BLOCK(inode, old_blocks); | 692 | DQUOT_FREE_BLOCK(inode, old_blocks); |
696 | 693 | ||
697 | inode->i_ctime = CURRENT_TIME; | 694 | inode->i_ctime = CURRENT_TIME; |
698 | rc = txCommit(tid, 1, &inode, 0); | ||
699 | txEnd(tid); | ||
700 | up(&ji->commit_sem); | ||
701 | 695 | ||
702 | return rc; | 696 | return 0; |
703 | } | 697 | } |
704 | 698 | ||
705 | /* | 699 | /* |
@@ -810,8 +804,8 @@ static int can_set_xattr(struct inode *inode, const char *name, | |||
810 | return permission(inode, MAY_WRITE, NULL); | 804 | return permission(inode, MAY_WRITE, NULL); |
811 | } | 805 | } |
812 | 806 | ||
813 | int __jfs_setxattr(struct inode *inode, const char *name, const void *value, | 807 | int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, |
814 | size_t value_len, int flags) | 808 | const void *value, size_t value_len, int flags) |
815 | { | 809 | { |
816 | struct jfs_ea_list *ealist; | 810 | struct jfs_ea_list *ealist; |
817 | struct jfs_ea *ea, *old_ea = NULL, *next_ea = NULL; | 811 | struct jfs_ea *ea, *old_ea = NULL, *next_ea = NULL; |
@@ -825,9 +819,6 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value, | |||
825 | int rc; | 819 | int rc; |
826 | int length; | 820 | int length; |
827 | 821 | ||
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) { | 822 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { |
832 | os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1, | 823 | os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1, |
833 | GFP_KERNEL); | 824 | GFP_KERNEL); |
@@ -939,7 +930,7 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value, | |||
939 | 930 | ||
940 | ealist->size = cpu_to_le32(new_size); | 931 | ealist->size = cpu_to_le32(new_size); |
941 | 932 | ||
942 | rc = ea_put(inode, &ea_buf, new_size); | 933 | rc = ea_put(tid, inode, &ea_buf, new_size); |
943 | 934 | ||
944 | goto out; | 935 | goto out; |
945 | release: | 936 | release: |
@@ -955,12 +946,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, | 946 | int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
956 | size_t value_len, int flags) | 947 | size_t value_len, int flags) |
957 | { | 948 | { |
949 | struct inode *inode = dentry->d_inode; | ||
950 | struct jfs_inode_info *ji = JFS_IP(inode); | ||
951 | int rc; | ||
952 | tid_t tid; | ||
953 | |||
954 | if ((rc = can_set_xattr(inode, name, value, value_len))) | ||
955 | return rc; | ||
956 | |||
958 | if (value == NULL) { /* empty EA, do not remove */ | 957 | if (value == NULL) { /* empty EA, do not remove */ |
959 | value = ""; | 958 | value = ""; |
960 | value_len = 0; | 959 | value_len = 0; |
961 | } | 960 | } |
962 | 961 | ||
963 | return __jfs_setxattr(dentry->d_inode, name, value, value_len, flags); | 962 | tid = txBegin(inode->i_sb, 0); |
963 | down(&ji->commit_sem); | ||
964 | rc = __jfs_setxattr(tid, dentry->d_inode, name, value, value_len, | ||
965 | flags); | ||
966 | if (!rc) | ||
967 | rc = txCommit(tid, 1, &inode, 0); | ||
968 | txEnd(tid); | ||
969 | up(&ji->commit_sem); | ||
970 | |||
971 | return rc; | ||
964 | } | 972 | } |
965 | 973 | ||
966 | static int can_get_xattr(struct inode *inode, const char *name) | 974 | static int can_get_xattr(struct inode *inode, const char *name) |
@@ -1122,5 +1130,21 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size) | |||
1122 | 1130 | ||
1123 | int jfs_removexattr(struct dentry *dentry, const char *name) | 1131 | int jfs_removexattr(struct dentry *dentry, const char *name) |
1124 | { | 1132 | { |
1125 | return __jfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); | 1133 | struct inode *inode = dentry->d_inode; |
1134 | struct jfs_inode_info *ji = JFS_IP(inode); | ||
1135 | int rc; | ||
1136 | tid_t tid; | ||
1137 | |||
1138 | if ((rc = can_set_xattr(inode, name, NULL, 0))) | ||
1139 | return rc; | ||
1140 | |||
1141 | tid = txBegin(inode->i_sb, 0); | ||
1142 | down(&ji->commit_sem); | ||
1143 | rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE); | ||
1144 | if (!rc) | ||
1145 | rc = txCommit(tid, 1, &inode, 0); | ||
1146 | txEnd(tid); | ||
1147 | up(&ji->commit_sem); | ||
1148 | |||
1149 | return rc; | ||
1126 | } | 1150 | } |