Example #1
0
/*
 * Given an object number, return its parent object number and whether
 * or not the object is an extended attribute directory.
 */
static int
zfs_obj_to_pobj(sa_handle_t *hdl, sa_attr_type_t *sa_table, uint64_t *pobjp,
    int *is_xattrdir)
{
	uint64_t parent;
	uint64_t pflags;
	uint64_t mode;
	sa_bulk_attr_t bulk[3];
	int count = 0;
	int error;

	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_PARENT], NULL,
	    &parent, sizeof (parent));
	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_FLAGS], NULL,
	    &pflags, sizeof (pflags));
	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_MODE], NULL,
	    &mode, sizeof (mode));

	if ((error = sa_bulk_lookup(hdl, bulk, count)) != 0)
		return (error);

	*pobjp = parent;
	*is_xattrdir = ((pflags & ZFS_XATTR) != 0) && S_ISDIR(mode);

	return (0);
}
Example #2
0
/*
 * Given an object number, return some zpl level statistics
 */
static int
zfs_obj_to_stats_impl(sa_handle_t *hdl, sa_attr_type_t *sa_table,
    zfs_stat_t *sb)
{
	sa_bulk_attr_t bulk[4];
	int count = 0;

	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_MODE], NULL,
	    &sb->zs_mode, sizeof (sb->zs_mode));
	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_GEN], NULL,
	    &sb->zs_gen, sizeof (sb->zs_gen));
	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_LINKS], NULL,
	    &sb->zs_links, sizeof (sb->zs_links));
	SA_ADD_BULK_ATTR(bulk, count, sa_table[ZPL_CTIME], NULL,
	    &sb->zs_ctime, sizeof (sb->zs_ctime));

	return (sa_bulk_lookup(hdl, bulk, count));
}
Example #3
0
void
zfs_fuid_map_ids(znode_t *zp, cred_t *cr, uid_t *uidp, uid_t *gidp)
{
	uint64_t fuid, fgid;
	sa_bulk_attr_t bulk[2];
	int count = 0;

	if (IS_EPHEMERAL(zp->z_uid) || IS_EPHEMERAL(zp->z_gid)) {
		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zp->z_zfsvfs),
		    NULL, &fuid, 8);
		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zp->z_zfsvfs),
		    NULL, &fgid, 8);
		VERIFY(0 == sa_bulk_lookup(zp->z_sa_hdl, bulk, count));
	}
	if (IS_EPHEMERAL(zp->z_uid))
		*uidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER);
	else
		*uidp = zp->z_uid;
	if (IS_EPHEMERAL(zp->z_gid))
		*gidp = zfs_fuid_map_id(zp->z_zfsvfs,
		    zp->z_gid, cr, ZFS_GROUP);
	else
		*gidp = zp->z_gid;
}
Example #4
0
/*
 * Retrieve the attributes of a DMU object
 */
int __osd_object_attr_get(const struct lu_env *env, udmu_objset_t *uos,
			  struct osd_object *obj, struct lu_attr *la)
{
	struct osa_attr	*osa = &osd_oti_get(env)->oti_osa;
	sa_handle_t	*sa_hdl;
	sa_bulk_attr_t	*bulk;
	int		 cnt = 0;
	int		 rc;
	ENTRY;

	LASSERT(obj->oo_db != NULL);

	rc = -sa_handle_get(uos->os, obj->oo_db->db_object, NULL,
			    SA_HDL_PRIVATE, &sa_hdl);
	if (rc)
		RETURN(rc);

	OBD_ALLOC(bulk, sizeof(sa_bulk_attr_t) * 9);
	if (bulk == NULL)
		GOTO(out_sa, rc = -ENOMEM);

	la->la_valid |= LA_ATIME | LA_MTIME | LA_CTIME | LA_MODE | LA_TYPE |
			LA_SIZE | LA_UID | LA_GID | LA_FLAGS | LA_NLINK;

	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_ATIME(uos), NULL, osa->atime, 16);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MTIME(uos), NULL, osa->mtime, 16);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CTIME(uos), NULL, osa->ctime, 16);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MODE(uos), NULL, &osa->mode, 8);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_SIZE(uos), NULL, &osa->size, 8);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_LINKS(uos), NULL, &osa->nlink, 8);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_UID(uos), NULL, &osa->uid, 8);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_GID(uos), NULL, &osa->gid, 8);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_FLAGS(uos), NULL, &osa->flags, 8);

	rc = -sa_bulk_lookup(sa_hdl, bulk, cnt);
	if (rc)
		GOTO(out_bulk, rc);

	la->la_atime = osa->atime[0];
	la->la_mtime = osa->mtime[0];
	la->la_ctime = osa->ctime[0];
	la->la_mode = osa->mode;
	la->la_uid = osa->uid;
	la->la_gid = osa->gid;
	la->la_nlink = osa->nlink;
	la->la_flags = osa->flags;
	la->la_size = osa->size;

	if (S_ISCHR(la->la_mode) || S_ISBLK(la->la_mode)) {
		rc = -sa_lookup(sa_hdl, SA_ZPL_RDEV(uos), &osa->rdev, 8);
		if (rc)
			GOTO(out_bulk, rc);
		la->la_rdev = osa->rdev;
		la->la_valid |= LA_RDEV;
	}
