Commit dbf789ce authored by Jinshan Xiong's avatar Jinshan Xiong Committed by Greg Kroah-Hartman
Browse files

staging: lustre: llite: allow setting stripes to specify OSTs



Extend the llite layer to support specifying individual target
OSTs. Support specifying OSTs for regular files only. Directory
support will be implemented later in a separate project. With
this a file could have for example a OST index layout of
2,4,5,9,11. In addition, duplicate indices will be eliminated
automatically. Calculate the max easize by ld_active_tgt_count
instead of ld_tgt_count. However this may introduce problems
when the OSTs are in recovery because non sufficient buffer
may be allocated to store EA.

Signed-off-by: default avatarJian Yu <jian.yu@intel.com>
Signed-off-by: default avatarJinshan Xiong <jinshan.xiong@intel.com>
Signed-off-by: default avatarJames Simmons <uja.ornl@gmail.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4665
Reviewed-on: http://review.whamcloud.com/9383


Reviewed-by: default avatarAndreas Dilger <andreas.dilger@intel.com>
Reviewed-by: default avatarJohn L. Hammond <john.hammond@intel.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a6d879fd
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1483,6 +1483,8 @@ enum obdo_flags {
#define LOV_MAGIC_JOIN_V1	(0x0BD20000 | LOV_MAGIC_MAGIC)
#define LOV_MAGIC_V3		(0x0BD30000 | LOV_MAGIC_MAGIC)
#define LOV_MAGIC_MIGRATE	(0x0BD40000 | LOV_MAGIC_MAGIC)
/* reserved for specifying OSTs */
#define LOV_MAGIC_SPECIFIC	(0x0BD50000 | LOV_MAGIC_MAGIC)
#define LOV_MAGIC		LOV_MAGIC_V1

/*
+9 −8
Original line number Diff line number Diff line
@@ -284,6 +284,8 @@ enum ll_lease_type {
#define LOV_USER_MAGIC		LOV_USER_MAGIC_V1
#define LOV_USER_MAGIC_JOIN_V1	0x0BD20BD0
#define LOV_USER_MAGIC_V3	0x0BD30BD0
/* 0x0BD40BD0 is occupied by LOV_MAGIC_MIGRATE */
#define LOV_USER_MAGIC_SPECIFIC	0x0BD50BD0	/* for specific OSTs */

#define LMV_USER_MAGIC    0x0CD30CD0    /*default lmv magic*/

@@ -361,12 +363,11 @@ struct lov_user_md_v3 { /* LOV EA user data (host-endian) */

static inline __u32 lov_user_md_size(__u16 stripes, __u32 lmm_magic)
{
	if (lmm_magic == LOV_USER_MAGIC_V3)
		return sizeof(struct lov_user_md_v3) +
				stripes * sizeof(struct lov_user_ost_data_v1);
	else
	if (lmm_magic == LOV_USER_MAGIC_V1)
		return sizeof(struct lov_user_md_v1) +
				stripes * sizeof(struct lov_user_ost_data_v1);
	return sizeof(struct lov_user_md_v3) +
	       stripes * sizeof(struct lov_user_ost_data_v1);
}

/* Compile with -D_LARGEFILE64_SOURCE or -D_GNU_SOURCE (or #define) to
+11 −17
Original line number Diff line number Diff line
@@ -1540,39 +1540,33 @@ static int ll_lov_setea(struct inode *inode, struct file *file,
static int ll_lov_setstripe(struct inode *inode, struct file *file,
			    unsigned long arg)
{
	struct lov_user_md_v3 lumv3;
	struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&lumv3;
	struct lov_user_md_v1 __user *lumv1p = (void __user *)arg;
	struct lov_user_md_v3 __user *lumv3p = (void __user *)arg;
	struct lov_user_md __user *lum = (struct lov_user_md __user *)arg;
	struct lov_user_md *klum;
	int lum_size, rc;
	__u64 flags = FMODE_WRITE;

	/* first try with v1 which is smaller than v3 */
	lum_size = sizeof(struct lov_user_md_v1);
	if (copy_from_user(lumv1, lumv1p, lum_size))
		return -EFAULT;

	if (lumv1->lmm_magic == LOV_USER_MAGIC_V3) {
		lum_size = sizeof(struct lov_user_md_v3);
		if (copy_from_user(&lumv3, lumv3p, lum_size))
			return -EFAULT;
	}
	rc = ll_copy_user_md(lum, &klum);
	if (rc < 0)
		return rc;

	rc = ll_lov_setstripe_ea_info(inode, file->f_path.dentry, flags, lumv1,
	lum_size = rc;
	rc = ll_lov_setstripe_ea_info(inode, file->f_path.dentry, flags, klum,
				      lum_size);
	cl_lov_delay_create_clear(&file->f_flags);
	if (rc == 0) {
		struct lov_stripe_md *lsm;
		__u32 gen;

		put_user(0, &lumv1p->lmm_stripe_count);
		put_user(0, &lum->lmm_stripe_count);

		ll_layout_refresh(inode, &gen);
		lsm = ccc_inode_lsm_get(inode);
		rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode),
				   0, lsm, (void __user *)arg);
				   0, lsm, lum);
		ccc_inode_lsm_put(inode, lsm);
	}

	kfree(klum);
	return rc;
}

