diff options
-rw-r--r-- | fs/jffs2/gc.c | 21 | ||||
-rw-r--r-- | fs/jffs2/xattr.c | 68 | ||||
-rw-r--r-- | fs/jffs2/xattr.h | 4 |
3 files changed, 36 insertions, 57 deletions
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c index 4ea1b7f0ae78..a5ef9814f165 100644 --- a/fs/jffs2/gc.c +++ b/fs/jffs2/gc.c | |||
@@ -266,15 +266,22 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) | |||
266 | 266 | ||
267 | ic = jffs2_raw_ref_to_ic(raw); | 267 | ic = jffs2_raw_ref_to_ic(raw); |
268 | 268 | ||
269 | #ifdef CONFIG_JFFS2_FS_XATTR | ||
269 | /* When 'ic' refers xattr_datum/xattr_ref, this node is GCed as xattr. | 270 | /* When 'ic' refers xattr_datum/xattr_ref, this node is GCed as xattr. |
270 | We can decide whether this node is inode or xattr by ic->class. | 271 | * We can decide whether this node is inode or xattr by ic->class. */ |
271 | ret = 0 : ic is xattr_datum/xattr_ref, and GC was SUCCESSED. | 272 | if (ic->class == RAWNODE_CLASS_XATTR_DATUM |
272 | ret < 0 : ic is xattr_datum/xattr_ref, but GC was FAILED. | 273 | || ic->class == RAWNODE_CLASS_XATTR_REF) { |
273 | ret > 0 : ic is NOT xattr_datum/xattr_ref. | 274 | BUG_ON(raw->next_in_ino != (void *)ic); |
274 | */ | 275 | spin_unlock(&c->erase_completion_lock); |
275 | ret = jffs2_garbage_collect_xattr(c, ic); | 276 | |
276 | if (ret <= 0) | 277 | if (ic->class == RAWNODE_CLASS_XATTR_DATUM) { |
278 | ret = jffs2_garbage_collect_xattr_datum(c, (struct jffs2_xattr_datum *)ic); | ||
279 | } else { | ||
280 | ret = jffs2_garbage_collect_xattr_ref(c, (struct jffs2_xattr_ref *)ic); | ||
281 | } | ||
277 | goto release_sem; | 282 | goto release_sem; |
283 | } | ||
284 | #endif | ||
278 | 285 | ||
279 | /* We need to hold the inocache. Either the erase_completion_lock or | 286 | /* We need to hold the inocache. Either the erase_completion_lock or |
280 | the inocache_lock are sufficient; we trade down since the inocache_lock | 287 | the inocache_lock are sufficient; we trade down since the inocache_lock |
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index b16bc71c9cd2..9c1f401d12d7 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c | |||
@@ -1170,104 +1170,76 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, | |||
1170 | * is used to move xdatum into new node. | 1170 | * is used to move xdatum into new node. |
1171 | * jffs2_garbage_collect_xattr_ref(c, ref) | 1171 | * jffs2_garbage_collect_xattr_ref(c, ref) |
1172 | * is used to move xref into new node. | 1172 | * is used to move xref into new node. |
1173 | * jffs2_garbage_collect_xattr(c, ic) | ||
1174 | * is used to call appropriate garbage collector function, if argument | ||
1175 | * pointer (ic) is the reference of xdatum/xref. | ||
1176 | * jffs2_verify_xattr(c) | 1173 | * jffs2_verify_xattr(c) |
1177 | * is used to call do_verify_xattr_datum() before garbage collecting. | 1174 | * is used to call do_verify_xattr_datum() before garbage collecting. |
1178 | * -------------------------------------------------- */ | 1175 | * -------------------------------------------------- */ |
1179 | static int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, | 1176 | int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) |
1180 | struct jffs2_xattr_datum *xd) | ||
1181 | { | 1177 | { |
1182 | /* must be called under down_write(xattr_sem), and called from GC thread */ | ||
1183 | uint32_t phys_ofs, totlen, length, old_ofs; | 1178 | uint32_t phys_ofs, totlen, length, old_ofs; |
1184 | int rc; | 1179 | int rc = -EINVAL; |
1185 | 1180 | ||
1181 | down_write(&c->xattr_sem); | ||
1186 | BUG_ON(!xd->node); | 1182 | BUG_ON(!xd->node); |
1187 | 1183 | ||
1188 | old_ofs = ref_offset(xd->node); | 1184 | old_ofs = ref_offset(xd->node); |
1189 | totlen = ref_totlen(c, c->gcblock, xd->node); | 1185 | totlen = ref_totlen(c, c->gcblock, xd->node); |
1190 | if (totlen < sizeof(struct jffs2_raw_xattr)) | 1186 | if (totlen < sizeof(struct jffs2_raw_xattr)) |
1191 | return -EINVAL; | 1187 | goto out; |
1192 | 1188 | ||
1193 | if (!xd->xname) { | 1189 | if (!xd->xname) { |
1194 | rc = load_xattr_datum(c, xd); | 1190 | rc = load_xattr_datum(c, xd); |
1195 | if (unlikely(rc > 0)) { | 1191 | if (unlikely(rc > 0)) { |
1196 | delete_xattr_datum_node(c, xd); | 1192 | delete_xattr_datum_node(c, xd); |
1197 | return 0; | 1193 | rc = 0; |
1194 | goto out; | ||
1198 | } else if (unlikely(rc < 0)) | 1195 | } else if (unlikely(rc < 0)) |
1199 | return -EINVAL; | 1196 | goto out; |
1200 | } | 1197 | } |
1201 | rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XATTR_SIZE); | 1198 | rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XATTR_SIZE); |
1202 | if (rc || length < totlen) { | 1199 | if (rc || length < totlen) { |
1203 | JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, totlen); | 1200 | JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, totlen); |
1204 | return rc ? rc : -EBADFD; | 1201 | rc = rc ? rc : -EBADFD; |
1202 | goto out; | ||
1205 | } | 1203 | } |
1206 | rc = save_xattr_datum(c, xd, phys_ofs); | 1204 | rc = save_xattr_datum(c, xd, phys_ofs); |
1207 | if (!rc) | 1205 | if (!rc) |
1208 | dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n", | 1206 | dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n", |
1209 | xd->xid, xd->version, old_ofs, ref_offset(xd->node)); | 1207 | xd->xid, xd->version, old_ofs, ref_offset(xd->node)); |
1208 | out: | ||
1209 | up_write(&c->xattr_sem); | ||
1210 | return rc; | 1210 | return rc; |
1211 | } | 1211 | } |
1212 | 1212 | ||
1213 | 1213 | ||
1214 | static int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, | 1214 | int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) |
1215 | struct jffs2_xattr_ref *ref) | ||
1216 | { | 1215 | { |
1217 | /* must be called under down(alloc_sem) */ | ||
1218 | uint32_t phys_ofs, totlen, length, old_ofs; | 1216 | uint32_t phys_ofs, totlen, length, old_ofs; |
1219 | int rc; | 1217 | int rc = -EINVAL; |
1220 | 1218 | ||
1219 | down_write(&c->xattr_sem); | ||
1221 | BUG_ON(!ref->node); | 1220 | BUG_ON(!ref->node); |
1222 | 1221 | ||
1223 | old_ofs = ref_offset(ref->node); | 1222 | old_ofs = ref_offset(ref->node); |
1224 | totlen = ref_totlen(c, c->gcblock, ref->node); | 1223 | totlen = ref_totlen(c, c->gcblock, ref->node); |
1225 | if (totlen != sizeof(struct jffs2_raw_xref)) | 1224 | if (totlen != sizeof(struct jffs2_raw_xref)) |
1226 | return -EINVAL; | 1225 | goto out; |
1226 | |||
1227 | rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XREF_SIZE); | 1227 | rc = jffs2_reserve_space_gc(c, totlen, &phys_ofs, &length, JFFS2_SUMMARY_XREF_SIZE); |
1228 | if (rc || length < totlen) { | 1228 | if (rc || length < totlen) { |
1229 | JFFS2_WARNING("%s: jffs2_reserve_space() = %d, request = %u\n", | 1229 | JFFS2_WARNING("%s: jffs2_reserve_space() = %d, request = %u\n", |
1230 | __FUNCTION__, rc, totlen); | 1230 | __FUNCTION__, rc, totlen); |
1231 | return rc ? rc : -EBADFD; | 1231 | rc = rc ? rc : -EBADFD; |
1232 | goto out; | ||
1232 | } | 1233 | } |
1233 | rc = save_xattr_ref(c, ref, phys_ofs); | 1234 | rc = save_xattr_ref(c, ref, phys_ofs); |
1234 | if (!rc) | 1235 | if (!rc) |
1235 | dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n", | 1236 | dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n", |
1236 | ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node)); | 1237 | ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node)); |
1238 | out: | ||
1239 | up_write(&c->xattr_sem); | ||
1237 | return rc; | 1240 | return rc; |
1238 | } | 1241 | } |
1239 | 1242 | ||
1240 | int jffs2_garbage_collect_xattr(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) | ||
1241 | { | ||
1242 | struct jffs2_xattr_datum *xd; | ||
1243 | struct jffs2_xattr_ref *ref; | ||
1244 | int ret; | ||
1245 | |||
1246 | switch (ic->class) { | ||
1247 | case RAWNODE_CLASS_XATTR_DATUM: | ||
1248 | spin_unlock(&c->erase_completion_lock); | ||
1249 | |||
1250 | down_write(&c->xattr_sem); | ||
1251 | xd = (struct jffs2_xattr_datum *)ic; | ||
1252 | ret = xd ? jffs2_garbage_collect_xattr_datum(c, xd) : 0; | ||
1253 | up_write(&c->xattr_sem); | ||
1254 | break; | ||
1255 | case RAWNODE_CLASS_XATTR_REF: | ||
1256 | spin_unlock(&c->erase_completion_lock); | ||
1257 | |||
1258 | down_write(&c->xattr_sem); | ||
1259 | ref = (struct jffs2_xattr_ref *)ic; | ||
1260 | ret = ref ? jffs2_garbage_collect_xattr_ref(c, ref) : 0; | ||
1261 | up_write(&c->xattr_sem); | ||
1262 | break; | ||
1263 | default: | ||
1264 | /* This node is not xattr_datum/xattr_ref */ | ||
1265 | ret = 1; | ||
1266 | break; | ||
1267 | } | ||
1268 | return ret; | ||
1269 | } | ||
1270 | |||
1271 | int jffs2_verify_xattr(struct jffs2_sb_info *c) | 1243 | int jffs2_verify_xattr(struct jffs2_sb_info *c) |
1272 | { | 1244 | { |
1273 | struct jffs2_xattr_datum *xd, *_xd; | 1245 | struct jffs2_xattr_datum *xd, *_xd; |
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h index 0360097e5933..762814b7107b 100644 --- a/fs/jffs2/xattr.h +++ b/fs/jffs2/xattr.h | |||
@@ -69,7 +69,8 @@ extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c | |||
69 | extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); | 69 | extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); |
70 | extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); | 70 | extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); |
71 | 71 | ||
72 | extern int jffs2_garbage_collect_xattr(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); | 72 | extern int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd); |
73 | extern int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref); | ||
73 | extern int jffs2_verify_xattr(struct jffs2_sb_info *c); | 74 | extern int jffs2_verify_xattr(struct jffs2_sb_info *c); |
74 | 75 | ||
75 | extern int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname, | 76 | extern int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname, |
@@ -94,7 +95,6 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); | |||
94 | 95 | ||
95 | #define jffs2_xattr_delete_inode(c, ic) | 96 | #define jffs2_xattr_delete_inode(c, ic) |
96 | #define jffs2_xattr_free_inode(c, ic) | 97 | #define jffs2_xattr_free_inode(c, ic) |
97 | #define jffs2_garbage_collect_xattr(c, ic) (1) | ||
98 | #define jffs2_verify_xattr(c) (1) | 98 | #define jffs2_verify_xattr(c) (1) |
99 | 99 | ||
100 | #define jffs2_xattr_handlers NULL | 100 | #define jffs2_xattr_handlers NULL |