[PATCH] XATTR issues on JFFS2

Kaigai Kohei kaigai at ak.jp.nec.com
Tue Aug 23 06:24:31 EDT 2005


Hello,

The attached patch provids XATTR support in JFFS2.
We can apply it to mtd-snapshot-20050822.tar.bz2 tree.

I hope your worthwhile comments for improvement.
# By coincidence, two patches for similar functionality are posted in same day :)
# I changed the subject of this mail a bit to avoid confusion.

This implementation added two new node types JFFS2_NODETYPE_XATTR
and JFFS2_NODETYPE_XREF.
JFFS2_NODETYPE_XATTR node has a set of XATTR entry which contains
name and value. It's represented as jffs2_raw_xattr structure on MTD-device.
JFFS2_NODETYPE_XREF node has a set of reference to associate inode with XATTR.
It's represented as jffs2_raw_xref structure on MTD-device.

* Data Structure
 - jffs2_xattr_cache
  This object contains XATTR name/value. It must be refered by an inode
  at least. When the last inode which refers jffs2_xattr_cache is unlinked,
  jffs2_xattr_cache will be deleted.
  XATTR name/value is not loaded until inode object is allocated.

 - jffs2_xattr_ref
  This object refers jffs2_inode_cache and jffs2_xattr_cache, and chains each other.
  When we walk on ref->ilist from jffs2_inode_cache, we can scan all the XATTR which
  is bound to this inode. Adversely, we can scan all the inode which refers this
  XATTR, when we walk on ref->xlist from jffs2_xattr_cache.

struct jffs2_xattr_cache
{
        struct list_head xcache; <-- It's chained from struct jffs2_sb_info (global hash list).
        struct list_head xlist;  <-- jffs2_xattr_ref is chained on this list.
        struct jffs2_raw_node_ref *node;

        uint32_t xid;            <-- Unique Identifier
        uint32_t version;

        uint32_t crc;
        char *xname;    /* XATTR name */   <--
        char *xvalue;   /* XATTR value */
        int xsize;      /* size of XATTR value */
};

struct jffs2_xattr_ref
{
        uint32_t seqno;         /* sequencial number */
        uint32_t flags;
        struct list_head ilist; /* list from jffs2_inode_cache */
        struct list_head xlist; /* list from jffs2_xattr_cache */
        struct jffs2_xattr_cache *xc;
        struct jffs2_inode_cache *ic;
        struct jffs2_raw_node_ref *node;
};


* How to work

[1] FS mounting
When jffs2 is mounting, xattrcache which is array of list_head
is created by kmalloc() on jffs2_sb_info first.

Then jffs2_scan_eraseblock() is called on each erase block,
and jffs2_scan_xattr_node() and jffs2_scan_xref_node() are
used to treat two new node-type.
jffs2_scan_xattr_node() create jffs2_xattr_cache object and chain
it to xattrcache. jffs2_scan_xref_node() create jffs2_xattr_ref
object and chain it to temporary list.

Next, jffs2_build_xattr_caches() is called. This function associate
jffs2_inode_cache with jffs2_xattr_cache by using jffs2_xattr_ref.
(struct jffs2_xattr_ref *)ref->ilist ... Chained jffs2_inode_cache
(struct jffs2_xattr_ref *)ref->xlist ... Chained jffs2_xattr_cache

[2] inode-creation
When inode object is created, jffs2_get_xattr_inode() will be called.
It walks on ilist on inode-cache and calls do_load_xattr_cache() for
related XATTR object to load XATTR name/value.

[3] getxattr/setxattr
We can refer an jffs2_inode_cache object in {get|set}xattr handler,
and walks on jffs2_inode_cache->ilist for looking up target XATTR.
In setxattr case, do_create_xattr_cache() is called for creation
new XATTR-node, then do_delete_xattr_ref() is used for old-node.


* Example of use

[root at saba ~]# dd if=jffs2.xattr.img of=/dev/mtdblock0
8192+0 records in
8192+0 records out
[root at saba ~]# mount -t jffs2 /dev/mtdblock0 /mnt/0
[root at saba ~]# ls -lZ /mnt/0
drwxr-xr-x  root     root     system_u:object_r:bin_t          bin/
drwxr-xr-x  root     root     system_u:object_r:mnt_t          dev/
drwxr-xr-x  root     root     system_u:object_r:etc_t          etc/
-rw-r--r--  root     root     system_u:object_r:mnt_t          hoge
-rwxr-xr-x  root     root     system_u:object_r:mnt_t          init*
drwxr-xr-x  root     root     system_u:object_r:lib_t          lib/
drwxr-xr-x  root     root     system_u:object_r:mnt_t          loopfs/
drwxr-xr-x  root     root     system_u:object_r:mnt_t          proc/
lrwxrwxrwx  root     root     system_u:object_r:bin_t          sbin
drwxr-xr-x  root     root     system_u:object_r:mnt_t          sys/
drwxr-xr-x  root     root     system_u:object_r:mnt_t          sysroot/
[root at saba ~]#


* ToDo List

(1) stabilization
 o more tests and debugging are necessary. I hope any trouble reporting.
   I don't have real MTD device. This implementation is developed on
   MTD-RAM pseudo device. Does it work on real MTD-devices ?

(2) performance & scalability
 o Currently, any XATTR objects are guarded by a xattr_sem. But this
   implementation is not scale, I guess. To divid locking is necessary.
 o When setxattr() is called, the system scans XATTR cache to look for
   same combination of name/value and share it.
   But it's so expensive process, to reduce finding-step is necessary.

(3) more functionality
 o Currently, only XATTR has "security.*" prefix is supported.
   It's enough to use SELinux, but that's more useful if we can use
   POSIX-ACL and so on.
 o modifying mkfs.jffs2 command.

Thanks,
-- 
Linux Promotion Center, NEC
KaiGai Kohei <kaigai at ak.jp.nec.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: jffs2_xattr_take-1.patch
Type: text/x-patch
Size: 45733 bytes
Desc: not available
Url : http://lists.infradead.org/pipermail/linux-mtd/attachments/20050823/8d35c504/attachment.bin 


More information about the linux-mtd mailing list