int orangefs_init_acl(struct inode *inode, struct inode *dir) { struct posix_acl *default_acl, *acl; umode_t mode = inode->i_mode; struct iattr iattr; int error = 0; error = posix_acl_create(dir, &mode, &default_acl, &acl); if (error) return error; if (default_acl) { error = __orangefs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); posix_acl_release(default_acl); } if (acl) { if (!error) error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS); posix_acl_release(acl); } /* If mode of the inode was changed, then do a forcible ->setattr */ if (mode != inode->i_mode) { memset(&iattr, 0, sizeof iattr); inode->i_mode = mode; iattr.ia_mode = mode; iattr.ia_valid |= ATTR_MODE; orangefs_inode_setattr(inode, &iattr); } return error; }
int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) { int error; struct iattr iattr; int rc; if (type == ACL_TYPE_ACCESS && acl) { /* * posix_acl_update_mode checks to see if the permissions * described by the ACL can be encoded into the * object's mode. If so, it sets "acl" to NULL * and "mode" to the new desired value. It is up to * us to propagate the new mode back to the server... */ error = posix_acl_update_mode(inode, &iattr.ia_mode, &acl); if (error) { gossip_err("%s: posix_acl_update_mode err: %d\n", __func__, error); return error; } if (acl) { rc = __orangefs_set_acl(inode, acl, type); } else { iattr.ia_valid = ATTR_MODE; rc = orangefs_inode_setattr(inode, &iattr); } return rc; } else { return -EINVAL; } }
/* * Change attributes of an object referenced by dentry. */ int orangefs_setattr(struct dentry *dentry, struct iattr *iattr) { int ret = -EINVAL; struct inode *inode = dentry->d_inode; gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_setattr: called on %pd\n", dentry); ret = setattr_prepare(dentry, iattr); if (ret) goto out; if (iattr->ia_valid & ATTR_SIZE) { ret = orangefs_setattr_size(inode, iattr); if (ret) goto out; } setattr_copy(inode, iattr); mark_inode_dirty(inode); ret = orangefs_inode_setattr(inode, iattr); gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_setattr: inode_setattr returned %d\n", ret); if (!ret && (iattr->ia_valid & ATTR_MODE)) /* change mod on a file that has ACLs */ ret = posix_acl_chmod(inode, inode->i_mode); out: gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_setattr: returning %d\n", ret); return ret; }
int orangefs_update_time(struct inode *inode, struct timespec *time, int flags) { struct iattr iattr; gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_update_time: %pU\n", get_khandle_from_ino(inode)); generic_update_time(inode, time, flags); memset(&iattr, 0, sizeof iattr); if (flags & S_ATIME) iattr.ia_valid |= ATTR_ATIME; if (flags & S_CTIME) iattr.ia_valid |= ATTR_CTIME; if (flags & S_MTIME) iattr.ia_valid |= ATTR_MTIME; return orangefs_inode_setattr(inode, &iattr); }