+20 −0
Original line number Diff line number Diff line
@@ -875,6 +875,26 @@ int ll_get_obd_name(struct inode *inode, unsigned int cmd, unsigned long arg);
char *ll_get_fsname(struct super_block *sb, char *buf, int buflen);
void ll_compute_rootsquash_state(struct ll_sb_info *sbi);
void ll_open_cleanup(struct super_block *sb, struct ptlrpc_request *open_req);
ssize_t ll_copy_user_md(const struct lov_user_md __user *md,
			struct lov_user_md **kbuf);

/* Compute expected user md size when passing in a md from user space */
static inline ssize_t ll_lov_user_md_size(const struct lov_user_md *lum)
{
	switch (lum->lmm_magic) {
	case LOV_USER_MAGIC_V1:
		return sizeof(struct lov_user_md_v1);
	case LOV_USER_MAGIC_V3:
		return sizeof(struct lov_user_md_v3);
	case LOV_USER_MAGIC_SPECIFIC:
		if (lum->lmm_stripe_count > LOV_MAX_STRIPE_COUNT)
			return -EINVAL;

		return lov_user_md_size(lum->lmm_stripe_count,
					LOV_USER_MAGIC_SPECIFIC);
	}
	return -EINVAL;
}

/* llite/llite_nfs.c */
extern const struct export_operations lustre_export_operations;
+30 −0
Original line number Diff line number Diff line
@@ -2507,6 +2507,36 @@ void ll_dirty_page_discard_warn(struct page *page, int ioret)
		free_page((unsigned long)buf);
}

ssize_t ll_copy_user_md(const struct lov_user_md __user *md,
			struct lov_user_md **kbuf)
{
	struct lov_user_md lum;
	ssize_t lum_size;

	if (copy_from_user(&lum, md, sizeof(lum))) {
		lum_size = -EFAULT;
		goto no_kbuf;
	}

	lum_size = ll_lov_user_md_size(&lum);
	if (lum_size < 0)
		goto no_kbuf;

	*kbuf = kzalloc(lum_size, GFP_NOFS);
	if (!*kbuf) {
		lum_size = -ENOMEM;
		goto no_kbuf;
	}

	if (copy_from_user(*kbuf, md, lum_size) != 0) {
		kfree(*kbuf);
		*kbuf = NULL;
		lum_size = -EFAULT;
	}
no_kbuf:
	return lum_size;
}

/*
 * Compute llite root squash state after a change of root squash
 * configuration setting or add/remove of a lnet nid
Loading