aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2')
-rw-r--r--fs/jffs2/acl.c4
-rw-r--r--fs/jffs2/acl.h4
-rw-r--r--fs/jffs2/malloc.c2
-rw-r--r--fs/jffs2/nodelist.h2
-rw-r--r--fs/jffs2/readinode.c1
-rw-r--r--fs/jffs2/scan.c4
-rw-r--r--fs/jffs2/xattr.c45
7 files changed, 29 insertions, 33 deletions
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
index 9c2077e7e081..0ae3cd10702c 100644
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -345,10 +345,8 @@ int jffs2_init_acl(struct inode *inode, struct inode *dir)
345 return rc; 345 return rc;
346} 346}
347 347
348void jffs2_clear_acl(struct inode *inode) 348void jffs2_clear_acl(struct jffs2_inode_info *f)
349{ 349{
350 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
351
352 if (f->i_acl_access && f->i_acl_access != JFFS2_ACL_NOT_CACHED) { 350 if (f->i_acl_access && f->i_acl_access != JFFS2_ACL_NOT_CACHED) {
353 posix_acl_release(f->i_acl_access); 351 posix_acl_release(f->i_acl_access);
354 f->i_acl_access = JFFS2_ACL_NOT_CACHED; 352 f->i_acl_access = JFFS2_ACL_NOT_CACHED;
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h
index 8893bd1a6ba7..fa327dbd3171 100644
--- a/fs/jffs2/acl.h
+++ b/fs/jffs2/acl.h
@@ -30,7 +30,7 @@ struct jffs2_acl_header {
30extern int jffs2_permission(struct inode *, int, struct nameidata *); 30extern int jffs2_permission(struct inode *, int, struct nameidata *);
31extern int jffs2_acl_chmod(struct inode *); 31extern int jffs2_acl_chmod(struct inode *);
32extern int jffs2_init_acl(struct inode *, struct inode *); 32extern int jffs2_init_acl(struct inode *, struct inode *);
33extern void jffs2_clear_acl(struct inode *); 33extern void jffs2_clear_acl(struct jffs2_inode_info *);
34 34
35extern struct xattr_handler jffs2_acl_access_xattr_handler; 35extern struct xattr_handler jffs2_acl_access_xattr_handler;
36extern struct xattr_handler jffs2_acl_default_xattr_handler; 36extern struct xattr_handler jffs2_acl_default_xattr_handler;
@@ -40,6 +40,6 @@ extern struct xattr_handler jffs2_acl_default_xattr_handler;
40#define jffs2_permission NULL 40#define jffs2_permission NULL
41#define jffs2_acl_chmod(inode) (0) 41#define jffs2_acl_chmod(inode) (0)
42#define jffs2_init_acl(inode,dir) (0) 42#define jffs2_init_acl(inode,dir) (0)
43#define jffs2_clear_acl(inode) 43#define jffs2_clear_acl(f)
44 44
45#endif /* CONFIG_JFFS2_FS_POSIX_ACL */ 45#endif /* CONFIG_JFFS2_FS_POSIX_ACL */
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c
index 8310c95478e9..33f291005012 100644
--- a/fs/jffs2/malloc.c
+++ b/fs/jffs2/malloc.c
@@ -190,7 +190,7 @@ void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x)
190 kmem_cache_free(tmp_dnode_info_slab, x); 190 kmem_cache_free(tmp_dnode_info_slab, x);
191} 191}
192 192
193struct jffs2_raw_node_ref *jffs2_alloc_refblock(void) 193static struct jffs2_raw_node_ref *jffs2_alloc_refblock(void)
194{ 194{
195 struct jffs2_raw_node_ref *ret; 195 struct jffs2_raw_node_ref *ret;
196 196
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index f752baa8d399..cae92c14116d 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -426,8 +426,6 @@ char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
426/* scan.c */ 426/* scan.c */
427int jffs2_scan_medium(struct jffs2_sb_info *c); 427int jffs2_scan_medium(struct jffs2_sb_info *c);
428void jffs2_rotate_lists(struct jffs2_sb_info *c); 428void jffs2_rotate_lists(struct jffs2_sb_info *c);
429int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf,
430 uint32_t ofs, uint32_t len);
431struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino); 429struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino);
432int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); 430int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
433int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t size); 431int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t size);
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index cc1899268c43..266423b2709d 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -968,6 +968,7 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
968 struct jffs2_full_dirent *fd, *fds; 968 struct jffs2_full_dirent *fd, *fds;
969 int deleted; 969 int deleted;
970 970
971 jffs2_clear_acl(f);
971 jffs2_xattr_delete_inode(c, f->inocache); 972 jffs2_xattr_delete_inode(c, f->inocache);
972 down(&f->sem); 973 down(&f->sem);
973 deleted = f->inocache && !f->inocache->nlink; 974 deleted = f->inocache && !f->inocache->nlink;
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 2bfdc33752d3..e2413466ddd5 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -274,8 +274,8 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
274 return ret; 274 return ret;
275} 275}
276 276
277int jffs2_fill_scan_buf (struct jffs2_sb_info *c, void *buf, 277static int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf,
278 uint32_t ofs, uint32_t len) 278 uint32_t ofs, uint32_t len)
279{ 279{
280 int ret; 280 int ret;
281 size_t retlen; 281 size_t retlen;
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index 18e66dbf23b4..25bc1ae08648 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -50,9 +50,10 @@
50 * is used to write xdatum to medium. xd->version will be incremented. 50 * is used to write xdatum to medium. xd->version will be incremented.
51 * create_xattr_datum(c, xprefix, xname, xvalue, xsize) 51 * create_xattr_datum(c, xprefix, xname, xvalue, xsize)
52 * is used to create new xdatum and write to medium. 52 * is used to create new xdatum and write to medium.
53 * delete_xattr_datum(c, xd) 53 * unrefer_xattr_datum(c, xd)
54 * is used to delete a xdatum. It marks xd JFFS2_XFLAGS_DEAD, and allows 54 * is used to delete a xdatum. When nobody refers this xdatum, JFFS2_XFLAGS_DEAD
55 * GC to reclaim those physical nodes. 55 * is set on xd->flags and chained xattr_dead_list or release it immediately.
56 * In the first case, the garbage collector release it later.
56 * -------------------------------------------------- */ 57 * -------------------------------------------------- */
57static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize) 58static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize)
58{ 59{
@@ -394,22 +395,24 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
394 return xd; 395 return xd;
395} 396}
396 397
397static void delete_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) 398static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
398{ 399{
399 /* must be called under down_write(xattr_sem) */ 400 /* must be called under down_write(xattr_sem) */
400 BUG_ON(atomic_read(&xd->refcnt)); 401 if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) {
402 uint32_t xid = xd->xid, version = xd->version;
401 403
402 unload_xattr_datum(c, xd); 404 unload_xattr_datum(c, xd);
403 xd->flags |= JFFS2_XFLAGS_DEAD; 405 xd->flags |= JFFS2_XFLAGS_DEAD;
404 spin_lock(&c->erase_completion_lock); 406 if (xd->node == (void *)xd) {
405 if (xd->node == (void *)xd) { 407 BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID));
406 BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID)); 408 jffs2_free_xattr_datum(xd);
407 jffs2_free_xattr_datum(xd); 409 } else {
408 } else { 410 list_add(&xd->xindex, &c->xattr_dead_list);
409 list_add(&xd->xindex, &c->xattr_dead_list); 411 }
412 spin_unlock(&c->erase_completion_lock);
413
414 dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n", xid, version);
410 } 415 }
411 spin_unlock(&c->erase_completion_lock);
412 dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n", xd->xid, xd->version);
413} 416}
414 417
415/* -------- xref related functions ------------------ 418/* -------- xref related functions ------------------
@@ -580,8 +583,7 @@ static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *re
580 dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n", 583 dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n",
581 ref->ino, ref->xid, ref->xseqno); 584 ref->ino, ref->xid, ref->xseqno);
582 585
583 if (atomic_dec_and_test(&xd->refcnt)) 586 unrefer_xattr_datum(c, xd);
584 delete_xattr_datum(c, xd);
585} 587}
586 588
587void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) 589void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
@@ -1119,8 +1121,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1119 ref->next = c->xref_dead_list; 1121 ref->next = c->xref_dead_list;
1120 c->xref_dead_list = ref; 1122 c->xref_dead_list = ref;
1121 spin_unlock(&c->erase_completion_lock); 1123 spin_unlock(&c->erase_completion_lock);
1122 if (atomic_dec_and_test(&xd->refcnt)) 1124 unrefer_xattr_datum(c, xd);
1123 delete_xattr_datum(c, xd);
1124 } else { 1125 } else {
1125 ref->ic = ic; 1126 ref->ic = ic;
1126 ref->xd = xd; 1127 ref->xd = xd;
@@ -1156,8 +1157,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1156 down_write(&c->xattr_sem); 1157 down_write(&c->xattr_sem);
1157 if (rc) { 1158 if (rc) {
1158 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request); 1159 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
1159 if (atomic_dec_and_test(&xd->refcnt)) 1160 unrefer_xattr_datum(c, xd);
1160 delete_xattr_datum(c, xd);
1161 up_write(&c->xattr_sem); 1161 up_write(&c->xattr_sem);
1162 return rc; 1162 return rc;
1163 } 1163 }
@@ -1170,8 +1170,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1170 ic->xref = ref; 1170 ic->xref = ref;
1171 } 1171 }
1172 rc = PTR_ERR(newref); 1172 rc = PTR_ERR(newref);
1173 if (atomic_dec_and_test(&xd->refcnt)) 1173 unrefer_xattr_datum(c, xd);
1174 delete_xattr_datum(c, xd);
1175 } else if (ref) { 1174 } else if (ref) {
1176 delete_xattr_ref(c, ref); 1175 delete_xattr_ref(c, ref);
1177 } 1176 }