Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[deliverable/linux.git] / fs / gfs2 / acl.c
index 791932617d1a39972aee07a87ed35e8597e6b7bd..363ba9e9d8d0ab4c4bdeb0795d9901c13cf198d4 100644 (file)
@@ -24,6 +24,7 @@
 #include "glock.h"
 #include "inode.h"
 #include "meta_io.h"
+#include "rgrp.h"
 #include "trans.h"
 #include "util.h"
 
@@ -38,7 +39,7 @@ static const char *gfs2_acl_name(int type)
        return NULL;
 }
 
-struct posix_acl *gfs2_get_acl(struct inode *inode, int type)
+static struct posix_acl *__gfs2_get_acl(struct inode *inode, int type)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
        struct posix_acl *acl;
@@ -50,29 +51,41 @@ struct posix_acl *gfs2_get_acl(struct inode *inode, int type)
                return NULL;
 
        name = gfs2_acl_name(type);
-       if (name == NULL)
-               return ERR_PTR(-EINVAL);
-
        len = gfs2_xattr_acl_get(ip, name, &data);
-       if (len < 0)
+       if (len <= 0)
                return ERR_PTR(len);
-       if (len == 0)
-               return NULL;
-
        acl = posix_acl_from_xattr(&init_user_ns, data, len);
        kfree(data);
        return acl;
 }
 
-int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+struct posix_acl *gfs2_get_acl(struct inode *inode, int type)
+{
+       struct gfs2_inode *ip = GFS2_I(inode);
+       struct gfs2_holder gh;
+       bool need_unlock = false;
+       struct posix_acl *acl;
+
+       if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
+               int ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED,
+                                            LM_FLAG_ANY, &gh);
+               if (ret)
+                       return ERR_PTR(ret);
+               need_unlock = true;
+       }
+       acl = __gfs2_get_acl(inode, type);
+       if (need_unlock)
+               gfs2_glock_dq_uninit(&gh);
+       return acl;
+}
+
+int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 {
        int error;
        int len;
        char *data;
        const char *name = gfs2_acl_name(type);
 
-       BUG_ON(name == NULL);
-
        if (acl && acl->a_count > GFS2_ACL_MAX_ENTRIES(GFS2_SB(inode)))
                return -E2BIG;
 
@@ -115,3 +128,26 @@ out:
        kfree(data);
        return error;
 }
+
+int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+{
+       struct gfs2_inode *ip = GFS2_I(inode);
+       struct gfs2_holder gh;
+       bool need_unlock = false;
+       int ret;
+
+       ret = gfs2_rsqa_alloc(ip);
+       if (ret)
+               return ret;
+
+       if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
+               ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
+               if (ret)
+                       return ret;
+               need_unlock = true;
+       }
+       ret = __gfs2_set_acl(inode, acl, type);
+       if (need_unlock)
+               gfs2_glock_dq_uninit(&gh);
+       return ret;
+}
This page took 0.032656 seconds and 5 git commands to generate.