This is Hirofumi's earlier patch, with attribute numbering slightly
changed.  Attributes are now numbered from zero, with rdev = 0.
This tries to finalize numbering of attributes, but is still not final.
See the atkind enum in tux3.h.

With this patch, Tux3 will boot as rootfs (and succeed in opening the
console device, which otherwise is not possible).

Daniel
diff -r e034620d446a user/iattr.c
--- a/user/iattr.c	Tue Feb 24 06:40:53 2009 +0900
+++ b/user/iattr.c	Sat Feb 28 15:08:39 2009 -0800
@@ -32,7 +32,6 @@ int main(int argc, char *argv[])
 	};
 
 	char attrs[1000] = { };
-	printf("%i attributes starting from %i\n", MAX_ATTRS - MIN_ATTR, MIN_ATTR);
 	printf("need %i attr bytes\n", encode_asize(abits));
 	printf("decode %ti attr bytes\n", sizeof(attrs));
 	decode_attrs(inode, attrs, sizeof(attrs));
diff -r e034620d446a user/kernel/iattr.c
--- a/user/kernel/iattr.c	Tue Feb 24 06:40:53 2009 +0900
+++ b/user/kernel/iattr.c	Sat Feb 28 15:08:39 2009 -0800
@@ -23,6 +23,7 @@ unsigned atsize[MAX_ATTRS] = {
 	[DATA_BTREE_ATTR] = 8,
 	[LINK_COUNT_ATTR] = 4,
 	[MTIME_ATTR] = 6,
+	[RDEV_ATTR] = 8,
 	[IDATA_ATTR] = 2,
 	[XATTR_ATTR] = 4,
 };
