int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) { struct inode *inode = &ip->i_inode; struct posix_acl *acl; char *data; unsigned int len; int error; acl = gfs2_get_acl(&ip->i_inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); if (!acl) return gfs2_setattr_simple(inode, 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; }
static int gfs2_setattr(struct dentry *dentry, struct iattr *attr) { struct inode *inode = dentry->d_inode; struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_holder i_gh; int error; error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); if (error) return error; error = -EPERM; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) goto out; error = inode_change_ok(inode, attr); if (error) goto out; if (attr->ia_valid & ATTR_SIZE) error = setattr_size(inode, attr); else if (attr->ia_valid & (ATTR_UID | ATTR_GID)) error = setattr_chown(inode, attr); else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode)) error = gfs2_acl_chmod(ip, attr); else error = gfs2_setattr_simple(ip, attr); out: gfs2_glock_dq_uninit(&i_gh); if (!error) mark_inode_dirty(inode); return error; }
static int gfs2_set_mode(struct inode *inode, umode_t mode) { int error = 0; if (mode != inode->i_mode) { struct iattr iattr; iattr.ia_valid = ATTR_MODE; iattr.ia_mode = mode; error = gfs2_setattr_simple(inode, &iattr); } return error; }