diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-04 00:29:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-04 00:29:08 -0400 |
commit | 0d1782144e81faf6203075c5fcd0a2f0db91af5b (patch) | |
tree | 761dd18870e97ec9c6c14bc1c4db1429065483c0 /fs/jffs2 | |
parent | 67ab33db8be1cd466c09dfcba334d69d3e2f92e6 (diff) | |
parent | c7afb0f97700e73109564f83c35bfeeb14cb653b (diff) |
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6:
[JFFS2][XATTR] Fix memory leak in POSIX-ACL support
fs/jffs2/: make 2 functions static
[MTD] NAND: Fix broken sharpsl driver
[JFFS2][XATTR] Fix xd->refcnt race condition
MTD: kernel-doc fixes + additions
MTD: fix all kernel-doc warnings
[MTD] DOC: Fixup read functions and do a little cleanup
Diffstat (limited to 'fs/jffs2')
-rw-r--r-- | fs/jffs2/acl.c | 4 | ||||
-rw-r--r-- | fs/jffs2/acl.h | 4 | ||||
-rw-r--r-- | fs/jffs2/malloc.c | 2 | ||||
-rw-r--r-- | fs/jffs2/nodelist.h | 2 | ||||
-rw-r--r-- | fs/jffs2/readinode.c | 1 | ||||
-rw-r--r-- | fs/jffs2/scan.c | 4 | ||||
-rw-r--r-- | fs/jffs2/xattr.c | 45 |
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 | ||
348 | void jffs2_clear_acl(struct inode *inode) | 348 | void 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 { | |||
30 | extern int jffs2_permission(struct inode *, int, struct nameidata *); | 30 | extern int jffs2_permission(struct inode *, int, struct nameidata *); |
31 | extern int jffs2_acl_chmod(struct inode *); | 31 | extern int jffs2_acl_chmod(struct inode *); |
32 | extern int jffs2_init_acl(struct inode *, struct inode *); | 32 | extern int jffs2_init_acl(struct inode *, struct inode *); |
33 | extern void jffs2_clear_acl(struct inode *); | 33 | extern void jffs2_clear_acl(struct jffs2_inode_info *); |
34 | 34 | ||
35 | extern struct xattr_handler jffs2_acl_access_xattr_handler; | 35 | extern struct xattr_handler jffs2_acl_access_xattr_handler; |
36 | extern struct xattr_handler jffs2_acl_default_xattr_handler; | 36 | extern 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 | ||
193 | struct jffs2_raw_node_ref *jffs2_alloc_refblock(void) | 193 | static 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 */ |
427 | int jffs2_scan_medium(struct jffs2_sb_info *c); | 427 | int jffs2_scan_medium(struct jffs2_sb_info *c); |
428 | void jffs2_rotate_lists(struct jffs2_sb_info *c); | 428 | void jffs2_rotate_lists(struct jffs2_sb_info *c); |
429 | int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf, | ||
430 | uint32_t ofs, uint32_t len); | ||
431 | struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino); | 429 | struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino); |
432 | int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); | 430 | int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); |
433 | int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t size); | 431 | int 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 | ||
277 | int jffs2_fill_scan_buf (struct jffs2_sb_info *c, void *buf, | 277 | static 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 | * -------------------------------------------------- */ |
57 | static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize) | 58 | static 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 | ||
397 | static void delete_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) | 398 | static 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 | ||
587 | void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) | 589 | void 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 | } |