mirror of https://gitee.com/openkylin/linux.git
[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: KaiGai Kohei <kaigai@ak.jp.nec.com>
This commit is contained in:
parent
8b0b339d46
commit
8f2b6f49c6
|
@ -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)
|
||||||
|
|
||||||
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 {
|
||||||
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,
|
||||||
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
|
||||||
* 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
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
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,
|
||||||
* 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
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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
|
||||||
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
|
||||||
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
|
||||||
}
|
}
|
||||||
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
|
||||||
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
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
} 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,
|
||||||
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,
|
||||||
} 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,
|
||||||
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,
|
||||||
/* 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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* 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,
|
||||||
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
|
||||||
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);
|
||||||
#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);
|
||||||
#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
|
||||||
|
|
Loading…
Reference in New Issue