static int gfs2_xattr_system_get(struct dentry *dentry, const char *name, void *buffer, size_t size, int xtype) { struct inode *inode = dentry->d_inode; struct gfs2_sbd *sdp = GFS2_SB(inode); struct posix_acl *acl; int type; int error; if (!sdp->sd_args.ar_posix_acl) return -EOPNOTSUPP; type = gfs2_acl_type(name); if (type < 0) return type; acl = gfs2_acl_get(GFS2_I(inode), type); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl == NULL) return -ENODATA; error = posix_acl_to_xattr(acl, buffer, size); posix_acl_release(acl); return error; }
int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) { struct posix_acl *acl; char *data; unsigned int len; int error; acl = gfs2_acl_get(ip, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); if (!acl) return gfs2_setattr_simple(ip, attr); error = posix_acl_chmod(&acl, GFP_NOFS, attr->ia_mode); if (error) return error; len = posix_acl_to_xattr(acl, NULL, 0); data = kmalloc(len, GFP_NOFS); error = -ENOMEM; if (data == NULL) goto out; posix_acl_to_xattr(acl, data, len); error = gfs2_xattr_acl_chmod(ip, attr, data); kfree(data); set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl); out: posix_acl_release(acl); return error; }
int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode) { struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); struct posix_acl *acl, *clone; mode_t mode = inode->i_mode; int error = 0; if (!sdp->sd_args.ar_posix_acl) return 0; if (S_ISLNK(inode->i_mode)) return 0; acl = gfs2_acl_get(dip, ACL_TYPE_DEFAULT); if (IS_ERR(acl)) return PTR_ERR(acl); if (!acl) { mode &= ~current_umask(); if (mode != inode->i_mode) error = gfs2_set_mode(inode, mode); return error; } if (S_ISDIR(inode->i_mode)) { error = gfs2_acl_set(inode, ACL_TYPE_DEFAULT, acl); if (error) goto out; } clone = posix_acl_clone(acl, GFP_NOFS); error = -ENOMEM; if (!clone) goto out; posix_acl_release(acl); acl = clone; error = posix_acl_create_masq(acl, &mode); if (error < 0) goto out; if (error == 0) goto munge; error = gfs2_acl_set(inode, ACL_TYPE_ACCESS, acl); if (error) goto out; munge: error = gfs2_set_mode(inode, mode); out: posix_acl_release(acl); return error; }
int gfs2_check_acl(struct inode *inode, int mask) { struct posix_acl *acl; int error; acl = gfs2_acl_get(GFS2_I(inode), ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl) { error = posix_acl_permission(inode, acl, mask); posix_acl_release(acl); return error; } return -EAGAIN; }
int gfs2_check_acl(struct inode *inode, int mask, unsigned int flags) { struct posix_acl *acl; int error; if (flags & IPERM_FLAG_RCU) { if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) return -ECHILD; return -EAGAIN; } acl = gfs2_acl_get(GFS2_I(inode), ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); if (acl) { error = posix_acl_permission(inode, acl, mask); posix_acl_release(acl); return error; } return -EAGAIN; }