diff options
-rw-r--r-- | fs/ceph/ioctl.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index 3b256b50f7d8..5a14c29cbba6 100644 --- a/fs/ceph/ioctl.c +++ b/fs/ceph/ioctl.c | |||
@@ -42,17 +42,39 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg) | |||
42 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; | 42 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; |
43 | struct ceph_mds_request *req; | 43 | struct ceph_mds_request *req; |
44 | struct ceph_ioctl_layout l; | 44 | struct ceph_ioctl_layout l; |
45 | struct ceph_inode_info *ci = ceph_inode(file->f_dentry->d_inode); | ||
46 | struct ceph_ioctl_layout nl; | ||
45 | int err, i; | 47 | int err, i; |
46 | 48 | ||
47 | /* copy and validate */ | ||
48 | if (copy_from_user(&l, arg, sizeof(l))) | 49 | if (copy_from_user(&l, arg, sizeof(l))) |
49 | return -EFAULT; | 50 | return -EFAULT; |
50 | 51 | ||
51 | if ((l.object_size & ~PAGE_MASK) || | 52 | /* validate changed params against current layout */ |
52 | (l.stripe_unit & ~PAGE_MASK) || | 53 | err = ceph_do_getattr(file->f_dentry->d_inode, CEPH_STAT_CAP_LAYOUT); |
53 | !l.stripe_unit || | 54 | if (!err) { |
54 | (l.object_size && | 55 | nl.stripe_unit = ceph_file_layout_su(ci->i_layout); |
55 | (unsigned)l.object_size % (unsigned)l.stripe_unit)) | 56 | nl.stripe_count = ceph_file_layout_stripe_count(ci->i_layout); |
57 | nl.object_size = ceph_file_layout_object_size(ci->i_layout); | ||
58 | nl.data_pool = le32_to_cpu(ci->i_layout.fl_pg_pool); | ||
59 | nl.preferred_osd = | ||
60 | (s32)le32_to_cpu(ci->i_layout.fl_pg_preferred); | ||
61 | } else | ||
62 | return err; | ||
63 | |||
64 | if (l.stripe_count) | ||
65 | nl.stripe_count = l.stripe_count; | ||
66 | if (l.stripe_unit) | ||
67 | nl.stripe_unit = l.stripe_unit; | ||
68 | if (l.object_size) | ||
69 | nl.object_size = l.object_size; | ||
70 | if (l.data_pool) | ||
71 | nl.data_pool = l.data_pool; | ||
72 | if (l.preferred_osd) | ||
73 | nl.preferred_osd = l.preferred_osd; | ||
74 | |||
75 | if ((nl.object_size & ~PAGE_MASK) || | ||
76 | (nl.stripe_unit & ~PAGE_MASK) || | ||
77 | ((unsigned)nl.object_size % (unsigned)nl.stripe_unit)) | ||
56 | return -EINVAL; | 78 | return -EINVAL; |
57 | 79 | ||
58 | /* make sure it's a valid data pool */ | 80 | /* make sure it's a valid data pool */ |