Commit 8f2b6f49 authored by KaiGai Kohei's avatar KaiGai Kohei

[JFFS2][XATTR] Remove 'struct list_head ilist' from jffs2_inode_cache.

This patch can reduce 4-byte of memory usage per inode_cache.

[4/10] jffs2-xattr-v5.1-04-remove_ilist_from_ic.patch
Signed-off-by: default avatarKaiGai Kohei <kaigai@ak.jp.nec.com>
parent 8b0b339d
...@@ -119,8 +119,8 @@ struct jffs2_sb_info { ...@@ -119,8 +119,8 @@ struct jffs2_sb_info {
#define XATTRINDEX_HASHSIZE (57) #define XATTRINDEX_HASHSIZE (57)
uint32_t highest_xid; uint32_t highest_xid;
struct list_head xattrindex[XATTRINDEX_HASHSIZE]; struct list_head xattrindex[XATTRINDEX_HASHSIZE];
struct list_head xattr_temp;
struct list_head xattr_unchecked; struct list_head xattr_unchecked;
struct jffs2_xattr_ref *xref_temp;
struct rw_semaphore xattr_sem; struct rw_semaphore xattr_sem;
uint32_t xdatum_mem_usage; uint32_t xdatum_mem_usage;
uint32_t xdatum_mem_threshold; uint32_t xdatum_mem_threshold;
......
...@@ -259,7 +259,6 @@ struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void) ...@@ -259,7 +259,6 @@ struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void)
memset(ref, 0, sizeof(struct jffs2_xattr_ref)); memset(ref, 0, sizeof(struct jffs2_xattr_ref));
ref->class = RAWNODE_CLASS_XATTR_REF; ref->class = RAWNODE_CLASS_XATTR_REF;
INIT_LIST_HEAD(&ref->ilist);
return ref; return ref;
} }
......
...@@ -117,7 +117,7 @@ struct jffs2_inode_cache { ...@@ -117,7 +117,7 @@ struct jffs2_inode_cache {
uint32_t ino; uint32_t ino;
int nlink; int nlink;
#ifdef CONFIG_JFFS2_FS_XATTR #ifdef CONFIG_JFFS2_FS_XATTR
struct list_head ilist; struct jffs2_xattr_ref *xref;
#endif #endif
}; };
......
...@@ -902,7 +902,6 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, ...@@ -902,7 +902,6 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
f->inocache->ino = f->inocache->nlink = 1; f->inocache->ino = f->inocache->nlink = 1;
f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
f->inocache->state = INO_STATE_READING; f->inocache->state = INO_STATE_READING;
init_xattr_inode_cache(f->inocache);
jffs2_add_ino_cache(c, f->inocache); jffs2_add_ino_cache(c, f->inocache);
} }
if (!f->inocache) { if (!f->inocache) {
......
...@@ -408,14 +408,15 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock ...@@ -408,14 +408,15 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock
* ref->xid is used to store 32bit xid, xd is not used * ref->xid is used to store 32bit xid, xd is not used
* ref->ino is used to store 32bit inode-number, ic is not used * ref->ino is used to store 32bit inode-number, ic is not used
* Thoes variables are declared as union, thus using those * Thoes variables are declared as union, thus using those
* are exclusive. In a similar way, ref->ilist is temporarily * are exclusive. In a similar way, ref->next is temporarily
* used to chain all xattr_ref object. It's re-chained to * used to chain all xattr_ref object. It's re-chained to
* jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly. * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly.
*/ */
ref->node = raw; ref->node = raw;
ref->ino = je32_to_cpu(rr->ino); ref->ino = je32_to_cpu(rr->ino);
ref->xid = je32_to_cpu(rr->xid); ref->xid = je32_to_cpu(rr->xid);
list_add_tail(&ref->ilist, &c->xattr_temp); ref->next = c->xref_temp;
c->xref_temp = ref;
raw->__totlen = PAD(je32_to_cpu(rr->totlen)); raw->__totlen = PAD(je32_to_cpu(rr->totlen));
raw->flash_offset = ofs | REF_PRISTINE; raw->flash_offset = ofs | REF_PRISTINE;
...@@ -888,7 +889,6 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin ...@@ -888,7 +889,6 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin
ic->ino = ino; ic->ino = ino;
ic->nodes = (void *)ic; ic->nodes = (void *)ic;
init_xattr_inode_cache(ic);
jffs2_add_ino_cache(c, ic); jffs2_add_ino_cache(c, ic);
if (ino == 1) if (ino == 1)
ic->nlink = 1; ic->nlink = 1;
......
...@@ -556,7 +556,8 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras ...@@ -556,7 +556,8 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
ref->ino = 0xfffffffe; ref->ino = 0xfffffffe;
ref->xid = 0xfffffffd; ref->xid = 0xfffffffd;
ref->node = raw; ref->node = raw;
list_add_tail(&ref->ilist, &c->xattr_temp); ref->next = c->xref_temp;
c->xref_temp = ref;
raw->__totlen = PAD(sizeof(struct jffs2_raw_xref)); raw->__totlen = PAD(sizeof(struct jffs2_raw_xref));
raw->flash_offset = ofs | REF_UNCHECKED; raw->flash_offset = ofs | REF_UNCHECKED;
......
...@@ -36,7 +36,6 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint ...@@ -36,7 +36,6 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
f->inocache->nlink = 1; f->inocache->nlink = 1;
f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
f->inocache->state = INO_STATE_PRESENT; f->inocache->state = INO_STATE_PRESENT;
init_xattr_inode_cache(f->inocache);
jffs2_add_ino_cache(c, f->inocache); jffs2_add_ino_cache(c, f->inocache);
D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino)); D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino));
......
...@@ -456,7 +456,7 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c, ...@@ -456,7 +456,7 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
* is called to remove xrefs related to obsolete inode when inode is unlinked. * is called to remove xrefs related to obsolete inode when inode is unlinked.
* jffs2_xattr_free_inode(c, ic) * jffs2_xattr_free_inode(c, ic)
* is called to release xattr related objects when unmounting. * is called to release xattr related objects when unmounting.
* check_xattr_ref_ilist(c, ic) * check_xattr_ref_inode(c, ic)
* is used to confirm inode does not have duplicate xattr name/value pair. * is used to confirm inode does not have duplicate xattr name/value pair.
* -------------------------------------------------- */ * -------------------------------------------------- */
static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
...@@ -549,7 +549,6 @@ static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *re ...@@ -549,7 +549,6 @@ static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *re
BUG_ON(!ref->node); BUG_ON(!ref->node);
delete_xattr_ref_node(c, ref); delete_xattr_ref_node(c, ref);
list_del(&ref->ilist);
xd = ref->xd; xd = ref->xd;
xd->refcnt--; xd->refcnt--;
if (!xd->refcnt) if (!xd->refcnt)
...@@ -629,7 +628,8 @@ static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct ...@@ -629,7 +628,8 @@ static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct
} }
/* Chain to inode */ /* Chain to inode */
list_add(&ref->ilist, &ic->ilist); ref->next = ic->xref;
ic->xref = ref;
return ref; /* success */ return ref; /* success */
} }
...@@ -644,8 +644,11 @@ void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache ...@@ -644,8 +644,11 @@ void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache
return; return;
down_write(&c->xattr_sem); down_write(&c->xattr_sem);
list_for_each_entry_safe(ref, _ref, &ic->ilist, ilist) for (ref = ic->xref; ref; ref = _ref) {
_ref = ref->next;
delete_xattr_ref(c, ref); delete_xattr_ref(c, ref);
}
ic->xref = NULL;
up_write(&c->xattr_sem); up_write(&c->xattr_sem);
} }
...@@ -656,8 +659,8 @@ void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i ...@@ -656,8 +659,8 @@ void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i
struct jffs2_xattr_ref *ref, *_ref; struct jffs2_xattr_ref *ref, *_ref;
down_write(&c->xattr_sem); down_write(&c->xattr_sem);
list_for_each_entry_safe(ref, _ref, &ic->ilist, ilist) { for (ref = ic->xref; ref; ref = _ref) {
list_del(&ref->ilist); _ref = ref->next;
xd = ref->xd; xd = ref->xd;
xd->refcnt--; xd->refcnt--;
if (!xd->refcnt) { if (!xd->refcnt) {
...@@ -666,16 +669,17 @@ void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i ...@@ -666,16 +669,17 @@ void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i
} }
jffs2_free_xattr_ref(ref); jffs2_free_xattr_ref(ref);
} }
ic->xref = NULL;
up_write(&c->xattr_sem); up_write(&c->xattr_sem);
} }
static int check_xattr_ref_ilist(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
{ {
/* success of check_xattr_ref_ilist() means taht inode (ic) dose not have /* success of check_xattr_ref_inode() means taht inode (ic) dose not have
* duplicate name/value pairs. If duplicate name/value pair would be found, * duplicate name/value pairs. If duplicate name/value pair would be found,
* one will be removed. * one will be removed.
*/ */
struct jffs2_xattr_ref *ref, *cmp; struct jffs2_xattr_ref *ref, *cmp, **pref;
int rc = 0; int rc = 0;
if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED)) if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
...@@ -683,22 +687,23 @@ static int check_xattr_ref_ilist(struct jffs2_sb_info *c, struct jffs2_inode_cac ...@@ -683,22 +687,23 @@ static int check_xattr_ref_ilist(struct jffs2_sb_info *c, struct jffs2_inode_cac
down_write(&c->xattr_sem); down_write(&c->xattr_sem);
retry: retry:
rc = 0; rc = 0;
list_for_each_entry(ref, &ic->ilist, ilist) { for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
if (!ref->xd->xname) { if (!ref->xd->xname) {
rc = load_xattr_datum(c, ref->xd); rc = load_xattr_datum(c, ref->xd);
if (unlikely(rc > 0)) { if (unlikely(rc > 0)) {
*pref = ref->next;
delete_xattr_ref(c, ref); delete_xattr_ref(c, ref);
goto retry; goto retry;
} else if (unlikely(rc < 0)) } else if (unlikely(rc < 0))
goto out; goto out;
} }
cmp = ref; for (cmp=ref->next, pref=&ref->next; cmp; pref=&cmp->next, cmp=cmp->next) {
list_for_each_entry_continue(cmp, &ic->ilist, ilist) {
if (!cmp->xd->xname) { if (!cmp->xd->xname) {
ref->xd->flags |= JFFS2_XFLAGS_BIND; ref->xd->flags |= JFFS2_XFLAGS_BIND;
rc = load_xattr_datum(c, cmp->xd); rc = load_xattr_datum(c, cmp->xd);
ref->xd->flags &= ~JFFS2_XFLAGS_BIND; ref->xd->flags &= ~JFFS2_XFLAGS_BIND;
if (unlikely(rc > 0)) { if (unlikely(rc > 0)) {
*pref = cmp->next;
delete_xattr_ref(c, cmp); delete_xattr_ref(c, cmp);
goto retry; goto retry;
} else if (unlikely(rc < 0)) } else if (unlikely(rc < 0))
...@@ -706,6 +711,7 @@ static int check_xattr_ref_ilist(struct jffs2_sb_info *c, struct jffs2_inode_cac ...@@ -706,6 +711,7 @@ static int check_xattr_ref_ilist(struct jffs2_sb_info *c, struct jffs2_inode_cac
} }
if (ref->xd->xprefix == cmp->xd->xprefix if (ref->xd->xprefix == cmp->xd->xprefix
&& !strcmp(ref->xd->xname, cmp->xd->xname)) { && !strcmp(ref->xd->xname, cmp->xd->xname)) {
*pref = cmp->next;
delete_xattr_ref(c, cmp); delete_xattr_ref(c, cmp);
goto retry; goto retry;
} }
...@@ -736,8 +742,8 @@ void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c) ...@@ -736,8 +742,8 @@ void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c)
for (i=0; i < XATTRINDEX_HASHSIZE; i++) for (i=0; i < XATTRINDEX_HASHSIZE; i++)
INIT_LIST_HEAD(&c->xattrindex[i]); INIT_LIST_HEAD(&c->xattrindex[i]);
INIT_LIST_HEAD(&c->xattr_temp);
INIT_LIST_HEAD(&c->xattr_unchecked); INIT_LIST_HEAD(&c->xattr_unchecked);
c->xref_temp = NULL;
init_rwsem(&c->xattr_sem); init_rwsem(&c->xattr_sem);
c->xdatum_mem_usage = 0; c->xdatum_mem_usage = 0;
...@@ -765,8 +771,11 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c) ...@@ -765,8 +771,11 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
struct jffs2_xattr_ref *ref, *_ref; struct jffs2_xattr_ref *ref, *_ref;
int i; int i;
list_for_each_entry_safe(ref, _ref, &c->xattr_temp, ilist) for (ref=c->xref_temp; ref; ref = _ref) {
_ref = ref->next;
jffs2_free_xattr_ref(ref); jffs2_free_xattr_ref(ref);
}
c->xref_temp = NULL;
for (i=0; i < XATTRINDEX_HASHSIZE; i++) { for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) { list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
...@@ -788,8 +797,8 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) ...@@ -788,8 +797,8 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING)); BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
/* Phase.1 */ /* Phase.1 */
list_for_each_entry_safe(ref, _ref, &c->xattr_temp, ilist) { for (ref=c->xref_temp; ref; ref=_ref) {
list_del_init(&ref->ilist); _ref = ref->next;
/* checking REF_UNCHECKED nodes */ /* checking REF_UNCHECKED nodes */
if (ref_flags(ref->node) != REF_PRISTINE) { if (ref_flags(ref->node) != REF_PRISTINE) {
if (verify_xattr_ref(c, ref)) { if (verify_xattr_ref(c, ref)) {
...@@ -813,9 +822,11 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) ...@@ -813,9 +822,11 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
ref->xd = xd; ref->xd = xd;
ref->ic = ic; ref->ic = ic;
xd->refcnt++; xd->refcnt++;
list_add_tail(&ref->ilist, &ic->ilist); ref->next = ic->xref;
ic->xref = ref;
xref_count++; xref_count++;
} }
c->xref_temp = NULL;
/* After this, ref->xid/ino are NEVER used. */ /* After this, ref->xid/ino are NEVER used. */
/* Phase.2 */ /* Phase.2 */
...@@ -931,20 +942,20 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) ...@@ -931,20 +942,20 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
struct jffs2_inode_cache *ic = f->inocache; struct jffs2_inode_cache *ic = f->inocache;
struct jffs2_xattr_ref *ref; struct jffs2_xattr_ref *ref, **pref;
struct jffs2_xattr_datum *xd; struct jffs2_xattr_datum *xd;
struct xattr_handler *xhandle; struct xattr_handler *xhandle;
ssize_t len, rc; ssize_t len, rc;
int retry = 0; int retry = 0;
rc = check_xattr_ref_ilist(c, ic); rc = check_xattr_ref_inode(c, ic);
if (unlikely(rc)) if (unlikely(rc))
return rc; return rc;
down_read(&c->xattr_sem); down_read(&c->xattr_sem);
retry: retry:
len = 0; len = 0;
list_for_each_entry(ref, &ic->ilist, ilist) { for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
BUG_ON(ref->ic != ic); BUG_ON(ref->ic != ic);
xd = ref->xd; xd = ref->xd;
if (!xd->xname) { if (!xd->xname) {
...@@ -957,6 +968,7 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) ...@@ -957,6 +968,7 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
} else { } else {
rc = load_xattr_datum(c, xd); rc = load_xattr_datum(c, xd);
if (unlikely(rc > 0)) { if (unlikely(rc > 0)) {
*pref = ref->next;
delete_xattr_ref(c, ref); delete_xattr_ref(c, ref);
goto retry; goto retry;
} else if (unlikely(rc < 0)) } else if (unlikely(rc < 0))
...@@ -992,16 +1004,16 @@ int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname, ...@@ -992,16 +1004,16 @@ int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
struct jffs2_inode_cache *ic = f->inocache; struct jffs2_inode_cache *ic = f->inocache;
struct jffs2_xattr_datum *xd; struct jffs2_xattr_datum *xd;
struct jffs2_xattr_ref *ref; struct jffs2_xattr_ref *ref, **pref;
int rc, retry = 0; int rc, retry = 0;
rc = check_xattr_ref_ilist(c, ic); rc = check_xattr_ref_inode(c, ic);
if (unlikely(rc)) if (unlikely(rc))
return rc; return rc;
down_read(&c->xattr_sem); down_read(&c->xattr_sem);
retry: retry:
list_for_each_entry(ref, &ic->ilist, ilist) { for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
BUG_ON(ref->ic!=ic); BUG_ON(ref->ic!=ic);
xd = ref->xd; xd = ref->xd;
...@@ -1017,6 +1029,7 @@ int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname, ...@@ -1017,6 +1029,7 @@ int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
} else { } else {
rc = load_xattr_datum(c, xd); rc = load_xattr_datum(c, xd);
if (unlikely(rc > 0)) { if (unlikely(rc > 0)) {
*pref = ref->next;
delete_xattr_ref(c, ref); delete_xattr_ref(c, ref);
goto retry; goto retry;
} else if (unlikely(rc < 0)) { } else if (unlikely(rc < 0)) {
...@@ -1053,11 +1066,11 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, ...@@ -1053,11 +1066,11 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
struct jffs2_inode_cache *ic = f->inocache; struct jffs2_inode_cache *ic = f->inocache;
struct jffs2_xattr_datum *xd; struct jffs2_xattr_datum *xd;
struct jffs2_xattr_ref *ref, *newref; struct jffs2_xattr_ref *ref, *newref, **pref;
uint32_t phys_ofs, length, request; uint32_t phys_ofs, length, request;
int rc; int rc;
rc = check_xattr_ref_ilist(c, ic); rc = check_xattr_ref_inode(c, ic);
if (unlikely(rc)) if (unlikely(rc))
return rc; return rc;
...@@ -1072,13 +1085,14 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, ...@@ -1072,13 +1085,14 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
/* Find existing xattr */ /* Find existing xattr */
down_write(&c->xattr_sem); down_write(&c->xattr_sem);
retry: retry:
list_for_each_entry(ref, &ic->ilist, ilist) { for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
xd = ref->xd; xd = ref->xd;
if (xd->xprefix != xprefix) if (xd->xprefix != xprefix)
continue; continue;
if (!xd->xname) { if (!xd->xname) {
rc = load_xattr_datum(c, xd); rc = load_xattr_datum(c, xd);
if (unlikely(rc > 0)) { if (unlikely(rc > 0)) {
*pref = ref->next;
delete_xattr_ref(c, ref); delete_xattr_ref(c, ref);
goto retry; goto retry;
} else if (unlikely(rc < 0)) } else if (unlikely(rc < 0))
...@@ -1090,6 +1104,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, ...@@ -1090,6 +1104,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
goto out; goto out;
} }
if (!buffer) { if (!buffer) {
*pref = ref->next;
delete_xattr_ref(c, ref); delete_xattr_ref(c, ref);
rc = 0; rc = 0;
goto out; goto out;
...@@ -1098,7 +1113,6 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, ...@@ -1098,7 +1113,6 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
} }
} }
/* not found */ /* not found */
ref = NULL;
if (flags & XATTR_REPLACE) { if (flags & XATTR_REPLACE) {
rc = -ENODATA; rc = -ENODATA;
goto out; goto out;
...@@ -1130,14 +1144,19 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, ...@@ -1130,14 +1144,19 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
return rc; return rc;
} }
down_write(&c->xattr_sem); down_write(&c->xattr_sem);
if (ref)
*pref = ref->next;
newref = create_xattr_ref(c, ic, xd, phys_ofs); newref = create_xattr_ref(c, ic, xd, phys_ofs);
if (IS_ERR(newref)) { if (IS_ERR(newref)) {
if (ref) {
ref->next = ic->xref;
ic->xref = ref;
}
rc = PTR_ERR(newref); rc = PTR_ERR(newref);
xd->refcnt--; xd->refcnt--;
if (!xd->refcnt) if (!xd->refcnt)
delete_xattr_datum(c, xd); delete_xattr_datum(c, xd);
} else if (ref) { } else if (ref) {
/* If replaced xattr_ref exists */
delete_xattr_ref(c, ref); delete_xattr_ref(c, ref);
} }
out: out:
......
...@@ -54,7 +54,7 @@ struct jffs2_xattr_ref ...@@ -54,7 +54,7 @@ struct jffs2_xattr_ref
struct jffs2_xattr_datum *xd; /* reference to jffs2_xattr_datum */ struct jffs2_xattr_datum *xd; /* reference to jffs2_xattr_datum */
uint32_t xid; /* only used in sccanning/building */ uint32_t xid; /* only used in sccanning/building */
}; };
struct list_head ilist; /* chained from ic->ilist */ struct jffs2_xattr_ref *next; /* chained from ic->xref_list */
}; };
#ifdef CONFIG_JFFS2_FS_XATTR #ifdef CONFIG_JFFS2_FS_XATTR
...@@ -86,9 +86,6 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); ...@@ -86,9 +86,6 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t);
#define jffs2_setxattr generic_setxattr #define jffs2_setxattr generic_setxattr
#define jffs2_removexattr generic_removexattr #define jffs2_removexattr generic_removexattr
/*---- Any inline initialize functions ----*/
#define init_xattr_inode_cache(x) INIT_LIST_HEAD(&((x)->ilist))
#else #else
#define jffs2_init_xattr_subsystem(c) #define jffs2_init_xattr_subsystem(c)
...@@ -106,8 +103,6 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); ...@@ -106,8 +103,6 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t);
#define jffs2_setxattr NULL #define jffs2_setxattr NULL
#define jffs2_removexattr NULL #define jffs2_removexattr NULL
#define init_xattr_inode_cache(x)
#endif /* CONFIG_JFFS2_FS_XATTR */ #endif /* CONFIG_JFFS2_FS_XATTR */
#ifdef CONFIG_JFFS2_FS_SECURITY #ifdef CONFIG_JFFS2_FS_SECURITY
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment