aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jffs2/gc.c21
-rw-r--r--fs/jffs2/xattr.c68
-rw-r--r--fs/jffs2/xattr.h4
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 * -------------------------------------------------- */
1179static int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, 1176int 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
1214static int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, 1214int 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
1240int 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
1271int jffs2_verify_xattr(struct jffs2_sb_info *c) 1243int 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
69extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); 69extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
70extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); 70extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
71 71
72extern int jffs2_garbage_collect_xattr(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); 72extern int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd);
73extern int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref);
73extern int jffs2_verify_xattr(struct jffs2_sb_info *c); 74extern int jffs2_verify_xattr(struct jffs2_sb_info *c);
74 75
75extern int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname, 76extern 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