diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-11 13:14:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-11 13:14:54 -0400 |
commit | 32983696a48a6c41d99f3eca82ba7510a552d843 (patch) | |
tree | ab793556d6a9d2d4e0f366eed58e74b8e705cd8c /fs | |
parent | ce1289adeb67b5480f35cb257cbf6e9881153783 (diff) | |
parent | 1d15b10f95d4c4295a0f2288c7be7b6a005490da (diff) |
Merge branch 'for-linus' from kernel.org:/.../shaggy/jfs-2.6 manually
Clash due to new delete_inode behavior (the filesystem now needs to do
the truncate_inode_pages() call itself).
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/jfs/acl.c | 24 | ||||
-rw-r--r-- | fs/jfs/inode.c | 26 | ||||
-rw-r--r-- | fs/jfs/jfs_acl.h | 12 | ||||
-rw-r--r-- | fs/jfs/jfs_xattr.h | 14 | ||||
-rw-r--r-- | fs/jfs/namei.c | 85 | ||||
-rw-r--r-- | fs/jfs/xattr.c | 94 |
6 files changed, 193 insertions, 62 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/inode.c b/fs/jfs/inode.c index cff352f4ec18..0ec62d5310db 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
@@ -128,23 +128,23 @@ void jfs_delete_inode(struct inode *inode) | |||
128 | { | 128 | { |
129 | jfs_info("In jfs_delete_inode, inode = 0x%p", inode); | 129 | jfs_info("In jfs_delete_inode, inode = 0x%p", inode); |
130 | 130 | ||
131 | if (is_bad_inode(inode) || | 131 | if (!is_bad_inode(inode) && |
132 | (JFS_IP(inode)->fileset != cpu_to_le32(FILESYSTEM_I))) | 132 | (JFS_IP(inode)->fileset == cpu_to_le32(FILESYSTEM_I))) { |
133 | return; | ||
134 | 133 | ||
135 | truncate_inode_pages(&inode->i_data, 0); | 134 | truncate_inode_pages(&inode->i_data, 0); |
136 | 135 | ||
137 | if (test_cflag(COMMIT_Freewmap, inode)) | 136 | if (test_cflag(COMMIT_Freewmap, inode)) |
138 | jfs_free_zero_link(inode); | 137 | jfs_free_zero_link(inode); |
139 | 138 | ||
140 | diFree(inode); | 139 | diFree(inode); |
141 | 140 | ||
142 | /* | 141 | /* |
143 | * Free the inode from the quota allocation. | 142 | * Free the inode from the quota allocation. |
144 | */ | 143 | */ |
145 | DQUOT_INIT(inode); | 144 | DQUOT_INIT(inode); |
146 | DQUOT_FREE_INODE(inode); | 145 | DQUOT_FREE_INODE(inode); |
147 | DQUOT_DROP(inode); | 146 | DQUOT_DROP(inode); |
147 | } | ||
148 | 148 | ||
149 | clear_inode(inode); | 149 | clear_inode(inode); |
150 | } | 150 | } |
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..25e9990bccd1 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); |
@@ -61,4 +61,14 @@ extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t); | |||
61 | extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); | 61 | extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); |
62 | extern int jfs_removexattr(struct dentry *, const char *); | 62 | extern int jfs_removexattr(struct dentry *, const char *); |
63 | 63 | ||
64 | #ifdef CONFIG_JFS_SECURITY | ||
65 | extern int jfs_init_security(tid_t, struct inode *, struct inode *); | ||
66 | #else | ||
67 | static inline int jfs_init_security(tid_t tid, struct inode *inode, | ||
68 | struct inode *dir) | ||
69 | { | ||
70 | return 0; | ||
71 | } | ||
72 | #endif | ||
73 | |||
64 | #endif /* H_JFS_XATTR */ | 74 | #endif /* H_JFS_XATTR */ |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 49ccde3937f9..1abe7343f920 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,19 @@ 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 | |||
114 | rc = jfs_init_security(tid, ip, dip); | ||
115 | if (rc) { | ||
116 | txAbort(tid, 0); | ||
117 | goto out3; | ||
118 | } | ||
119 | |||
92 | if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { | 120 | if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { |
93 | jfs_err("jfs_create: dtSearch returned %d", rc); | 121 | jfs_err("jfs_create: dtSearch returned %d", rc); |
122 | txAbort(tid, 0); | ||
94 | goto out3; | 123 | goto out3; |
95 | } | 124 | } |
96 | 125 | ||
@@ -139,6 +168,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, | |||
139 | up(&JFS_IP(dip)->commit_sem); | 168 | up(&JFS_IP(dip)->commit_sem); |
140 | up(&JFS_IP(ip)->commit_sem); | 169 | up(&JFS_IP(ip)->commit_sem); |
141 | if (rc) { | 170 | if (rc) { |
171 | free_ea_wmap(ip); | ||
142 | ip->i_nlink = 0; | 172 | ip->i_nlink = 0; |
143 | iput(ip); | 173 | iput(ip); |
144 | } else | 174 | } else |
@@ -147,11 +177,6 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, | |||
147 | out2: | 177 | out2: |
148 | free_UCSname(&dname); | 178 | free_UCSname(&dname); |
149 | 179 | ||
150 | #ifdef CONFIG_JFS_POSIX_ACL | ||
151 | if (rc == 0) | ||
152 | jfs_init_acl(ip, dip); | ||
153 | #endif | ||
154 | |||
155 | out1: | 180 | out1: |
156 | 181 | ||
157 | jfs_info("jfs_create: rc:%d", rc); | 182 | jfs_info("jfs_create: rc:%d", rc); |
@@ -216,8 +241,19 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
216 | down(&JFS_IP(dip)->commit_sem); | 241 | down(&JFS_IP(dip)->commit_sem); |
217 | down(&JFS_IP(ip)->commit_sem); | 242 | down(&JFS_IP(ip)->commit_sem); |
218 | 243 | ||
244 | rc = jfs_init_acl(tid, ip, dip); | ||
245 | if (rc) | ||
246 | goto out3; | ||
247 | |||
248 | rc = jfs_init_security(tid, ip, dip); | ||
249 | if (rc) { | ||
250 | txAbort(tid, 0); | ||
251 | goto out3; | ||
252 | } | ||
253 | |||
219 | if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { | 254 | if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { |
220 | jfs_err("jfs_mkdir: dtSearch returned %d", rc); | 255 | jfs_err("jfs_mkdir: dtSearch returned %d", rc); |
256 | txAbort(tid, 0); | ||
221 | goto out3; | 257 | goto out3; |
222 | } | 258 | } |
223 | 259 | ||
@@ -267,6 +303,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
267 | up(&JFS_IP(dip)->commit_sem); | 303 | up(&JFS_IP(dip)->commit_sem); |
268 | up(&JFS_IP(ip)->commit_sem); | 304 | up(&JFS_IP(ip)->commit_sem); |
269 | if (rc) { | 305 | if (rc) { |
306 | free_ea_wmap(ip); | ||
270 | ip->i_nlink = 0; | 307 | ip->i_nlink = 0; |
271 | iput(ip); | 308 | iput(ip); |
272 | } else | 309 | } else |
@@ -275,10 +312,6 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
275 | out2: | 312 | out2: |
276 | free_UCSname(&dname); | 313 | free_UCSname(&dname); |
277 | 314 | ||
278 | #ifdef CONFIG_JFS_POSIX_ACL | ||
279 | if (rc == 0) | ||
280 | jfs_init_acl(ip, dip); | ||
281 | #endif | ||
282 | 315 | ||
283 | out1: | 316 | out1: |
284 | 317 | ||
@@ -885,6 +918,10 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
885 | down(&JFS_IP(dip)->commit_sem); | 918 | down(&JFS_IP(dip)->commit_sem); |
886 | down(&JFS_IP(ip)->commit_sem); | 919 | down(&JFS_IP(ip)->commit_sem); |
887 | 920 | ||
921 | rc = jfs_init_security(tid, ip, dip); | ||
922 | if (rc) | ||
923 | goto out3; | ||
924 | |||
888 | tblk = tid_to_tblock(tid); | 925 | tblk = tid_to_tblock(tid); |
889 | tblk->xflag |= COMMIT_CREATE; | 926 | tblk->xflag |= COMMIT_CREATE; |
890 | tblk->ino = ip->i_ino; | 927 | tblk->ino = ip->i_ino; |
@@ -1000,6 +1037,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
1000 | up(&JFS_IP(dip)->commit_sem); | 1037 | up(&JFS_IP(dip)->commit_sem); |
1001 | up(&JFS_IP(ip)->commit_sem); | 1038 | up(&JFS_IP(ip)->commit_sem); |
1002 | if (rc) { | 1039 | if (rc) { |
1040 | free_ea_wmap(ip); | ||
1003 | ip->i_nlink = 0; | 1041 | ip->i_nlink = 0; |
1004 | iput(ip); | 1042 | iput(ip); |
1005 | } else | 1043 | } else |
@@ -1008,11 +1046,6 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
1008 | out2: | 1046 | out2: |
1009 | free_UCSname(&dname); | 1047 | free_UCSname(&dname); |
1010 | 1048 | ||
1011 | #ifdef CONFIG_JFS_POSIX_ACL | ||
1012 | if (rc == 0) | ||
1013 | jfs_init_acl(ip, dip); | ||
1014 | #endif | ||
1015 | |||
1016 | out1: | 1049 | out1: |
1017 | jfs_info("jfs_symlink: rc:%d", rc); | 1050 | jfs_info("jfs_symlink: rc:%d", rc); |
1018 | return rc; | 1051 | return rc; |
@@ -1328,8 +1361,20 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1328 | down(&JFS_IP(dir)->commit_sem); | 1361 | down(&JFS_IP(dir)->commit_sem); |
1329 | down(&JFS_IP(ip)->commit_sem); | 1362 | down(&JFS_IP(ip)->commit_sem); |
1330 | 1363 | ||
1331 | if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) | 1364 | rc = jfs_init_acl(tid, ip, dir); |
1365 | if (rc) | ||
1366 | goto out3; | ||
1367 | |||
1368 | rc = jfs_init_security(tid, ip, dir); | ||
1369 | if (rc) { | ||
1370 | txAbort(tid, 0); | ||
1332 | goto out3; | 1371 | goto out3; |
1372 | } | ||
1373 | |||
1374 | if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) { | ||
1375 | txAbort(tid, 0); | ||
1376 | goto out3; | ||
1377 | } | ||
1333 | 1378 | ||
1334 | tblk = tid_to_tblock(tid); | 1379 | tblk = tid_to_tblock(tid); |
1335 | tblk->xflag |= COMMIT_CREATE; | 1380 | tblk->xflag |= COMMIT_CREATE; |
@@ -1337,8 +1382,10 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1337 | tblk->u.ixpxd = JFS_IP(ip)->ixpxd; | 1382 | tblk->u.ixpxd = JFS_IP(ip)->ixpxd; |
1338 | 1383 | ||
1339 | ino = ip->i_ino; | 1384 | ino = ip->i_ino; |
1340 | if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) | 1385 | if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) { |
1386 | txAbort(tid, 0); | ||
1341 | goto out3; | 1387 | goto out3; |
1388 | } | ||
1342 | 1389 | ||
1343 | ip->i_op = &jfs_file_inode_operations; | 1390 | ip->i_op = &jfs_file_inode_operations; |
1344 | jfs_ip->dev = new_encode_dev(rdev); | 1391 | jfs_ip->dev = new_encode_dev(rdev); |
@@ -1360,6 +1407,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1360 | up(&JFS_IP(ip)->commit_sem); | 1407 | up(&JFS_IP(ip)->commit_sem); |
1361 | up(&JFS_IP(dir)->commit_sem); | 1408 | up(&JFS_IP(dir)->commit_sem); |
1362 | if (rc) { | 1409 | if (rc) { |
1410 | free_ea_wmap(ip); | ||
1363 | ip->i_nlink = 0; | 1411 | ip->i_nlink = 0; |
1364 | iput(ip); | 1412 | iput(ip); |
1365 | } else | 1413 | } else |
@@ -1368,11 +1416,6 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1368 | out1: | 1416 | out1: |
1369 | free_UCSname(&dname); | 1417 | free_UCSname(&dname); |
1370 | 1418 | ||
1371 | #ifdef CONFIG_JFS_POSIX_ACL | ||
1372 | if (rc == 0) | ||
1373 | jfs_init_acl(ip, dir); | ||
1374 | #endif | ||
1375 | |||
1376 | out: | 1419 | out: |
1377 | jfs_info("jfs_mknod: returning %d", rc); | 1420 | jfs_info("jfs_mknod: returning %d", rc); |
1378 | return rc; | 1421 | return rc; |
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 | ||