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
[email protected]
http://mailman.tux3.org/cgi-bin/mailman/listinfo/tux3

Reply via email to