aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/ioctl.c')
-rw-r--r--fs/ceph/ioctl.c102
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
37static 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
38static long ceph_ioctl_set_layout(struct file *file, void __user *arg) 63static 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);