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) | |||
26 | l.stripe_count = ceph_file_layout_stripe_count(ci->i_layout); | 26 | l.stripe_count = ceph_file_layout_stripe_count(ci->i_layout); |
27 | l.object_size = ceph_file_layout_object_size(ci->i_layout); | 27 | l.object_size = ceph_file_layout_object_size(ci->i_layout); |
28 | l.data_pool = le32_to_cpu(ci->i_layout.fl_pg_pool); | 28 | l.data_pool = le32_to_cpu(ci->i_layout.fl_pg_pool); |
29 | l.preferred_osd = | 29 | l.preferred_osd = (s32)-1; |
30 | (s32)le32_to_cpu(ci->i_layout.fl_pg_preferred); | ||
31 | if (copy_to_user(arg, &l, sizeof(l))) | 30 | if (copy_to_user(arg, &l, sizeof(l))) |
32 | return -EFAULT; | 31 | return -EFAULT; |
33 | } | 32 | } |
@@ -35,6 +34,32 @@ static long ceph_ioctl_get_layout(struct file *file, void __user *arg) | |||
35 | return err; | 34 | return err; |
36 | } | 35 | } |
37 | 36 | ||
37 | static long __validate_layout(struct ceph_mds_client *mdsc, | ||
38 | struct ceph_ioctl_layout *l) | ||
39 | { | ||
40 | int i, err; | ||
41 | |||
42 | /* validate striping parameters */ | ||
43 | if ((l->object_size & ~PAGE_MASK) || | ||
44 | (l->stripe_unit & ~PAGE_MASK) || | ||
45 | ((unsigned)l->object_size % (unsigned)l->stripe_unit)) | ||
46 | return -EINVAL; | ||
47 | |||
48 | /* make sure it's a valid data pool */ | ||
49 | mutex_lock(&mdsc->mutex); | ||
50 | err = -EINVAL; | ||
51 | for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++) | ||
52 | if (mdsc->mdsmap->m_data_pg_pools[i] == l->data_pool) { | ||
53 | err = 0; | ||
54 | break; | ||
55 | } | ||
56 | mutex_unlock(&mdsc->mutex); | ||
57 | if (err) | ||
58 | return err; | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
38 | static long ceph_ioctl_set_layout(struct file *file, void __user *arg) | 63 | static long ceph_ioctl_set_layout(struct file *file, void __user *arg) |
39 | { | 64 | { |
40 | struct inode *inode = file->f_dentry->d_inode; | 65 | struct inode *inode = file->f_dentry->d_inode; |
@@ -44,52 +69,40 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg) | |||
44 | struct ceph_ioctl_layout l; | 69 | struct ceph_ioctl_layout l; |
45 | struct ceph_inode_info *ci = ceph_inode(file->f_dentry->d_inode); | 70 | struct ceph_inode_info *ci = ceph_inode(file->f_dentry->d_inode); |
46 | struct ceph_ioctl_layout nl; | 71 | struct ceph_ioctl_layout nl; |
47 | int err, i; | 72 | int err; |
48 | 73 | ||
49 | if (copy_from_user(&l, arg, sizeof(l))) | 74 | if (copy_from_user(&l, arg, sizeof(l))) |
50 | return -EFAULT; | 75 | return -EFAULT; |
51 | 76 | ||
52 | /* validate changed params against current layout */ | 77 | /* validate changed params against current layout */ |
53 | err = ceph_do_getattr(file->f_dentry->d_inode, CEPH_STAT_CAP_LAYOUT); | 78 | err = ceph_do_getattr(file->f_dentry->d_inode, CEPH_STAT_CAP_LAYOUT); |
54 | if (!err) { | 79 | if (err) |
55 | nl.stripe_unit = ceph_file_layout_su(ci->i_layout); | ||
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; | 80 | return err; |
63 | 81 | ||
82 | memset(&nl, 0, sizeof(nl)); | ||
64 | if (l.stripe_count) | 83 | if (l.stripe_count) |
65 | nl.stripe_count = l.stripe_count; | 84 | nl.stripe_count = l.stripe_count; |
85 | else | ||
86 | nl.stripe_count = ceph_file_layout_stripe_count(ci->i_layout); | ||
66 | if (l.stripe_unit) | 87 | if (l.stripe_unit) |
67 | nl.stripe_unit = l.stripe_unit; | 88 | nl.stripe_unit = l.stripe_unit; |
89 | else | ||
90 | nl.stripe_unit = ceph_file_layout_su(ci->i_layout); | ||
68 | if (l.object_size) | 91 | if (l.object_size) |
69 | nl.object_size = l.object_size; | 92 | nl.object_size = l.object_size; |
93 | else | ||
94 | nl.object_size = ceph_file_layout_object_size(ci->i_layout); | ||
70 | if (l.data_pool) | 95 | if (l.data_pool) |
71 | nl.data_pool = l.data_pool; | 96 | nl.data_pool = l.data_pool; |
72 | if (l.preferred_osd) | 97 | else |
73 | nl.preferred_osd = l.preferred_osd; | 98 | nl.data_pool = ceph_file_layout_pg_pool(ci->i_layout); |
74 | 99 | ||
75 | if ((nl.object_size & ~PAGE_MASK) || | 100 | /* this is obsolete, and always -1 */ |
76 | (nl.stripe_unit & ~PAGE_MASK) || | 101 | nl.preferred_osd = le64_to_cpu(-1); |
77 | ((unsigned)nl.object_size % (unsigned)nl.stripe_unit)) | ||
78 | return -EINVAL; | ||
79 | 102 | ||
80 | /* make sure it's a valid data pool */ | 103 | err = __validate_layout(mdsc, &nl); |
81 | if (l.data_pool > 0) { | 104 | if (err) |
82 | mutex_lock(&mdsc->mutex); | 105 | return err; |
83 | err = -EINVAL; | ||
84 | for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++) | ||
85 | if (mdsc->mdsmap->m_data_pg_pools[i] == l.data_pool) { | ||
86 | err = 0; | ||
87 | break; | ||
88 | } | ||
89 | mutex_unlock(&mdsc->mutex); | ||
90 | if (err) | ||
91 | return err; | ||
92 | } | ||
93 | 106 | ||
94 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETLAYOUT, | 107 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETLAYOUT, |
95 | USE_AUTH_MDS); | 108 | USE_AUTH_MDS); |
@@ -106,8 +119,6 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg) | |||
106 | req->r_args.setlayout.layout.fl_object_size = | 119 | req->r_args.setlayout.layout.fl_object_size = |
107 | cpu_to_le32(l.object_size); | 120 | cpu_to_le32(l.object_size); |
108 | req->r_args.setlayout.layout.fl_pg_pool = cpu_to_le32(l.data_pool); | 121 | req->r_args.setlayout.layout.fl_pg_pool = cpu_to_le32(l.data_pool); |
109 | req->r_args.setlayout.layout.fl_pg_preferred = | ||
110 | cpu_to_le32(l.preferred_osd); | ||
111 | 122 | ||
112 | parent_inode = ceph_get_dentry_parent_inode(file->f_dentry); | 123 | parent_inode = ceph_get_dentry_parent_inode(file->f_dentry); |
113 | err = ceph_mdsc_do_request(mdsc, parent_inode, req); | 124 | 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) | |||
127 | struct inode *inode = file->f_dentry->d_inode; | 138 | struct inode *inode = file->f_dentry->d_inode; |
128 | struct ceph_mds_request *req; | 139 | struct ceph_mds_request *req; |
129 | struct ceph_ioctl_layout l; | 140 | struct ceph_ioctl_layout l; |
130 | int err, i; | 141 | int err; |
131 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; | 142 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; |
132 | 143 | ||
133 | /* copy and validate */ | 144 | /* copy and validate */ |
134 | if (copy_from_user(&l, arg, sizeof(l))) | 145 | if (copy_from_user(&l, arg, sizeof(l))) |
135 | return -EFAULT; | 146 | return -EFAULT; |
136 | 147 | ||
137 | if ((l.object_size & ~PAGE_MASK) || | 148 | err = __validate_layout(mdsc, &l); |
138 | (l.stripe_unit & ~PAGE_MASK) || | 149 | if (err) |
139 | !l.stripe_unit || | 150 | return err; |
140 | (l.object_size && | ||
141 | (unsigned)l.object_size % (unsigned)l.stripe_unit)) | ||
142 | return -EINVAL; | ||
143 | |||
144 | /* make sure it's a valid data pool */ | ||
145 | if (l.data_pool > 0) { | ||
146 | mutex_lock(&mdsc->mutex); | ||
147 | err = -EINVAL; | ||
148 | for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++) | ||
149 | if (mdsc->mdsmap->m_data_pg_pools[i] == l.data_pool) { | ||
150 | err = 0; | ||
151 | break; | ||
152 | } | ||
153 | mutex_unlock(&mdsc->mutex); | ||
154 | if (err) | ||
155 | return err; | ||
156 | } | ||
157 | 151 | ||
158 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETDIRLAYOUT, | 152 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETDIRLAYOUT, |
159 | USE_AUTH_MDS); | 153 | USE_AUTH_MDS); |
@@ -171,8 +165,6 @@ static long ceph_ioctl_set_layout_policy (struct file *file, void __user *arg) | |||
171 | cpu_to_le32(l.object_size); | 165 | cpu_to_le32(l.object_size); |
172 | req->r_args.setlayout.layout.fl_pg_pool = | 166 | req->r_args.setlayout.layout.fl_pg_pool = |
173 | cpu_to_le32(l.data_pool); | 167 | cpu_to_le32(l.data_pool); |
174 | req->r_args.setlayout.layout.fl_pg_preferred = | ||
175 | cpu_to_le32(l.preferred_osd); | ||
176 | 168 | ||
177 | err = ceph_mdsc_do_request(mdsc, inode, req); | 169 | err = ceph_mdsc_do_request(mdsc, inode, req); |
178 | ceph_mdsc_put_request(req); | 170 | ceph_mdsc_put_request(req); |