[Tux3] Patch: Basic SMP locking for xcache

Daniel Phillips phillips at phunq.net
Fri Dec 26 22:57:10 PST 2008


The lazy strategy here is to use the itable i_mutex for all xattr
operations, which is very crude.  It is just for now.

I also changed xcache_lookup to ERR_PTR, which was badly needed.

Regards,

Daniel

diff -r f534c917e9d2 user/kernel/tux3.h
--- a/user/kernel/tux3.h	Fri Dec 26 19:28:19 2008 -0800
+++ b/user/kernel/tux3.h	Fri Dec 26 22:52:13 2008 -0800
@@ -290,6 +290,7 @@ typedef struct inode {
 	unsigned i_version;
 	struct timespec i_mtime, i_ctime, i_atime;
 	unsigned i_mode, i_uid, i_gid, i_nlink;
+	struct mutex i_mutex;
 	dev_t i_rdev;
 } tuxnode_t;
 
diff -r f534c917e9d2 user/kernel/xattr.c
--- a/user/kernel/xattr.c	Fri Dec 26 19:28:19 2008 -0800
+++ b/user/kernel/xattr.c	Fri Dec 26 22:52:13 2008 -0800
@@ -264,7 +264,7 @@ bail:
 	return -1;
 }
 
-static struct xattr *xcache_lookup(struct xcache *xcache, unsigned atom, int *err)
+static struct xattr *xcache_lookup(struct xcache *xcache, unsigned atom)
 {
 	if (!xcache)
 		return NULL;
@@ -274,15 +274,10 @@ static struct xattr *xcache_lookup(struc
 		if (xattr->atom == atom)
 			return xattr;
 		if ((xattr = xcache_next(xattr)) > limit)
-			goto fail;
+			return ERR_PTR(-EINVAL);
 	}
 	assert(xattr == limit);
-null:
-	return NULL;
-fail:
-	*err = EINVAL;
-	error("corrupt xattrs");
-	goto null;
+	return ERR_PTR(-ENOATTR);
 }
 
 struct xcache *new_xcache(unsigned maxsize)
@@ -317,15 +312,17 @@ static inline int remove_old(struct xcac
  */
 static int xcache_update(struct inode *inode, unsigned atom, void *data, unsigned len, unsigned flags)
 {
-	int err = 0, use = 0;
+	int use = 0;
 	struct xcache *xcache = tux_inode(inode)->xcache;
-	struct xattr *xattr = xcache_lookup(xcache, atom, &err);
-	if (xattr) {
+	struct xattr *xattr = xcache_lookup(xcache, atom);
+	if (!IS_ERR(xattr)) {
 		if (flags & XATTR_CREATE)
 			return -EEXIST;
 		use -= remove_old(xcache, xattr);
-	} else if (flags & XATTR_REPLACE)
+	} else if (PTR_ERR(xattr) == -ENOATTR && (flags & XATTR_REPLACE))
 		return -ENOATTR;
+	else
+		return PTR_ERR(xattr);
 
 	/* Insert new */
 	unsigned more = sizeof(*xattr) + len;
@@ -356,46 +353,53 @@ static int xcache_update(struct inode *i
 
 struct xattr *get_xattr(struct inode *inode, char *name, unsigned len)
 {
-	int err = 0;
-	atom_t atom = find_atom(tux_sb(inode->i_sb)->atable, name, len);
+	struct inode *atable = tux_sb(inode->i_sb)->atable;
+	mutex_lock(&atable->i_mutex);
+	atom_t atom = find_atom(atable, name, len);
 	if (atom == -1)
-		return NULL;
-	return xcache_lookup(tux_inode(inode)->xcache, atom, &err); // and what about the err???
+		return ERR_PTR(-ENOATTR);
+	struct xattr *got = xcache_lookup(tux_inode(inode)->xcache, atom);
+	mutex_unlock(&atable->i_mutex);
+	return got;
 }
 
 int set_xattr(struct inode *inode, char *name, unsigned len, void *data, unsigned size, unsigned flags)
 {
-	atom_t atom = make_atom(tux_sb(inode->i_sb)->atable, name, len);
+	struct inode *atable = tux_sb(inode->i_sb)->atable;
+	mutex_lock(&atable->i_mutex);
+	atom_t atom = make_atom(atable, name, len);
 	if (atom == -1)
 		return -EINVAL;
-	return xcache_update(inode, atom, data, size, flags);
+	int err = xcache_update(inode, atom, data, size, flags);
+	mutex_unlock(&atable->i_mutex);
+	return err;
 }
 
-/* unused */
 int del_xattr(struct inode *inode, char *name, unsigned len)
 {
 	int err = 0;
-	atom_t atom = find_atom(tux_sb(inode->i_sb)->atable, name, len);
+	struct inode *atable = tux_sb(inode->i_sb)->atable;
+	mutex_lock(&atable->i_mutex);
+	atom_t atom = find_atom(atable, name, len);
 	if (atom == -1)
 		return -ENOATTR;
 	struct xcache *xcache = tux_inode(inode)->xcache;
-	struct xattr *xattr = xcache_lookup(xcache, atom, &err);
-	if (err)
-		return err;
-	if (!xattr)
-		return -ENOATTR;
+	struct xattr *xattr = xcache_lookup(xcache, atom);
+	if (IS_ERR(xattr))
+		return PTR_ERR(xattr);
 	int used = remove_old(xcache, xattr);
 	if (used)
-		use_atom(tux_sb(inode->i_sb)->atable, atom, -used);
+		use_atom(atable, atom, -used);
+	mutex_unlock(&atable->i_mutex);
 	return err;
 }
 
-/* userland only */
 int xattr_list(struct inode *inode, char *text, size_t size)
 {
 	if (!tux_inode(inode)->xcache)
 		return 0;
 	struct inode *atable = tux_sb(inode->i_sb)->atable;
+	mutex_lock(&atable->i_mutex);
 	struct xcache *xcache = tux_inode(inode)->xcache;
 	struct xattr *xattr = xcache->xattrs, *limit = xcache_limit(xcache);
 	char *base = text, *top = text + size;
@@ -415,8 +419,10 @@ int xattr_list(struct inode *inode, char
 	}
 	assert(xattr == limit);
 full:
+	mutex_unlock(&atable->i_mutex);
 	return text - base;
 fail:
+	mutex_unlock(&atable->i_mutex);
 	return -EINVAL;
 }
 
diff -r f534c917e9d2 user/tux3.h
--- a/user/tux3.h	Fri Dec 26 19:28:19 2008 -0800
+++ b/user/tux3.h	Fri Dec 26 22:52:13 2008 -0800
@@ -60,6 +60,11 @@ static inline void up_read(struct rw_sem
 static inline void up_read(struct rw_semaphore *sem) { };
 static inline void up_write(struct rw_semaphore *sem) { };
 static inline void init_rwsem(struct rw_semaphore *sem) { };
+
+struct mutex { };
+
+static inline void mutex_lock(struct mutex *mutex) { };
+static inline void mutex_unlock(struct mutex *mutex) { };
 
 /* Bitmaps */
 
diff -r f534c917e9d2 user/xattr.c
--- a/user/xattr.c	Fri Dec 26 19:28:19 2008 -0800
+++ b/user/xattr.c	Fri Dec 26 22:52:13 2008 -0800
@@ -86,8 +86,8 @@ int main(int argc, char *argv[])
 	err = xcache_update(inode, 0x666, "hello", 5, 0);
 	err = xcache_update(inode, 0x777, "world!", 6, 0);
 	xcache_dump(inode);
-	struct xattr *xattr = xcache_lookup(tux_inode(inode)->xcache, 0x777, &err);
-	if (xattr)
+	struct xattr *xattr = xcache_lookup(tux_inode(inode)->xcache, 0x777);
+	if (!IS_ERR(xattr))
 		printf("atom %x => %.*s\n", xattr->atom, xattr->size, xattr->body);
 	err = xcache_update(inode, 0x111, "class", 5, 0);
 	err = xcache_update(inode, 0x666, NULL, 0, 0);
@@ -117,7 +117,7 @@ int main(int argc, char *argv[])
 	warn("---- xattr lookup ----");
 	for (int i = 0, len; i < 3; i++) {
 		char *namelist[] = { "hello", "foo", "world" }, *name = namelist[i];
-		if ((xattr = get_xattr(inode, name, len = strlen(name))))
+		if (!IS_ERR(xattr = get_xattr(inode, name, len = strlen(name))))
 			printf("found xattr %.*s => %.*s\n", len, name, xattr->size, xattr->body);
 		else
 			printf("xattr %.*s not found\n", len, name);

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



More information about the Tux3 mailing list