@@ -30,7 +31,7 @@ unsigned encode_asize(unsigned bits)
 unsigned encode_asize(unsigned bits)
 {
 	unsigned need = 0;
-	for (int kind = MIN_ATTR; kind < VAR_ATTRS; kind++)
+	for (int kind = 0; kind < VAR_ATTRS; kind++)
 		if ((bits & (1 << kind)))
 			need += atsize[kind] + 2;
 	return need;
@@ -45,7 +46,7 @@ int attr_check(void *attrs, unsigned siz
 	{
 		attrs = decode16(attrs, &head);
 		unsigned kind = head >> 12;
-		if (kind < MIN_ATTR || kind >= MAX_ATTRS)
+		if (kind >= MAX_ATTRS)
 			return 0;
 		if (attrs + atsize[kind] > limit)
 			return 0;
@@ -77,6 +78,9 @@ void dump_attrs(struct inode *inode)
 		case DATA_BTREE_ATTR:
 			printf("root %Lx:%u ", (L)tuxnode->btree.root.block, tuxnode->btree.root.depth);
 			break;
+		case RDEV_ATTR:
+			printf("rdev %x:%x ", MAJOR(inode->i_rdev), MINOR(inode->i_rdev));
+			break;
 		case XATTR_ATTR:
 			printf("xattr(s) ");
 			break;
@@ -93,7 +97,7 @@ void *encode_attrs(struct inode *inode, 
 	trace_off("encode %u attr bytes", size);
 	tuxnode_t *tuxnode = tux_inode(inode);
 	void *limit = attrs + size - 3;
-	for (int kind = MIN_ATTR; kind < VAR_ATTRS; kind++) {
+	for (int kind = 0; kind < VAR_ATTRS; kind++) {
 		if (!(tuxnode->present & (1 << kind)))
 			continue;
 		if (attrs >= limit)
@@ -117,6 +121,9 @@ void *encode_attrs(struct inode *inode, 
 			break;
 		case DATA_BTREE_ATTR:
 			attrs = encode64(attrs, pack_root(&tuxnode->btree.root));
+			break;
+		case RDEV_ATTR:
+			attrs = encode64(attrs, huge_encode_dev(inode->i_rdev));
 			break;
 		}
 	}
@@ -165,6 +172,10 @@ void *decode_attrs(struct inode *inode, 
 			attrs = decode64(attrs, &v64);
 			init_btree(&tuxnode->btree, sb, unpack_root(v64), &dtree_ops);
 			break;
+		case RDEV_ATTR:
+			attrs = decode64(attrs, &v64);
+			inode->i_rdev = huge_decode_dev(v64);
+			break;
 		case XATTR_ATTR:;
 			// immediate xattr: kind+version:16, bytes:16, atom:16, data[bytes - 2]
 			unsigned bytes, atom;
diff -r e034620d446a user/kernel/inode.c
--- a/user/kernel/inode.c	Tue Feb 24 06:40:53 2009 +0900
+++ b/user/kernel/inode.c	Sat Feb 28 15:08:39 2009 -0800
@@ -20,34 +20,34 @@ static int check_present(struct inode *i
 	switch (inode->i_mode & S_IFMT) {
 	default:
 		assert(tuxnode->present & MODE_OWNER_BIT);
-		/* FIXME: assert(!(tuxnode->present & RDEV_BIT)) */
+		assert(!(tuxnode->present & RDEV_BIT));
 		break;
 	case S_IFBLK:
 	case S_IFCHR:
 		assert(tuxnode->present & MODE_OWNER_BIT);
-		/* FIXME: assert(tuxnode->present & RDEV_BIT) */
+//		assert(tuxnode->present & RDEV_BIT);
 		break;
 	case S_IFREG:
 		assert(tuxnode->present & MODE_OWNER_BIT);
 		assert(tuxnode->present & DATA_BTREE_BIT);
-		/* FIXME: assert(!(tuxnode->present & RDEV_BIT)) */
+		assert(!(tuxnode->present & RDEV_BIT));
 		break;
 	case S_IFDIR:
 		assert(tuxnode->present & MODE_OWNER_BIT);
 		assert(tuxnode->present & DATA_BTREE_BIT);
-		/* FIXME: assert(!(tuxnode->present & RDEV_BIT)) */
+		assert(!(tuxnode->present & RDEV_BIT));
 		break;
 	case S_IFLNK:
 		assert(tuxnode->present & MODE_OWNER_BIT);
 		assert(tuxnode->present & DATA_BTREE_BIT);
-		/* FIXME: assert(!(tuxnode->present & RDEV_BIT)) */
+		assert(!(tuxnode->present & RDEV_BIT));
 		break;
 	case 0:
 		if (tux_inode(inode)->inum == TUX_VOLMAP_INO)
 			assert(tuxnode->present == 0);
 		else {
 			assert(tuxnode->present & DATA_BTREE_BIT);
-			/* FIXME: assert(!(tuxnode->present & RDEV_BIT)) */
+			assert(!(tuxnode->present & RDEV_BIT));
 		}
 		break;
 	}
@@ -84,6 +84,8 @@ struct inode *tux_new_inode(struct inode
 		inode->i_nlink++;
 	tux_set_inum(inode, TUX_INVALID_INO);
 	tux_inode(inode)->present = CTIME_SIZE_BIT|MTIME_BIT|MODE_OWNER_BIT|DATA_BTREE_BIT|LINK_COUNT_BIT;
+	if (rdev)
+		tux_inode(inode)->present |= RDEV_BIT;
 	tux_setup_inode(inode, rdev);
 	return inode;
 }
diff -r e034620d446a user/kernel/namei.c
--- a/user/kernel/namei.c	Tue Feb 24 06:40:53 2009 +0900
+++ b/user/kernel/namei.c	Sat Feb 28 15:08:39 2009 -0800
@@ -63,8 +63,8 @@ static int tux3_mknod(struct inode *dir,
 	struct inode *inode;
 	int err;
 
-//	if (!huge_valid_dev(rdev))
-//		return -EINVAL;
+	if (!huge_valid_dev(rdev))
+		return -EINVAL;
 
 	change_begin(tux_sb(dir->i_sb));
 	inode = tux_create_inode(dir, mode, rdev);
diff -r e034620d446a user/kernel/tux3.h
--- a/user/kernel/tux3.h	Tue Feb 24 06:40:53 2009 +0900
+++ b/user/kernel/tux3.h	Sat Feb 28 15:08:39 2009 -0800
@@ -207,8 +207,8 @@ static inline void flink_last_del(struct
 
 /* Tux3 disk format */
 
-#define SB_MAGIC_SIZE 8
-#define SB_MAGIC { 't', 'u', 'x', '3', 0xdd, 0x08, 0x12, 0x12 } /* date of latest incompatible sb format */
+#define SB_MAGIC_SIZE 8 /* includes date of latest incompatible disk format */
+#define SB_MAGIC { 't', 'u', 'x', '3', 0xdd, 0x09, 0x02, 0x28 }
 /*
  * disk format revision history
  * !!! always update this for every incompatible change !!!
@@ -216,6 +216,7 @@ static inline void flink_last_del(struct
  * 2008-08-06: Beginning of time
  * 2008-09-06: Actual checking starts
  * 2008-12-12: Atom dictionary size in disksuper instead of atable->i_size
+ * 2008-02-28: Attributes renumbered, rdev added
  */
 
 #define MAX_INODES_BITS 48
@@ -241,9 +242,7 @@ struct disksuper
 	be_u64 birthdate;	/* Volume creation date */
 	be_u64 flags;		/* Need to assign some flags */
 	be_u64 iroot;		/* Root of the inode table btree */
-	be_u64 unused;		/* The atime table is a file now, delete on next format rev */
 	be_u16 blockbits;	/* Shift to get volume block size */
-	be_u16 unused1;		/* Throw away on next format rev */
 	be_u64 volblocks;	/* Volume size */
 	/* The rest should be moved to a "metablock" that is updated frequently */
 	be_u64 freeblocks;	/* Should match total of zero bits in allocation bitmap */
@@ -646,16 +645,24 @@ int update_bitmap(struct sb *sb, block_t
 int update_bitmap(struct sb *sb, block_t start, unsigned count, int set);
 
 enum atkind {
-	MIN_ATTR = 6,
-	MODE_OWNER_ATTR = 6,
-	DATA_BTREE_ATTR = 7,
-	CTIME_SIZE_ATTR = 8,
-	LINK_COUNT_ATTR = 9,
-	MTIME_ATTR = 10,
+	RDEV_ATTR = 0,
+	MODE_OWNER_ATTR = 1,
+	DATA_BTREE_ATTR = 2,
+	CTIME_SIZE_ATTR = 3,
+	LINK_COUNT_ATTR = 4,
+	MTIME_ATTR = 5,
+	// <i_blocks, part of CTIME_SIZE?> = 6
+	// <generation?> = 7
+	// <i_version?> = 8
+	// <future fixed attribute> = 9
+	// <more fixed kinds> = 10
+	VAR_ATTRS,
 	IDATA_ATTR = 11,
 	XATTR_ATTR = 12,
-	MAX_ATTRS,
-	VAR_ATTRS = IDATA_ATTR
+	// <dedicated acl?> = 13
+	// <allocation hints?> = 14
+	// <more variable kinds> = 15
+	MAX_ATTRS
 };
 
 enum atbit {
@@ -664,6 +671,7 @@ enum atbit {
 	DATA_BTREE_BIT = 1 << DATA_BTREE_ATTR,
 	LINK_COUNT_BIT = 1 << LINK_COUNT_ATTR,
 	MTIME_BIT = 1 << MTIME_ATTR,
+	RDEV_BIT = 1 << RDEV_ATTR,
 	IDATA_BIT = 1 << IDATA_ATTR,
 	XATTR_BIT = 1 << XATTR_ATTR,
 };
diff -r e034620d446a user/tux3.h
--- a/user/tux3.h	Tue Feb 24 06:40:53 2009 +0900
+++ b/user/tux3.h	Sat Feb 28 15:08:39 2009 -0800
@@ -190,6 +190,42 @@ struct tux_iattr {
 	unsigned mode, uid, gid;
 };
 
+#define MINORBITS	20
+#define MINORMASK	((1U << MINORBITS) - 1)
+
+#define MAJOR(dev)	((unsigned int) ((dev) >> MINORBITS))
+#define MINOR(dev)	((unsigned int) ((dev) & MINORMASK))
+#define MKDEV(ma,mi)	(((ma) << MINORBITS) | (mi))
+
+static inline u32 new_encode_dev(dev_t dev)
+{
+	unsigned major = MAJOR(dev);
+	unsigned minor = MINOR(dev);
+	return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
+}
+
+static inline dev_t new_decode_dev(u32 dev)
+{
+	unsigned major = (dev & 0xfff00) >> 8;
+	unsigned minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);
+	return MKDEV(major, minor);
+}
+
+static inline int huge_valid_dev(dev_t dev)
+{
+	return 1;
+}
+
+static inline u64 huge_encode_dev(dev_t dev)
+{
+	return new_encode_dev(dev);
+}
+
+static inline dev_t huge_decode_dev(u64 dev)
+{
+	return new_decode_dev(dev);
+}
+
 #define mark_btree_dirty(x) do {} while (0)
 
 void change_begin(struct sb *sb);
_______________________________________________
Tux3 mailing list
Tux3@tux3.org
http://mailman.tux3.org/cgi-bin/mailman/listinfo/tux3

Reply via email to