1b3b94faaSDavid Teigland /* 2b3b94faaSDavid Teigland * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 33a8a9a10SSteven Whitehouse * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 4b3b94faaSDavid Teigland * 5b3b94faaSDavid Teigland * This copyrighted material is made available to anyone wishing to use, 6b3b94faaSDavid Teigland * modify, copy, or redistribute it subject to the terms and conditions 7e9fc2aa0SSteven Whitehouse * of the GNU General Public License version 2. 8b3b94faaSDavid Teigland */ 9b3b94faaSDavid Teigland 10b3b94faaSDavid Teigland #include <linux/sched.h> 11b3b94faaSDavid Teigland #include <linux/slab.h> 12b3b94faaSDavid Teigland #include <linux/spinlock.h> 13b3b94faaSDavid Teigland #include <linux/completion.h> 14b3b94faaSDavid Teigland #include <linux/buffer_head.h> 152646a1f6SSteven Whitehouse #include <linux/xattr.h> 16b3b94faaSDavid Teigland #include <linux/posix_acl.h> 17b3b94faaSDavid Teigland #include <linux/posix_acl_xattr.h> 185c676f6dSSteven Whitehouse #include <linux/gfs2_ondisk.h> 19b3b94faaSDavid Teigland 20b3b94faaSDavid Teigland #include "gfs2.h" 215c676f6dSSteven Whitehouse #include "incore.h" 22b3b94faaSDavid Teigland #include "acl.h" 23307cf6e6SSteven Whitehouse #include "xattr.h" 24b3b94faaSDavid Teigland #include "glock.h" 25b3b94faaSDavid Teigland #include "inode.h" 26b3b94faaSDavid Teigland #include "meta_io.h" 27b3b94faaSDavid Teigland #include "trans.h" 285c676f6dSSteven Whitehouse #include "util.h" 29b3b94faaSDavid Teigland 30479c427dSSteven Whitehouse static const char *gfs2_acl_name(int type) 31b3b94faaSDavid Teigland { 32479c427dSSteven Whitehouse switch (type) { 33479c427dSSteven Whitehouse case ACL_TYPE_ACCESS: 34479c427dSSteven Whitehouse return GFS2_POSIX_ACL_ACCESS; 35479c427dSSteven Whitehouse case ACL_TYPE_DEFAULT: 36479c427dSSteven Whitehouse return GFS2_POSIX_ACL_DEFAULT; 37479c427dSSteven Whitehouse } 38479c427dSSteven Whitehouse return NULL; 39479c427dSSteven Whitehouse } 40b3b94faaSDavid Teigland 41018a01cdSSteven Whitehouse struct posix_acl *gfs2_get_acl(struct inode *inode, int type) 42479c427dSSteven Whitehouse { 43018a01cdSSteven Whitehouse struct gfs2_inode *ip = GFS2_I(inode); 44479c427dSSteven Whitehouse struct posix_acl *acl; 45479c427dSSteven Whitehouse const char *name; 46479c427dSSteven Whitehouse char *data; 47479c427dSSteven Whitehouse int len; 4840b78a32SSteven Whitehouse 493767ac21SSteven Whitehouse if (!ip->i_eattr) 50479c427dSSteven Whitehouse return NULL; 51b3b94faaSDavid Teigland 52479c427dSSteven Whitehouse name = gfs2_acl_name(type); 53479c427dSSteven Whitehouse if (name == NULL) 54479c427dSSteven Whitehouse return ERR_PTR(-EINVAL); 55b3b94faaSDavid Teigland 56479c427dSSteven Whitehouse len = gfs2_xattr_acl_get(ip, name, &data); 57479c427dSSteven Whitehouse if (len < 0) 58479c427dSSteven Whitehouse return ERR_PTR(len); 59479c427dSSteven Whitehouse if (len == 0) 60479c427dSSteven Whitehouse return NULL; 61b3b94faaSDavid Teigland 625f3a4a28SEric W. Biederman acl = posix_acl_from_xattr(&init_user_ns, data, len); 6340b78a32SSteven Whitehouse kfree(data); 64479c427dSSteven Whitehouse return acl; 65b3b94faaSDavid Teigland } 66b3b94faaSDavid Teigland 67d3fb6120SAl Viro static int gfs2_set_mode(struct inode *inode, umode_t mode) 68b3b94faaSDavid Teigland { 6969dca424SSteven Whitehouse int error = 0; 70b3b94faaSDavid Teigland 7169dca424SSteven Whitehouse if (mode != inode->i_mode) { 72f9425ad4SSteven Whitehouse inode->i_mode = mode; 73f9425ad4SSteven Whitehouse mark_inode_dirty(inode); 74b3b94faaSDavid Teigland } 75b3b94faaSDavid Teigland 7669dca424SSteven Whitehouse return error; 77b3b94faaSDavid Teigland } 78b3b94faaSDavid Teigland 79e01580bfSChristoph Hellwig int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) 80b3b94faaSDavid Teigland { 81b3b94faaSDavid Teigland int error; 82479c427dSSteven Whitehouse int len; 83479c427dSSteven Whitehouse char *data; 84479c427dSSteven Whitehouse const char *name = gfs2_acl_name(type); 85479c427dSSteven Whitehouse 86479c427dSSteven Whitehouse BUG_ON(name == NULL); 87e01580bfSChristoph Hellwig 88e01580bfSChristoph Hellwig if (acl->a_count > GFS2_ACL_MAX_ENTRIES) 89e01580bfSChristoph Hellwig return -EINVAL; 90e01580bfSChristoph Hellwig 91e01580bfSChristoph Hellwig if (type == ACL_TYPE_ACCESS) { 92e01580bfSChristoph Hellwig umode_t mode = inode->i_mode; 93e01580bfSChristoph Hellwig 94e01580bfSChristoph Hellwig error = posix_acl_equiv_mode(acl, &mode); 95e01580bfSChristoph Hellwig if (error < 0) 96e01580bfSChristoph Hellwig return error; 97e01580bfSChristoph Hellwig 98e01580bfSChristoph Hellwig if (error == 0) 99e01580bfSChristoph Hellwig acl = NULL; 100e01580bfSChristoph Hellwig 101e01580bfSChristoph Hellwig error = gfs2_set_mode(inode, mode); 102e01580bfSChristoph Hellwig if (error) 103e01580bfSChristoph Hellwig return error; 104e01580bfSChristoph Hellwig } 105e01580bfSChristoph Hellwig 106e01580bfSChristoph Hellwig if (acl) { 1075f3a4a28SEric W. Biederman len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0); 108479c427dSSteven Whitehouse if (len == 0) 109479c427dSSteven Whitehouse return 0; 110479c427dSSteven Whitehouse data = kmalloc(len, GFP_NOFS); 111479c427dSSteven Whitehouse if (data == NULL) 112479c427dSSteven Whitehouse return -ENOMEM; 1135f3a4a28SEric W. Biederman error = posix_acl_to_xattr(&init_user_ns, acl, data, len); 114479c427dSSteven Whitehouse if (error < 0) 115479c427dSSteven Whitehouse goto out; 116e01580bfSChristoph Hellwig } else { 117e01580bfSChristoph Hellwig data = NULL; 118e01580bfSChristoph Hellwig len = 0; 119e01580bfSChristoph Hellwig } 120e01580bfSChristoph Hellwig 121431547b3SChristoph Hellwig error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS); 122479c427dSSteven Whitehouse if (error) 123479c427dSSteven Whitehouse goto out; 124479c427dSSteven Whitehouse 125106381bfSSteven Whitehouse if (acl) 126106381bfSSteven Whitehouse set_cached_acl(inode, type, acl); 127106381bfSSteven Whitehouse else 128106381bfSSteven Whitehouse forget_cached_acl(inode, type); 1292646a1f6SSteven Whitehouse out: 130e01580bfSChristoph Hellwig kfree(data); 1312646a1f6SSteven Whitehouse return error; 1322646a1f6SSteven Whitehouse } 133