From: Kaigai Kohei <kaigai@ak.jp.nec.com>
To: "Jörn Engel" <joern@wohnheim.fh-wedel.de>, linux-mtd@lists.infradead.org
Cc: James Morris <jmorris@redhat.com>, Ma Yun <sx_yunma@hotmail.com>,
David Woodhouse <dwmw2@infradead.org>,
Stephen Smalley <sds@tycho.nsa.gov>,
Kaigai Kohei <kaigai@ak.jp.nec.com>
Subject: Re: [PATCH] XATTR issues on JFFS2
Date: Wed, 12 Oct 2005 13:25:58 +0900 [thread overview]
Message-ID: <434C9056.4020600@ak.jp.nec.com> (raw)
In-Reply-To: <433A57D8.9030501@ak.jp.nec.com>
[-- Attachment #1: Type: text/plain, Size: 987 bytes --]
Hi,
The attached patch adds an functionality for mkfs.jffs2.
'-A' or '--with-xattr' enables to stuff up any xattr-imforamations
for each files into JFFS2 image file.
This patch depends on 'jffs2_xattr_take-3.patch' I posted on 28-Sep.
In addition, some constants of JFFS2_XPREFIX_* are moved from
fs/jffs2/xattr.h to include/linux/jffs2.h, because I want to
use those constants in mkfs.jffs2. This change has no effects
in kernel-side.
Perhaps, another style like '--with-selinux' or '--with-acl' might
be better than '--with-xattr'.
Any comments please,
Thanks.
Kaigai Kohei wrote:
> Hi,
>
> I revised the previous xattr patch in jffs2 based on some suggestions.
>
> [1] scanning xattr related node for cleaned-up scan.c.
> (jffs2_xattr_scan.c-cleanup.patch)
> [2] enables xattr support in jffs2.
> (jffs2_xattr_take-3.patch)
> (*) We can apply jffs2_xattr_take-3.patch for current CVS independently.
--
Linux Promotion Center, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>
[-- Attachment #2: mkfs.jffs2-xattr.patch --]
[-- Type: text/x-patch, Size: 12246 bytes --]
diff -prNU3 mtd-051011.xattr/fs/jffs2/xattr.c mtd-051011.xattr-mkfs/fs/jffs2/xattr.c
--- mtd-051011.xattr/fs/jffs2/xattr.c 2005-10-12 11:33:37.000000000 +0900
+++ mtd-051011.xattr-mkfs/fs/jffs2/xattr.c 2005-10-12 11:34:39.000000000 +0900
@@ -42,6 +42,7 @@ static int do_jffs2_setxattr(struct inod
const char *buffer, size_t size, int flags);
/* ---- XATTR Handler for "user.*" --------------------- */
+#define XATTR_USER_PREFIX "user."
static int jffs2_user_getxattr(struct inode *inode, const char *name,
void *buffer, size_t size)
{
@@ -97,6 +98,7 @@ static struct xattr_handler jffs2_user_x
};
/* ---- XATTR Handler for "trusted.*" ------------------ */
+#define XATTR_TRUSTED_PREFIX "trusted."
static int jffs2_trusted_getxattr(struct inode *inode, const char *name,
void *buffer, size_t size)
{
diff -prNU3 mtd-051011.xattr/fs/jffs2/xattr.h mtd-051011.xattr-mkfs/fs/jffs2/xattr.h
--- mtd-051011.xattr/fs/jffs2/xattr.h 2005-10-12 11:33:37.000000000 +0900
+++ mtd-051011.xattr-mkfs/fs/jffs2/xattr.h 2005-10-12 11:34:39.000000000 +0900
@@ -14,16 +14,6 @@
#include <linux/xattr.h>
#define XATTRINDEX_HASHSIZE (57)
-#define XATTR_USER_PREFIX "user."
-#define XATTR_TRUSTED_PREFIX "trusted."
-
-#define JFFS2_XPREFIX_USER 1 /* for "user.*" */
-#define JFFS2_XPREFIX_SECURITY 2 /* for "security.*" */
-#define JFFS2_XPREFIX_ACL_ACCESS 3 /* for "system.posix_acl_access" */
-#define JFFS2_XPREFIX_ACL_DEFAULT 4 /* for "system.posix_acl_default" */
-#define JFFS2_XPREFIX_TRUSTED 5 /* for "trusted.*" */
-#define JFFS2_XPREFIX_INVALID 6
-
#define JFFS2_XDATUM_FLAGS_HOT 0x01 /* This is hot xattr_datum */
#define RAWNODE_CLASS_INODE_CACHE 0
diff -prNU3 mtd-051011.xattr/include/linux/jffs2.h mtd-051011.xattr-mkfs/include/linux/jffs2.h
--- mtd-051011.xattr/include/linux/jffs2.h 2005-10-12 11:33:37.000000000 +0900
+++ mtd-051011.xattr-mkfs/include/linux/jffs2.h 2005-10-12 11:34:39.000000000 +0900
@@ -68,6 +68,13 @@
#define JFFS2_NODETYPE_XATTR (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 8)
#define JFFS2_NODETYPE_XREF (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 9)
+/* XATTR Related */
+#define JFFS2_XPREFIX_USER 1 /* for "user." */
+#define JFFS2_XPREFIX_SECURITY 2 /* for "security." */
+#define JFFS2_XPREFIX_ACL_ACCESS 3 /* for "system.posix_acl_access" */
+#define JFFS2_XPREFIX_ACL_DEFAULT 4 /* for "system.posix_acl_default" */
+#define JFFS2_XPREFIX_TRUSTED 5 /* for "trusted.*" */
+
// Maybe later...
//#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
//#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4)
diff -prNU3 mtd-051011.xattr/util/mkfs.jffs2.1 mtd-051011.xattr-mkfs/util/mkfs.jffs2.1
--- mtd-051011.xattr/util/mkfs.jffs2.1 2005-09-15 21:18:43.000000000 +0900
+++ mtd-051011.xattr-mkfs/util/mkfs.jffs2.1 2005-10-12 11:34:39.000000000 +0900
@@ -49,6 +49,9 @@ mkfs.jffs2 \- Create a JFFS2 file system
.B -P,--squash-perms
]
[
+.B -A,--with-xattr
+]
+[
.B -m,--compression-mode=MODE
]
[
@@ -178,6 +181,9 @@ Squash owners making all files be owned
.B -P, --squash-perms
Squash permissions, removing write permission for \'group\' and \'other\'.
.TP
+.B -A, --with-xattr
+Include XATTR meta information. It's necessary for SELinux or ACL support.
+.TP
.B -m, --compression-mode=MODE
Set the default compression mode. The default mode is
.B priority
diff -prNU3 mtd-051011.xattr/util/mkfs.jffs2.c mtd-051011.xattr-mkfs/util/mkfs.jffs2.c
--- mtd-051011.xattr/util/mkfs.jffs2.c 2005-09-15 21:18:43.000000000 +0900
+++ mtd-051011.xattr-mkfs/util/mkfs.jffs2.c 2005-10-12 11:55:09.000000000 +0900
@@ -7,6 +7,7 @@
* 2002 Axis Communications AB
* 2001, 2002 Erik Andersen <andersen@codepoet.org>
* 2004 University of Szeged, Hungary
+ * 2005 KaiGai Kohei <kaigai@ak.jp.nec.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -63,6 +64,7 @@
#include <ctype.h>
#include <time.h>
#include <getopt.h>
+#include <attr/xattr.h>
#include <byteswap.h>
#define crc32 __complete_crap
#include <zlib.h>
@@ -1018,6 +1020,166 @@ static void write_special_file(struct fi
padword();
}
+struct xattr_entry {
+ struct xattr_entry *next;
+ uint32_t xid;
+ int xprefix;
+ char *xname;
+ char *xvalue;
+ int value_len;
+};
+static int enable_xattr = 0;
+static uint32_t xseqno = 0;
+static struct {
+ int code;
+ char *string;
+ int length;
+} xprefix_tbl[] = {
+ { JFFS2_XPREFIX_USER, "user.", sizeof("user.")-1 },
+ { JFFS2_XPREFIX_SECURITY, "security.", sizeof("security.")-1 },
+// { JFFS2_XPREFIX_ACL_ACCESS, "system.posix_acl_access", sizeof("system.posix_acl_access")-1 },
+// { JFFS2_XPREFIX_ACL_DEFAULT, "system.posix_acl_default", sizeof("system.posix_acl_default")-1 },
+ { JFFS2_XPREFIX_TRUSTED, "trusted.", sizeof("trusted")-1 },
+ { 0, NULL, 0 }
+};
+
+static struct xattr_entry *create_xattr_entry(int xprefix, char *xname, char *xvalue, int value_len)
+{
+ struct xattr_entry *xe;
+ struct jffs2_raw_xattr rx;
+ int name_len, data_len;
+
+ name_len = strlen(xname);
+ data_len = name_len + 1 + value_len;
+ xe = xcalloc(1, sizeof(struct xattr_entry) + data_len);
+ xe->xid = ++xseqno;
+ xe->xprefix = xprefix;
+ xe->xname = (char *)(xe + 1);
+ xe->xvalue = xe->xname + name_len + 1;
+ xe->value_len = value_len;
+ strcpy(xe->xname, xname);
+ memcpy(xe->xvalue, xvalue, value_len);
+
+ memset(&rx, 0, sizeof(rx));
+ rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+ rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR);
+ rx.totlen = cpu_to_je32(sizeof(rx) + data_len);
+ rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4));
+
+ rx.xid = cpu_to_je32(xe->xid);
+ rx.xprefix = xprefix; /* 8bit width */
+ rx.name_len = name_len; /* 8bit width */
+ rx.value_len = cpu_to_je16(value_len);
+ rx.data_crc = cpu_to_je32(crc32(0, xe->xname, data_len));
+ rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(rx) - 8));
+
+ pad_block_if_less_than(sizeof(rx) + data_len);
+ full_write(out_fd, &rx, sizeof(rx));
+ full_write(out_fd, xe->xname, data_len);
+ padword();
+
+ return xe;
+}
+
+#define XATTRENTRY_HASHSIZE (256)
+static struct xattr_entry *find_xattr_entry(char *xname, char *xvalue, int value_len)
+{
+ static struct xattr_entry **xentry_hash = NULL;
+ struct xattr_entry *xe;
+ int i, name_len, xprefix, index;
+
+ /* -- lookup xprefix -- */
+ for (xprefix=0, i=0; xprefix_tbl[i].string; i++) {
+ char *prstr = xprefix_tbl[i].string;
+ int prlen = xprefix_tbl[i].length;
+ if (!strncmp(xname, prstr, prlen)) {
+ xprefix = xprefix_tbl[i].code;
+ xname += prlen;
+ break;
+ }
+ }
+ if (xprefix == 0)
+ return NULL;
+
+ /* -- find or create xattr entry -- */
+ if (!xentry_hash)
+ xentry_hash = xcalloc(1, sizeof(struct xattr_entry *) * XATTRENTRY_HASHSIZE);
+
+ name_len = strlen(xname) + 1;
+ index = (crc32(0, xname, name_len) ^ crc32(0, xvalue, value_len)) & XATTRENTRY_HASHSIZE;
+ for (xe = xentry_hash[index]; xe; xe = xe->next) {
+ if (xe->xprefix == xprefix
+ && xe->value_len == value_len
+ && !strcmp(xe->xname, xname)
+ && !memcmp(xe->xvalue, xvalue, value_len))
+ break;
+ }
+ if (!xe) {
+ xe = create_xattr_entry(xprefix, xname, xvalue, value_len);
+ xe->next = xentry_hash[index];
+ xentry_hash[index] = xe;
+ }
+
+ return xe;
+}
+
+#define XATTR_BUFSZ 65536
+static void write_xattr_entry(struct filesystem_entry *e)
+{
+ struct jffs2_raw_xref ref;
+ struct xattr_entry *xe;
+ char xlist[XATTR_BUFSZ], xvalue[XATTR_BUFSZ], filepath[PATH_MAX+1];
+ char *xname;
+ int list_sz, offset, name_len, value_len;
+
+ if (!enable_xattr)
+ return;
+
+ sprintf(filepath, "%s%s", rootdir, e->fullname);
+
+ list_sz = llistxattr(filepath, xlist, XATTR_BUFSZ);
+ if (list_sz < 0) {
+ if (verbose)
+ printf("llistxattr(\"%s\") returned %d:%s\n",
+ e->fullname, errno, strerror(errno));
+ return;
+ }
+
+ for (offset = 0; offset < list_sz; offset += name_len) {
+ xname = xlist+offset;
+ name_len = strlen(xname) + 1;
+
+ value_len = lgetxattr(filepath, xname, xvalue, XATTR_BUFSZ);
+ if (value_len < 0) {
+ if (verbose)
+ printf("lgetxattr(\"%s\", \"%s\") returned %d:%s\n",
+ e->fullname, xname, errno, strerror(errno));
+ continue;
+ }
+
+ xe = find_xattr_entry(xname, xvalue, value_len);
+ if (!xe) {
+ if (verbose)
+ printf("XATTR \"%s\" -- Not supported on \"%s\"\n", xname, e->fullname);
+ continue;
+ }
+
+ memset(&ref, 0, sizeof(ref));
+ ref.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+ ref.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF);
+ ref.totlen = cpu_to_je32(sizeof(ref));
+ ref.hdr_crc = cpu_to_je32(crc32(0, &ref, sizeof(struct jffs2_unknown_node) - 4));
+ ref.seqno = cpu_to_je32(++xseqno);
+ ref.ino = cpu_to_je32(e->sb.st_ino);
+ ref.xid = cpu_to_je32(xe->xid);
+ ref.node_crc = cpu_to_je32(crc32(0, &ref, sizeof(ref) - 4));
+
+ pad_block_if_less_than(sizeof(ref));
+ full_write(out_fd, &ref, sizeof(ref));
+ padword();
+ }
+}
+
static void recursive_populate_directory(struct filesystem_entry *dir)
{
struct filesystem_entry *e;
@@ -1025,9 +1187,10 @@ static void recursive_populate_directory
if (verbose) {
printf("%s\n", dir->fullname);
}
+ write_xattr_entry(dir); /* for '/' */
+
e = dir->files;
while (e) {
-
switch (e->sb.st_mode & S_IFMT) {
case S_IFDIR:
if (verbose) {
@@ -1037,6 +1200,7 @@ static void recursive_populate_directory
e->name);
}
write_pipe(e);
+ write_xattr_entry(e);
break;
case S_IFSOCK:
if (verbose) {
@@ -1045,6 +1209,7 @@ static void recursive_populate_directory
(int) e->sb.st_uid, (int) e->sb.st_gid, e->name);
}
write_pipe(e);
+ write_xattr_entry(e);
break;
case S_IFIFO:
if (verbose) {
@@ -1053,6 +1218,7 @@ static void recursive_populate_directory
(int) e->sb.st_uid, (int) e->sb.st_gid, e->name);
}
write_pipe(e);
+ write_xattr_entry(e);
break;
case S_IFCHR:
if (verbose) {
@@ -1062,6 +1228,7 @@ static void recursive_populate_directory
(int) e->sb.st_gid, e->name);
}
write_special_file(e);
+ write_xattr_entry(e);
break;
case S_IFBLK:
if (verbose) {
@@ -1071,6 +1238,7 @@ static void recursive_populate_directory
(int) e->sb.st_gid, e->name);
}
write_special_file(e);
+ write_xattr_entry(e);
break;
case S_IFLNK:
if (verbose) {
@@ -1080,6 +1248,7 @@ static void recursive_populate_directory
e->link);
}
write_symlink(e);
+ write_xattr_entry(e);
break;
case S_IFREG:
if (verbose) {
@@ -1088,6 +1257,7 @@ static void recursive_populate_directory
(int) e->sb.st_uid, (int) e->sb.st_gid, e->name);
}
write_regular_file(e);
+ write_xattr_entry(e);
break;
default:
error_msg("Unknown mode %o for %s", e->sb.st_mode,
@@ -1165,6 +1335,7 @@ static struct option long_options[] = {
{"test-compression", 0, NULL, 't'},
{"compressor-priority", 1, NULL, 'y'},
{"incremental", 1, NULL, 'i'},
+ {"with-xattr", 0, NULL, 'A'},
{NULL, 0, NULL, 0}
};
@@ -1200,7 +1371,8 @@ static char *helptext =
" -h, --help Display this help text\n"
" -v, --verbose Verbose operation\n"
" -V, --version Display version information\n"
- " -i, --incremental=FILE Parse FILE and generate appendage output for it\n\n";
+ " -i, --incremental=FILE Parse FILE and generate appendage output for it\n"
+ " -A, --with-xattr include XATTR meta informatin.\n\n";
static char *revtext = "$Revision: 1.45 $";
@@ -1353,7 +1525,7 @@ int main(int argc, char **argv)
jffs2_compressors_init();
while ((opt = getopt_long(argc, argv,
- "D:d:r:s:o:qUPfh?vVe:lbp::nc:m:x:X:Lty:i:", long_options, &c)) >= 0)
+ "D:d:r:s:o:qUPfh?vVe:lbp::nc:m:x:X:Lty:i:A", long_options, &c)) >= 0)
{
switch (opt) {
case 'D':
@@ -1515,6 +1687,9 @@ int main(int argc, char **argv)
perror_msg_and_die("cannot open (incremental) file");
}
break;
+ case 'A':
+ enable_xattr = 1;
+ break;
}
}
if (out_fd == -1) {
prev parent reply other threads:[~2005-10-12 4:28 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-08-23 10:24 [PATCH] XATTR issues on JFFS2 Kaigai Kohei
2005-08-23 12:46 ` Jörn Engel
2005-08-23 12:52 ` David Woodhouse
2005-08-24 9:49 ` Kaigai Kohei
2005-08-25 10:28 ` Kaigai Kohei
2005-08-25 14:12 ` Jörn Engel
2005-09-07 5:14 ` Kaigai Kohei
2005-09-08 19:49 ` Jörn Engel
2005-09-08 19:54 ` David Woodhouse
2005-09-09 4:15 ` Kaigai Kohei
2005-09-09 7:24 ` Jörn Engel
2005-09-10 4:15 ` KaiGai Kohei
2005-09-11 11:46 ` Jörn Engel
2005-09-12 2:17 ` Kaigai Kohei
2005-09-12 6:40 ` Jörn Engel
2005-09-12 11:01 ` Kaigai Kohei
2005-09-28 8:44 ` Kaigai Kohei
2005-09-29 7:45 ` Jörn Engel
2005-10-03 1:01 ` E-mail with attached file has not delivered yet. (Re: [PATCH] XATTR issues on JFFS2) Kaigai Kohei
2005-10-19 13:18 ` [PATCH] XATTR issues on JFFS2 Kaigai Kohei
2005-10-19 14:24 ` Jörn Engel
2005-10-20 2:01 ` Kaigai Kohei
2005-11-27 6:58 ` KaiGai Kohei
2005-11-27 9:43 ` KaiGai Kohei
2005-11-27 15:45 ` Artem B. Bityutskiy
2005-11-28 4:13 ` Kaigai Kohei
2005-12-03 4:38 ` KaiGai Kohei
2005-10-12 4:25 ` Kaigai Kohei [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=434C9056.4020600@ak.jp.nec.com \
--to=kaigai@ak.jp.nec.com \
--cc=dwmw2@infradead.org \
--cc=jmorris@redhat.com \
--cc=joern@wohnheim.fh-wedel.de \
--cc=linux-mtd@lists.infradead.org \
--cc=sds@tycho.nsa.gov \
--cc=sx_yunma@hotmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox