[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