Beispiel #1
0
int orangefs_init_acl(struct inode *inode, struct inode *dir)
{
	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
	struct posix_acl *default_acl, *acl;
	umode_t mode = inode->i_mode;
	int error = 0;

	ClearModeFlag(orangefs_inode);

	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) {
		SetModeFlag(orangefs_inode);
		inode->i_mode = mode;
		orangefs_flush_inode(inode);
	}

	return error;
}
Beispiel #2
0
Datei: acl.c Projekt: Goon83/SALB
/*
 * initialize the ACLs of a new inode.
 * This needs to be called from pvfs2_get_custom_inode.
 * Note that for the root of the PVFS2 file system,
 * dir will be NULL! For all others dir will be non-NULL
 * However, inode cannot be NULL!
 * Returns 0 on success and -ve number on failure.
 */
int pvfs2_init_acl(struct inode *inode, struct inode *dir)
{
    struct posix_acl *acl = NULL;
    int error = 0;
    pvfs2_inode_t *pvfs2_inode = PVFS2_I(inode);

    if (dir == NULL)
        dir = inode;
    ClearModeFlag(pvfs2_inode);
    if (!S_ISLNK(inode->i_mode))
    {
        if (get_acl_flag(inode) == 1)
        {
            acl = pvfs2_get_acl(dir, ACL_TYPE_DEFAULT);
            if (IS_ERR(acl)) {
                error = PTR_ERR(acl);
                gossip_err("pvfs2_get_acl (default) failed with error %d\n", error);
                return error;
            }
        }
        if (!acl && dir != inode)
        {
            int old_mode = inode->i_mode;
            inode->i_mode &= ~current->fs->umask;
            gossip_debug(GOSSIP_ACL_DEBUG, "inode->i_mode before %o and "
                    "after %o\n", old_mode, inode->i_mode);
            if (old_mode != inode->i_mode)
                SetModeFlag(pvfs2_inode);
        }
    }
    if (get_acl_flag(inode) == 1 && acl)
    {
        struct posix_acl *clone;
        mode_t mode;

        if (S_ISDIR(inode->i_mode)) 
        {
            error = pvfs2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
            if (error) {
                gossip_err("pvfs2_set_acl (default) directory failed with "
                        "error %d\n", error);
                ClearModeFlag(pvfs2_inode);
                goto cleanup;
            }
        }
        clone = posix_acl_clone(acl, GFP_KERNEL);
        error = -ENOMEM;
        if (!clone) {
            gossip_err("posix_acl_clone failed with ENOMEM\n");
            ClearModeFlag(pvfs2_inode);
            goto cleanup;
        }
        mode = inode->i_mode;
        error = posix_acl_create_masq(clone, &mode);
        if (error >= 0)
        {
            gossip_debug(GOSSIP_ACL_DEBUG, "posix_acl_create_masq changed mode "
                    "from %o to %o\n", inode->i_mode, mode);
            /*
             * Dont do a needless ->setattr() if mode has not changed 
             */
            if (inode->i_mode != mode)
                SetModeFlag(pvfs2_inode);
            inode->i_mode = mode;
            /* 
             * if this is an ACL that cannot be captured by
             * the mode bits, go for the server! 
             */
            if (error > 0)
            {
                error = pvfs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
                gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_set_acl (access) returned %d\n", error);
            }
        }
        posix_acl_release(clone);
    }
    /* If mode of the inode was changed, then do a forcible ->setattr */
    if (ModeFlag(pvfs2_inode))
        pvfs2_flush_inode(inode);
cleanup:
    posix_acl_release(acl);
    return error;
}