[Tux3] [RFC] Refactor create_entry and find_entry to work with xattrs

Daniel Phillips phillips at phunq.net
Thu Dec 11 23:49:26 PST 2008


Here is my proposal for a minimal change to make dir.c ops work with
xattr atoms, without relying on i_size to determine the size of the
atom directory, which is at the bottom of a sparse file that also
contains the atom refcounts and atom reverse map way up high.  The
kernel block IO library requires the i_size point above those tables,
otherwise it will not transfer data to them, and will return zeroes
instead of any data written up there (just reviewing for anybody who
has not been following this little issue).

I think the real problem is that the kernel block library is trying
to be too helpful here, or we are using it for a purpose for which
it was not intended.  Eventually we will most probably stop using the
block IO library entirely, because it provides an overly constricted
interface.  We could start on that process with a relatively simple
situation like the atom tables, setting up our own bio transfers.  But
that is an optimization for later, right now we need to make it work
with the block IO library one way or another.

I think this is about the simplest interface change.  For xattrs,
instead of passing i_size, we pass an atom size value in the sb and
load/save_sb it to disk.

We are likely to change this again after a while, but for now this
will let us test xattr support in kernel and we can concentrate on
more important issues.

Regards,

Daniel

diff -r ad6aff100867 user/kernel/dir.c
--- a/user/kernel/dir.c	Thu Dec 11 19:32:14 2008 -0800
+++ b/user/kernel/dir.c	Thu Dec 11 23:29:04 2008 -0800
@@ -105,13 +105,13 @@
 	[S_IFLNK >> STAT_SHIFT] = TUX_LNK,
 };
 
-loff_t tux_create_entry(struct inode *dir, const char *name, int len, inum_t inum, unsigned mode)
+loff_t _tux_create_entry(struct inode *dir, const char *name, int len, inum_t inum, unsigned mode, loff_t *size)
 {
 	tux_dirent *entry;
 	struct buffer_head *buffer;
 	unsigned reclen = TUX_REC_LEN(len), rec_len, name_len, offset;
 	unsigned blockbits = tux_sb(dir->i_sb)->blockbits, blocksize = 1 << blockbits;
-	unsigned blocks = dir->i_size >> blockbits, block;
+	unsigned blocks = *size >> blockbits, block;
 	for (block = 0; block < blocks; block++) {
 		buffer = blockread(mapping(dir), block);
 		if (!buffer)
@@ -139,7 +139,7 @@
 	name_len = 0;
 	rec_len = blocksize;
 	*entry = (tux_dirent){ .rec_len = tux_rec_len_to_disk(blocksize) };
-	dir->i_size += blocksize;
+	*size += blocksize;
 create:
 	if (!is_deleted(entry)) {
 		tux_dirent *newent = (tux_dirent *)((char *)entry + name_len);
@@ -158,11 +158,11 @@
 	return (block << blockbits) + offset; /* only needed for xattr create */
 }
 
-tux_dirent *tux_find_entry(struct inode *dir, const char *name, int len, struct buffer_head **result)
+tux_dirent *_tux_find_entry(struct inode *dir, const char *name, int len, struct buffer_head **result, loff_t size)
 {
 	unsigned reclen = TUX_REC_LEN(len);
 	unsigned blocksize = 1 << tux_sb(dir->i_sb)->blockbits;
-	unsigned blocks = dir->i_size >> tux_sb(dir->i_sb)->blockbits, block;
+	unsigned blocks = size >> tux_sb(dir->i_sb)->blockbits, block;
 	int err = -ENOENT;
 	for (block = 0; block < blocks; block++) {
 		struct buffer_head *buffer = blockread(mapping(dir), block);
@@ -190,6 +190,16 @@
 error:
 	*result = NULL;		/* for debug */
 	return ERR_PTR(err);
+}
+
+loff_t tux_create_entry(struct inode *dir, const char *name, int len, inum_t inum, unsigned mode)
+{
+	return _tux_create_entry(dir, name, len, inum, mode, &dir->i_size);
+}
+
+tux_dirent *tux_find_entry(struct inode *dir, const char *name, int len, struct buffer_head **result)
+{
+	return _tux_find_entry(dir, name, len, result, dir->i_size);
 }
 
 static unsigned char filetype[TUX_TYPES] = {
diff -r ad6aff100867 user/kernel/iattr.c
--- a/user/kernel/iattr.c	Thu Dec 11 19:32:14 2008 -0800
+++ b/user/kernel/iattr.c	Thu Dec 11 23:29:04 2008 -0800
@@ -150,7 +150,7 @@
 			break;
 		case CTIME_SIZE_ATTR:
 			attrs = decode48(attrs, &v64);
-			attrs = decode64(attrs, &inode->i_size);
+			attrs = decode64(attrs, (u64 *)&inode->i_size); // decode to temp?
 			inode->i_ctime = spectime(v64 << TIME_ATTR_SHIFT);
 			break;
 		case MTIME_ATTR:
diff -r ad6aff100867 user/kernel/tux3.h
--- a/user/kernel/tux3.h	Thu Dec 11 19:32:14 2008 -0800
+++ b/user/kernel/tux3.h	Thu Dec 11 23:29:04 2008 -0800
@@ -280,7 +280,7 @@
 	struct xcache *xcache;
 	struct sb *i_sb;
 	map_t *map;
-	u64 i_size;
+	loff_t i_size;
 	unsigned i_version;
 	struct timespec i_mtime, i_ctime, i_atime;
 	unsigned i_mode, i_uid, i_gid, i_nlink;

_______________________________________________
Tux3 mailing list
Tux3 at tux3.org
http://mailman.tux3.org/cgi-bin/mailman/listinfo/tux3



More information about the Tux3 mailing list