diff options
Diffstat (limited to 'fs/ceph/ioctl.c')
| -rw-r--r-- | fs/ceph/ioctl.c | 102 | 
1 files changed, 47 insertions, 55 deletions
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index 790914a598d..8e3fb69fbe6 100644 --- a/fs/ceph/ioctl.c +++ b/fs/ceph/ioctl.c @@ -26,8 +26,7 @@ static long ceph_ioctl_get_layout(struct file *file, void __user *arg)  		l.stripe_count = ceph_file_layout_stripe_count(ci->i_layout);  		l.object_size = ceph_file_layout_object_size(ci->i_layout);  		l.data_pool = le32_to_cpu(ci->i_layout.fl_pg_pool); -		l.preferred_osd = -			(s32)le32_to_cpu(ci->i_layout.fl_pg_preferred); +		l.preferred_osd = (s32)-1;  		if (copy_to_user(arg, &l, sizeof(l)))  			return -EFAULT;  	} @@ -35,6 +34,32 @@ static long ceph_ioctl_get_layout(struct file *file, void __user *arg)  	return err;  } +static long __validate_layout(struct ceph_mds_client *mdsc, +			      struct ceph_ioctl_layout *l) +{ +	int i, err; + +	/* validate striping parameters */ +	if ((l->object_size & ~PAGE_MASK) || +	    (l->stripe_unit & ~PAGE_MASK) || +	    ((unsigned)l->object_size % (unsigned)l->stripe_unit)) +		return -EINVAL; + +	/* make sure it's a valid data pool */ +	mutex_lock(&mdsc->mutex); +	err = -EINVAL; +	for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++) +		if (mdsc->mdsmap->m_data_pg_pools[i] == l->data_pool) { +			err = 0; +			break; +		} +	mutex_unlock(&mdsc->mutex); +	if (err) +		return err; + +	return 0; +} +  static long ceph_ioctl_set_layout(struct file *file, void __user *arg)  {  	struct inode *inode = file->f_dentry->d_inode; @@ -44,52 +69,40 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg)  	struct ceph_ioctl_layout l;  	struct ceph_inode_info *ci = ceph_inode(file->f_dentry->d_inode);  	struct ceph_ioctl_layout nl; -	int err, i; +	int err;  	if (copy_from_user(&l, arg, sizeof(l)))  		return -EFAULT;  	/* validate changed params against current layout */  	err = ceph_do_getattr(file->f_dentry->d_inode, CEPH_STAT_CAP_LAYOUT); -	if (!err) { -		nl.stripe_unit = ceph_file_layout_su(ci->i_layout); -		nl.stripe_count = ceph_file_layout_stripe_count(ci->i_layout); -		nl.object_size = ceph_file_layout_object_size(ci->i_layout); -		nl.data_pool = le32_to_cpu(ci->i_layout.fl_pg_pool); -		nl.preferred_osd = -				(s32)le32_to_cpu(ci->i_layout.fl_pg_preferred); -	} else +	if (err)  		return err; +	memset(&nl, 0, sizeof(nl));  	if (l.stripe_count)  		nl.stripe_count = l.stripe_count; +	else +		nl.stripe_count = ceph_file_layout_stripe_count(ci->i_layout);  	if (l.stripe_unit)  		nl.stripe_unit = l.stripe_unit; +	else +		nl.stripe_unit = ceph_file_layout_su(ci->i_layout);  	if (l.object_size)  		nl.object_size = l.object_size; +	else +		nl.object_size = ceph_file_layout_object_size(ci->i_layout);  	if (l.data_pool)  		nl.data_pool = l.data_pool; -	if (l.preferred_osd) -		nl.preferred_osd = l.preferred_osd; +	else +		nl.data_pool = ceph_file_layout_pg_pool(ci->i_layout); -	if ((nl.object_size & ~PAGE_MASK) || -	    (nl.stripe_unit & ~PAGE_MASK) || -	    ((unsigned)nl.object_size % (unsigned)nl.stripe_unit)) -		return -EINVAL; +	/* this is obsolete, and always -1 */ +	nl.preferred_osd = le64_to_cpu(-1); -	/* make sure it's a valid data pool */ -	if (l.data_pool > 0) { -		mutex_lock(&mdsc->mutex); -		err = -EINVAL; -		for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++) -			if (mdsc->mdsmap->m_data_pg_pools[i] == l.data_pool) { -				err = 0; -				break; -			} -		mutex_unlock(&mdsc->mutex); -		if (err) -			return err; -	} +	err = __validate_layout(mdsc, &nl); +	if (err) +		return err;  	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETLAYOUT,  				       USE_AUTH_MDS); @@ -106,8 +119,6 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg)  	req->r_args.setlayout.layout.fl_object_size =  		cpu_to_le32(l.object_size);  	req->r_args.setlayout.layout.fl_pg_pool = cpu_to_le32(l.data_pool); -	req->r_args.setlayout.layout.fl_pg_preferred = -		cpu_to_le32(l.preferred_osd);  	parent_inode = ceph_get_dentry_parent_inode(file->f_dentry);  	err = ceph_mdsc_do_request(mdsc, parent_inode, req); @@ -127,33 +138,16 @@ static long ceph_ioctl_set_layout_policy (struct file *file, void __user *arg)  	struct inode *inode = file->f_dentry->d_inode;  	struct ceph_mds_request *req;  	struct ceph_ioctl_layout l; -	int err, i; +	int err;  	struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;  	/* copy and validate */  	if (copy_from_user(&l, arg, sizeof(l)))  		return -EFAULT; -	if ((l.object_size & ~PAGE_MASK) || -	    (l.stripe_unit & ~PAGE_MASK) || -	    !l.stripe_unit || -	    (l.object_size && -	        (unsigned)l.object_size % (unsigned)l.stripe_unit)) -		return -EINVAL; - -	/* make sure it's a valid data pool */ -	if (l.data_pool > 0) { -		mutex_lock(&mdsc->mutex); -		err = -EINVAL; -		for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++) -			if (mdsc->mdsmap->m_data_pg_pools[i] == l.data_pool) { -				err = 0; -				break; -			} -		mutex_unlock(&mdsc->mutex); -		if (err) -			return err; -	} +	err = __validate_layout(mdsc, &l); +	if (err) +		return err;  	req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETDIRLAYOUT,  				       USE_AUTH_MDS); @@ -171,8 +165,6 @@ static long ceph_ioctl_set_layout_policy (struct file *file, void __user *arg)  			cpu_to_le32(l.object_size);  	req->r_args.setlayout.layout.fl_pg_pool =  			cpu_to_le32(l.data_pool); -	req->r_args.setlayout.layout.fl_pg_preferred = -			cpu_to_le32(l.preferred_osd);  	err = ceph_mdsc_do_request(mdsc, inode, req);  	ceph_mdsc_put_request(req);  |