diff options
Diffstat (limited to 'fs/jffs2/xattr.c')
-rw-r--r-- | fs/jffs2/xattr.c | 68 |
1 files changed, 20 insertions, 48 deletions
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; |