out_bulk:
	OBD_FREE(bulk, sizeof(sa_bulk_attr_t) * 9);
out_sa:
	sa_handle_destroy(sa_hdl);

	RETURN(rc);
}
Example #5
0
/*
 * Construct a znode+inode and initialize.
 *
 * This does not do a call to dmu_set_user() that is
 * up to the caller to do, in case you don't want to
 * return the znode
 */
static znode_t *
zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz,
    dmu_object_type_t obj_type, uint64_t obj, sa_handle_t *hdl,
    struct inode *dip)
{
	znode_t	*zp;
	struct inode *ip;
	uint64_t mode;
	uint64_t parent;
	sa_bulk_attr_t bulk[9];
	int count = 0;

	ASSERT(zsb != NULL);

	ip = new_inode(zsb->z_sb);
	if (ip == NULL)
		return (NULL);

	zp = ITOZ(ip);
	ASSERT(zp->z_dirlocks == NULL);
	ASSERT3P(zp->z_acl_cached, ==, NULL);
	ASSERT3P(zp->z_xattr_cached, ==, NULL);
	ASSERT3P(zp->z_xattr_parent, ==, NULL);
	zp->z_moved = 0;
	zp->z_sa_hdl = NULL;
	zp->z_unlinked = 0;
	zp->z_atime_dirty = 0;
	zp->z_mapcnt = 0;
	zp->z_id = db->db_object;
	zp->z_blksz = blksz;
	zp->z_seq = 0x7A4653;
	zp->z_sync_cnt = 0;
	zp->z_is_zvol = B_FALSE;
	zp->z_is_mapped = B_FALSE;
	zp->z_is_ctldir = B_FALSE;
	zp->z_is_stale = B_FALSE;

	zfs_znode_sa_init(zsb, zp, db, obj_type, hdl);

	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &mode, 8);
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zsb), NULL, &zp->z_gen, 8);
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL, &zp->z_size, 8);
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL, &zp->z_links, 8);
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
	    &zp->z_pflags, 8);
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL,
	    &parent, 8);
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zsb), NULL,
	    &zp->z_atime, 16);
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL, &zp->z_uid, 8);
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL, &zp->z_gid, 8);

	if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || zp->z_gen == 0) {
		if (hdl == NULL)
			sa_handle_destroy(zp->z_sa_hdl);

		goto error;
	}

	zp->z_mode = mode;

	/*
	 * xattr znodes hold a reference on their unique parent
	 */
	if (dip && zp->z_pflags & ZFS_XATTR) {
		igrab(dip);
		zp->z_xattr_parent = ITOZ(dip);
	}

	ip->i_ino = obj;
	zfs_inode_update(zp);
	zfs_inode_set_ops(zsb, ip);

	/*
	 * The only way insert_inode_locked() can fail is if the ip->i_ino
	 * number is already hashed for this super block.  This can never
	 * happen because the inode numbers map 1:1 with the object numbers.
	 *
	 * The one exception is rolling back a mounted file system, but in
	 * this case all the active inode are unhashed during the rollback.
	 */
	VERIFY3S(insert_inode_locked(ip), ==, 0);

	mutex_enter(&zsb->z_znodes_lock);
	list_insert_tail(&zsb->z_all_znodes, zp);
	zsb->z_nr_znodes++;
	membar_producer();
	mutex_exit(&zsb->z_znodes_lock);

	unlock_new_inode(ip);
	return (zp);

