Ejemplo n.º 1
0
/*
 * Initialize the ACLs of a new inode. If parent directory has default ACL,
 * then clone to new inode. Called from ocfs2_mknod.
 */
int ocfs2_init_acl(handle_t *handle,
		   struct inode *inode,
		   struct inode *dir,
		   struct buffer_head *di_bh,
		   struct buffer_head *dir_bh,
		   struct ocfs2_alloc_context *meta_ac,
		   struct ocfs2_alloc_context *data_ac)
{
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
	struct posix_acl *acl = NULL;
	int ret = 0;
	mode_t mode;

	if (!S_ISLNK(inode->i_mode)) {
		if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
			acl = ocfs2_get_acl_nolock(dir, ACL_TYPE_DEFAULT,
						   dir_bh);
			if (IS_ERR(acl))
				return PTR_ERR(acl);
		}
		if (!acl) {
			mode = inode->i_mode & ~current_umask();
			ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
			if (ret) {
				mlog_errno(ret);
				goto cleanup;
			}
		}
	}
	if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) {
		struct posix_acl *clone;

		if (S_ISDIR(inode->i_mode)) {
			ret = ocfs2_set_acl(handle, inode, di_bh,
					    ACL_TYPE_DEFAULT, acl,
					    meta_ac, data_ac);
			if (ret)
				goto cleanup;
		}
		clone = posix_acl_clone(acl, GFP_NOFS);
		ret = -ENOMEM;
		if (!clone)
			goto cleanup;

		mode = inode->i_mode;
		ret = posix_acl_create_masq(clone, &mode);
		if (ret >= 0) {
			ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
			if (ret > 0) {
				ret = ocfs2_set_acl(handle, inode,
						    di_bh, ACL_TYPE_ACCESS,
						    clone, meta_ac, data_ac);
			}
		}
		posix_acl_release(clone);
	}
cleanup:
	posix_acl_release(acl);
	return ret;
}
Ejemplo n.º 2
0
Archivo: acl.c Proyecto: acton393/linux
/*
 * Set the access or default ACL of an inode.
 */
int ocfs2_set_acl(handle_t *handle,
			 struct inode *inode,
			 struct buffer_head *di_bh,
			 int type,
			 struct posix_acl *acl,
			 struct ocfs2_alloc_context *meta_ac,
			 struct ocfs2_alloc_context *data_ac)
{
	int name_index;
	void *value = NULL;
	size_t size = 0;
	int ret;

	if (S_ISLNK(inode->i_mode))
		return -EOPNOTSUPP;

	switch (type) {
	case ACL_TYPE_ACCESS:
		name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
		if (acl) {
			umode_t mode;

			ret = posix_acl_update_mode(inode, &mode, &acl);
			if (ret)
				return ret;

			ret = ocfs2_acl_set_mode(inode, di_bh,
						 handle, mode);
			if (ret)
				return ret;
		}
		break;
	case ACL_TYPE_DEFAULT:
		name_index = OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT;
		if (!S_ISDIR(inode->i_mode))
			return acl ? -EACCES : 0;
		break;
	default:
		return -EINVAL;
	}

	if (acl) {
		value = ocfs2_acl_to_xattr(acl, &size);
		if (IS_ERR(value))
			return (int)PTR_ERR(value);
	}

	if (handle)
		ret = ocfs2_xattr_set_handle(handle, inode, di_bh, name_index,
					     "", value, size, 0,
					     meta_ac, data_ac);
	else
		ret = ocfs2_xattr_set(inode, name_index, "", value, size, 0);

	kfree(value);

	return ret;
}