Ejemplo n.º 1
0
static int
zpl_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
{
    cred_t *cr = CRED();
    struct inode *ip;
    vattr_t *vap;
    int error;

    crhold(cr);
    vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
    vap->va_mode = mode;
    vap->va_mask = ATTR_MODE;
    vap->va_rdev = rdev;
    vap->va_uid = crgetfsuid(cr);
    vap->va_gid = crgetfsgid(cr);
    vap->va_dentry = dentry;

    error = -zfs_create(dir, (char *)dentry->d_name.name,
                        vap, 0, mode, &ip, cr, 0, NULL);
    kmem_free(vap, sizeof(vattr_t));
    crfree(cr);
    ASSERT3S(error, <=, 0);

    return (-error);
}
Ejemplo n.º 2
0
void
zpl_vap_init(vattr_t *vap, struct inode *dir, zpl_umode_t mode, cred_t *cr)
{
	vap->va_mask = ATTR_MODE;
	vap->va_mode = mode;
	vap->va_uid = crgetfsuid(cr);

	if (dir && dir->i_mode & S_ISGID) {
		vap->va_gid = KGID_TO_SGID(dir->i_gid);
		if (S_ISDIR(mode))
			vap->va_mode |= S_ISGID;
	} else {
		vap->va_gid = crgetfsgid(cr);
	}
}
Ejemplo n.º 3
0
static void
zpl_vap_init(vattr_t *vap, struct inode *dir, struct dentry *dentry,
             mode_t mode, cred_t *cr)
{
    vap->va_mask = ATTR_MODE;
    vap->va_mode = mode;
    vap->va_dentry = dentry;
    vap->va_uid = crgetfsuid(cr);

    if (dir && dir->i_mode & S_ISGID) {
        vap->va_gid = dir->i_gid;
        if (S_ISDIR(mode))
            vap->va_mode |= S_ISGID;
    } else {
        vap->va_gid = crgetfsgid(cr);
    }
}
Ejemplo n.º 4
0
static int
zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
{
    cred_t *cr = CRED();
    vattr_t *vap;
    struct inode *ip;
    int error;

    crhold(cr);
    vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
    vap->va_mode = S_IFLNK | S_IRWXUGO;
    vap->va_mask = ATTR_MODE;
    vap->va_uid = crgetfsuid(cr);
    vap->va_gid = crgetfsgid(cr);
    vap->va_dentry = dentry;

    error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
    kmem_free(vap, sizeof(vattr_t));
    crfree(cr);
    ASSERT3S(error, <=, 0);

    return (error);
}
Ejemplo n.º 5
0
static int
zpl_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
    cred_t *cr = CRED();
    vattr_t *vap;
    struct inode *ip;
    int error;

    crhold(cr);
    vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
    vap->va_mode = S_IFDIR | mode;
    vap->va_mask = ATTR_MODE;
    vap->va_uid = crgetfsuid(cr);
    vap->va_gid = crgetfsgid(cr);
    vap->va_dentry = dentry;

    error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL);
    kmem_free(vap, sizeof(vattr_t));
    crfree(cr);
    ASSERT3S(error, <=, 0);

    return (error);
}
Ejemplo n.º 6
0
static int
zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
    size_t size, int flags, cred_t *cr)
{
	struct inode *dxip = NULL;
	struct inode *xip = NULL;
	vattr_t *vap = NULL;
	ssize_t wrote;
	int lookup_flags, error;
	const int xattr_mode = S_IFREG | 0644;

	/*
	 * Lookup the xattr directory.  When we're adding an entry pass
	 * CREATE_XATTR_DIR to ensure the xattr directory is created.
	 * When removing an entry this flag is not passed to avoid
	 * unnecessarily creating a new xattr directory.
	 */
	lookup_flags = LOOKUP_XATTR;
	if (value != NULL)
		lookup_flags |= CREATE_XATTR_DIR;

	error = -zfs_lookup(ip, NULL, &dxip, lookup_flags, cr, NULL, NULL);
	if (error)
		goto out;

	/* Lookup a specific xattr name in the directory */
	error = -zfs_lookup(dxip, (char *)name, &xip, 0, cr, NULL, NULL);
	if (error && (error != -ENOENT))
		goto out;

	error = 0;

	/* Remove a specific name xattr when value is set to NULL. */
	if (value == NULL) {
		if (xip)
			error = -zfs_remove(dxip, (char *)name, cr);

		goto out;
	}

	/* Lookup failed create a new xattr. */
	if (xip == NULL) {
		vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
		vap->va_mode = xattr_mode;
		vap->va_mask = ATTR_MODE;
		vap->va_uid = crgetfsuid(cr);
		vap->va_gid = crgetfsgid(cr);

		error = -zfs_create(dxip, (char *)name, vap, 0, 0644, &xip,
		    cr, 0, NULL);
		if (error)
			goto out;
	}

	ASSERT(xip != NULL);

	error = -zfs_freesp(ITOZ(xip), 0, 0, xattr_mode, TRUE);
	if (error)
		goto out;

	wrote = zpl_write_common(xip, value, size, 0, UIO_SYSSPACE, 0, cr);
	if (wrote < 0)
		error = wrote;

out:
	if (vap)
		kmem_free(vap, sizeof(vattr_t));

	if (xip)
		iput(xip);

	if (dxip)
		iput(dxip);

	if (error == -ENOENT)
		error = -ENODATA;

	ASSERT3S(error, <=, 0);

	return (error);
}
Ejemplo n.º 7
0
static int
zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
    size_t size, int flags, cred_t *cr)
{
	struct inode *dxip = NULL;
	struct inode *xip = NULL;
	vattr_t *vap = NULL;
	ssize_t wrote;
	int error;
	const int xattr_mode = S_IFREG | 0644;

	/* Lookup the xattr directory and create it if required. */
	error = -zfs_lookup(ip, NULL, &dxip, LOOKUP_XATTR | CREATE_XATTR_DIR,
	    cr, NULL, NULL);
	if (error)
		goto out;

	/* Lookup a specific xattr name in the directory */
	error = -zfs_lookup(dxip, (char *)name, &xip, 0, cr, NULL, NULL);
	if (error && (error != -ENOENT))
		goto out;

	error = 0;

	/* Remove a specific name xattr when value is set to NULL. */
	if (value == NULL) {
		if (xip)
			error = -zfs_remove(dxip, (char *)name, cr);

		goto out;
	}

	/* Lookup failed create a new xattr. */
	if (xip == NULL) {
		vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
		vap->va_mode = xattr_mode;
		vap->va_mask = ATTR_MODE;
		vap->va_uid = crgetfsuid(cr);
		vap->va_gid = crgetfsgid(cr);

		error = -zfs_create(dxip, (char *)name, vap, 0, 0644, &xip,
		    cr, 0, NULL);
		if (error)
			goto out;
	}

	ASSERT(xip != NULL);

	error = -zfs_freesp(ITOZ(xip), 0, 0, xattr_mode, TRUE);
	if (error)
		goto out;

	wrote = zpl_write_common(xip, value, size, 0, UIO_SYSSPACE, 0, cr);
	if (wrote < 0)
		error = wrote;

out:
	if (vap)
		kmem_free(vap, sizeof(vattr_t));

	if (xip)
		VN_RELE(xip);

	if (dxip)
		VN_RELE(dxip);

	if (error == -ENOENT)
		error = -ENODATA;

	ASSERT3S(error, <=, 0);

	return (error);
}