error:
	unlock_new_inode(ip);
	iput(ip);
	return (NULL);
}
Example #6
0
int
zfs_rezget(znode_t *zp)
{
	zfs_sb_t *zsb = ZTOZSB(zp);
	dmu_object_info_t doi;
	dmu_buf_t *db;
	uint64_t obj_num = zp->z_id;
	uint64_t mode;
	sa_bulk_attr_t bulk[8];
	int err;
	int count = 0;
	uint64_t gen;

	ZFS_OBJ_HOLD_ENTER(zsb, obj_num);

	mutex_enter(&zp->z_acl_lock);
	if (zp->z_acl_cached) {
		zfs_acl_free(zp->z_acl_cached);
		zp->z_acl_cached = NULL;
	}
	mutex_exit(&zp->z_acl_lock);

	rw_enter(&zp->z_xattr_lock, RW_WRITER);
	if (zp->z_xattr_cached) {
		nvlist_free(zp->z_xattr_cached);
		zp->z_xattr_cached = NULL;
	}

	if (zp->z_xattr_parent) {
		iput(ZTOI(zp->z_xattr_parent));
		zp->z_xattr_parent = NULL;
	}
	rw_exit(&zp->z_xattr_lock);

	ASSERT(zp->z_sa_hdl == NULL);
	err = sa_buf_hold(zsb->z_os, obj_num, NULL, &db);
	if (err) {
		ZFS_OBJ_HOLD_EXIT(zsb, obj_num);
		return (err);
	}

	dmu_object_info_from_db(db, &doi);
	if (doi.doi_bonus_type != DMU_OT_SA &&
	    (doi.doi_bonus_type != DMU_OT_ZNODE ||
	    (doi.doi_bonus_type == DMU_OT_ZNODE &&
	    doi.doi_bonus_size < sizeof (znode_phys_t)))) {
		sa_buf_rele(db, NULL);
		ZFS_OBJ_HOLD_EXIT(zsb, obj_num);
		return (SET_ERROR(EINVAL));
	}

	zfs_znode_sa_init(zsb, zp, db, doi.doi_bonus_type, NULL);

	/* reload cached values */
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zsb), NULL,
	    &gen, sizeof (gen));
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL,
	    &zp->z_size, sizeof (zp->z_size));
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL,
	    &zp->z_links, sizeof (zp->z_links));
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
	    &zp->z_pflags, sizeof (zp->z_pflags));
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zsb), NULL,
	    &zp->z_atime, sizeof (zp->z_atime));
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL,
	    &zp->z_uid, sizeof (zp->z_uid));
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL,
	    &zp->z_gid, sizeof (zp->z_gid));
	SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL,
	    &mode, sizeof (mode));

	if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count)) {
		zfs_znode_dmu_fini(zp);
		ZFS_OBJ_HOLD_EXIT(zsb, obj_num);
		return (SET_ERROR(EIO));
	}

	zp->z_mode = mode;

	if (gen != zp->z_gen) {
		zfs_znode_dmu_fini(zp);
		ZFS_OBJ_HOLD_EXIT(zsb, obj_num);
		return (SET_ERROR(EIO));
	}

	zp->z_unlinked = (zp->z_links == 0);
	zp->z_blksz = doi.doi_data_block_size;
	zfs_inode_update(zp);

	ZFS_OBJ_HOLD_EXIT(zsb, obj_num);

	return (0);
}
Example #7
0
/*
 * Retrieve the attributes of a DMU object
 */
int __osd_object_attr_get(const struct lu_env *env, struct osd_device *o,
			  struct osd_object *obj, struct lu_attr *la)
{
	struct osa_attr	*osa = &osd_oti_get(env)->oti_osa;
	sa_bulk_attr_t	*bulk = osd_oti_get(env)->oti_attr_bulk;
	sa_handle_t	*sa_hdl;
	int		 cnt = 0;
	int		 rc;
	ENTRY;

	LASSERT(obj->oo_db != NULL);

	rc = -sa_handle_get(o->od_os, obj->oo_db->db_object, NULL,
			    SA_HDL_PRIVATE, &sa_hdl);
	if (rc)
		RETURN(rc);

	la->la_valid |= LA_ATIME | LA_MTIME | LA_CTIME | LA_MODE | LA_TYPE |
			LA_SIZE | LA_UID | LA_GID | LA_FLAGS | LA_NLINK;

	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_ATIME(o), NULL, osa->atime, 16);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MTIME(o), NULL, osa->mtime, 16);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CTIME(o), NULL, osa->ctime, 16);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MODE(o), NULL, &osa->mode, 8);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_SIZE(o), NULL, &osa->size, 8);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_LINKS(o), NULL, &osa->nlink, 8);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_UID(o), NULL, &osa->uid, 8);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_GID(o), NULL, &osa->gid, 8);
	SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_FLAGS(o), NULL, &osa->flags, 8);
	LASSERT(cnt <= ARRAY_SIZE(osd_oti_get(env)->oti_attr_bulk));

	rc = -sa_bulk_lookup(sa_hdl, bulk, cnt);
	if (rc)
		GOTO(out_sa, rc);

	la->la_atime = osa->atime[0];
	la->la_mtime = osa->mtime[0];
	la->la_ctime = osa->ctime[0];
	la->la_mode = osa->mode;
	la->la_uid = osa->uid;
	la->la_gid = osa->gid;
	la->la_nlink = osa->nlink;
	la->la_flags = attrs_zfs2fs(osa->flags);
	la->la_size = osa->size;

	/* Try to get extra flag from LMA. Right now, only LMAI_ORPHAN
	 * flags is stored in LMA, and it is only for orphan directory */
	if (S_ISDIR(la->la_mode) && dt_object_exists(&obj->oo_dt)) {
		struct osd_thread_info *info = osd_oti_get(env);
		struct lustre_mdt_attrs *lma;
		struct lu_buf buf;

		lma = (struct lustre_mdt_attrs *)info->oti_buf;
		buf.lb_buf = lma;
		buf.lb_len = sizeof(info->oti_buf);
		rc = osd_xattr_get(env, &obj->oo_dt, &buf, XATTR_NAME_LMA);
		if (rc > 0) {
			rc = 0;
			lma->lma_incompat = le32_to_cpu(lma->lma_incompat);
			obj->oo_lma_flags =
				lma_to_lustre_flags(lma->lma_incompat);

		} else if (rc == -ENODATA) {
			rc = 0;
		}
	}

	if (S_ISCHR(la->la_mode) || S_ISBLK(la->la_mode)) {
		rc = -sa_lookup(sa_hdl, SA_ZPL_RDEV(o), &osa->rdev, 8);
		if (rc)
			GOTO(out_sa, rc);
		la->la_rdev = osa->rdev;
		la->la_valid |= LA_RDEV;
	}
out_sa:
	sa_handle_destroy(sa_hdl);

	RETURN(rc);
}
Example #8
0
/*
 * Construct a znode+inode and initialize.
 *
 * This does not do a call to dmu_set_user() that is
 * up to the caller to do, in case you don't want to
 * return the znode
 */
static znode_t *
zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz,
                dmu_object_type_t obj_type, uint64_t obj, sa_handle_t *hdl,
                struct dentry *dentry, struct inode *dip)
{
    znode_t	*zp;
    struct inode *ip;
    uint64_t parent;
    sa_bulk_attr_t bulk[9];
    int count = 0;

    ASSERT(zsb != NULL);

    ip = new_inode(zsb->z_sb);
    if (ip == NULL)
        return (NULL);

    zp = ITOZ(ip);
    ASSERT(zp->z_dirlocks == NULL);
    ASSERT3P(zp->z_acl_cached, ==, NULL);
    ASSERT3P(zp->z_xattr_cached, ==, NULL);
    zp->z_moved = 0;
    zp->z_sa_hdl = NULL;
    zp->z_unlinked = 0;
    zp->z_atime_dirty = 0;
    zp->z_mapcnt = 0;
    zp->z_id = db->db_object;
    zp->z_blksz = blksz;
    zp->z_seq = 0x7A4653;
    zp->z_sync_cnt = 0;
    zp->z_is_zvol = B_FALSE;
    zp->z_is_mapped = B_FALSE;
    zp->z_is_ctldir = B_FALSE;

    zfs_znode_sa_init(zsb, zp, db, obj_type, hdl);

    SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &zp->z_mode, 8);
    SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zsb), NULL, &zp->z_gen, 8);
    SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL, &zp->z_size, 8);
    SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL, &zp->z_links, 8);
    SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
                     &zp->z_pflags, 8);
    SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL,
                     &parent, 8);
    SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zsb), NULL,
                     &zp->z_atime, 16);
    SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL, &zp->z_uid, 8);
    SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL, &zp->z_gid, 8);

    if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || zp->z_gen == 0) {
        if (hdl == NULL)
            sa_handle_destroy(zp->z_sa_hdl);

        goto error;
    }

    ip->i_ino = obj;
    zfs_inode_update(zp);
    zfs_inode_set_ops(zsb, ip);

    if (insert_inode_locked(ip))
        goto error;

    if (dentry) {
        if (zpl_xattr_security_init(ip, dip, &dentry->d_name))
            goto error;

        d_instantiate(dentry, ip);
    }

    mutex_enter(&zsb->z_znodes_lock);
    list_insert_tail(&zsb->z_all_znodes, zp);
    zsb->z_nr_znodes++;
    membar_producer();
    mutex_exit(&zsb->z_znodes_lock);

    unlock_new_inode(ip);
    return (zp);

error:
    unlock_new_inode(ip);
    iput(ip);
    return NULL;
}