diff options
author | KaiGai Kohei <kaigai@ak.jp.nec.com> | 2006-06-23 20:16:50 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-06-27 11:19:06 -0400 |
commit | 2c887e2359f6e7217cdaa17994ca94ef328b658f (patch) | |
tree | 4af246384893ec0b18380aacb97cc0f2a0226ec8 | |
parent | 355ed4e141203fd7266ef9d90d57be0c61bd1aa4 (diff) |
[JFFS2][XATTR] Re-define xd->refcnt as atomic_t
In jffs2_release_xattr_datum(), it refers xd->refcnt to ensure
whether releasing xd is allowed or not.
But we can't hold xattr_sem since this function is called under
spin_lock(&c->erase_completion_lock). Thus we have to refer it
without any locking.
This patch redefine xd->refcnt as atomic_t. It enables to refer
xd->refcnt without any locking.
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r-- | fs/jffs2/xattr.c | 25 | ||||
-rw-r--r-- | fs/jffs2/xattr.h | 2 |
2 files changed, 12 insertions, 15 deletions
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 7622f79cb5b4..18e66dbf23b4 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c | |||
@@ -345,7 +345,7 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c, | |||
345 | && xd->value_len==xsize | 345 | && xd->value_len==xsize |
346 | && !strcmp(xd->xname, xname) | 346 | && !strcmp(xd->xname, xname) |
347 | && !memcmp(xd->xvalue, xvalue, xsize)) { | 347 | && !memcmp(xd->xvalue, xvalue, xsize)) { |
348 | xd->refcnt++; | 348 | atomic_inc(&xd->refcnt); |
349 | return xd; | 349 | return xd; |
350 | } | 350 | } |
351 | } | 351 | } |
@@ -365,7 +365,7 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c, | |||
365 | strcpy(data, xname); | 365 | strcpy(data, xname); |
366 | memcpy(data + name_len + 1, xvalue, xsize); | 366 | memcpy(data + name_len + 1, xvalue, xsize); |
367 | 367 | ||
368 | xd->refcnt = 1; | 368 | atomic_set(&xd->refcnt, 1); |
369 | xd->xid = ++c->highest_xid; | 369 | xd->xid = ++c->highest_xid; |
370 | xd->flags |= JFFS2_XFLAGS_HOT; | 370 | xd->flags |= JFFS2_XFLAGS_HOT; |
371 | xd->xprefix = xprefix; | 371 | xd->xprefix = xprefix; |
@@ -397,7 +397,7 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c, | |||
397 | static void delete_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) | 397 | static void delete_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) |
398 | { | 398 | { |
399 | /* must be called under down_write(xattr_sem) */ | 399 | /* must be called under down_write(xattr_sem) */ |
400 | BUG_ON(xd->refcnt); | 400 | BUG_ON(atomic_read(&xd->refcnt)); |
401 | 401 | ||
402 | unload_xattr_datum(c, xd); | 402 | unload_xattr_datum(c, xd); |
403 | xd->flags |= JFFS2_XFLAGS_DEAD; | 403 | xd->flags |= JFFS2_XFLAGS_DEAD; |
@@ -580,7 +580,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", | 580 | dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n", |
581 | ref->ino, ref->xid, ref->xseqno); | 581 | ref->ino, ref->xid, ref->xseqno); |
582 | 582 | ||
583 | if (!--xd->refcnt) | 583 | if (atomic_dec_and_test(&xd->refcnt)) |
584 | delete_xattr_datum(c, xd); | 584 | delete_xattr_datum(c, xd); |
585 | } | 585 | } |
586 | 586 | ||
@@ -612,8 +612,7 @@ void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i | |||
612 | for (ref = ic->xref; ref; ref = _ref) { | 612 | for (ref = ic->xref; ref; ref = _ref) { |
613 | _ref = ref->next; | 613 | _ref = ref->next; |
614 | xd = ref->xd; | 614 | xd = ref->xd; |
615 | xd->refcnt--; | 615 | if (atomic_dec_and_test(&xd->refcnt)) { |
616 | if (!xd->refcnt) { | ||
617 | unload_xattr_datum(c, xd); | 616 | unload_xattr_datum(c, xd); |
618 | jffs2_free_xattr_datum(xd); | 617 | jffs2_free_xattr_datum(xd); |
619 | } | 618 | } |
@@ -835,7 +834,7 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) | |||
835 | } | 834 | } |
836 | ref->xd = xd; | 835 | ref->xd = xd; |
837 | ref->ic = ic; | 836 | ref->ic = ic; |
838 | xd->refcnt++; | 837 | atomic_inc(&xd->refcnt); |
839 | ref->next = ic->xref; | 838 | ref->next = ic->xref; |
840 | ic->xref = ref; | 839 | ic->xref = ref; |
841 | } | 840 | } |
@@ -846,7 +845,7 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) | |||
846 | list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) { | 845 | list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) { |
847 | xdatum_count++; | 846 | xdatum_count++; |
848 | list_del_init(&xd->xindex); | 847 | list_del_init(&xd->xindex); |
849 | if (!xd->refcnt) { | 848 | if (!atomic_read(&xd->refcnt)) { |
850 | dbg_xattr("xdatum(xid=%u, version=%u) is orphan.\n", | 849 | dbg_xattr("xdatum(xid=%u, version=%u) is orphan.\n", |
851 | xd->xid, xd->version); | 850 | xd->xid, xd->version); |
852 | xd->flags |= JFFS2_XFLAGS_DEAD; | 851 | xd->flags |= JFFS2_XFLAGS_DEAD; |
@@ -1120,7 +1119,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, | |||
1120 | ref->next = c->xref_dead_list; | 1119 | ref->next = c->xref_dead_list; |
1121 | c->xref_dead_list = ref; | 1120 | c->xref_dead_list = ref; |
1122 | spin_unlock(&c->erase_completion_lock); | 1121 | spin_unlock(&c->erase_completion_lock); |
1123 | if (!--xd->refcnt) | 1122 | if (atomic_dec_and_test(&xd->refcnt)) |
1124 | delete_xattr_datum(c, xd); | 1123 | delete_xattr_datum(c, xd); |
1125 | } else { | 1124 | } else { |
1126 | ref->ic = ic; | 1125 | ref->ic = ic; |
@@ -1157,8 +1156,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, | |||
1157 | down_write(&c->xattr_sem); | 1156 | down_write(&c->xattr_sem); |
1158 | if (rc) { | 1157 | if (rc) { |
1159 | JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request); | 1158 | JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request); |
1160 | xd->refcnt--; | 1159 | if (atomic_dec_and_test(&xd->refcnt)) |
1161 | if (!xd->refcnt) | ||
1162 | delete_xattr_datum(c, xd); | 1160 | delete_xattr_datum(c, xd); |
1163 | up_write(&c->xattr_sem); | 1161 | up_write(&c->xattr_sem); |
1164 | return rc; | 1162 | return rc; |
@@ -1172,8 +1170,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, | |||
1172 | ic->xref = ref; | 1170 | ic->xref = ref; |
1173 | } | 1171 | } |
1174 | rc = PTR_ERR(newref); | 1172 | rc = PTR_ERR(newref); |
1175 | xd->refcnt--; | 1173 | if (atomic_dec_and_test(&xd->refcnt)) |
1176 | if (!xd->refcnt) | ||
1177 | delete_xattr_datum(c, xd); | 1174 | delete_xattr_datum(c, xd); |
1178 | } else if (ref) { | 1175 | } else if (ref) { |
1179 | delete_xattr_ref(c, ref); | 1176 | delete_xattr_ref(c, ref); |
@@ -1304,7 +1301,7 @@ int jffs2_verify_xattr(struct jffs2_sb_info *c) | |||
1304 | void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) | 1301 | void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) |
1305 | { | 1302 | { |
1306 | /* must be called under spin_lock(&c->erase_completion_lock) */ | 1303 | /* must be called under spin_lock(&c->erase_completion_lock) */ |
1307 | if (xd->refcnt > 0 || xd->node != (void *)xd) | 1304 | if (atomic_read(&xd->refcnt) || xd->node != (void *)xd) |
1308 | return; | 1305 | return; |
1309 | 1306 | ||
1310 | list_del(&xd->xindex); | 1307 | list_del(&xd->xindex); |
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h index 4a10abc6d917..06a5c69dcf8b 100644 --- a/fs/jffs2/xattr.h +++ b/fs/jffs2/xattr.h | |||
@@ -28,7 +28,7 @@ struct jffs2_xattr_datum | |||
28 | uint16_t xprefix; /* see JFFS2_XATTR_PREFIX_* */ | 28 | uint16_t xprefix; /* see JFFS2_XATTR_PREFIX_* */ |
29 | 29 | ||
30 | struct list_head xindex; /* chained from c->xattrindex[n] */ | 30 | struct list_head xindex; /* chained from c->xattrindex[n] */ |
31 | uint32_t refcnt; /* # of xattr_ref refers this */ | 31 | atomic_t refcnt; /* # of xattr_ref refers this */ |
32 | uint32_t xid; | 32 | uint32_t xid; |
33 | uint32_t version; | 33 | uint32_t version; |
34 | 34 | ||