1 /*
2  * linux/fs/ocfs2/ioctl.c
3  *
4  * Copyright (C) 2006 Herbert Poetzl
5  * adapted from Remy Card's ext2/ioctl.c
6  */
7 
8 #include <linux/fs.h>
9 #include <linux/mount.h>
10 #include <linux/compat.h>
11 
12 #include <cluster/masklog.h>
13 
14 #include "ocfs2.h"
15 #include "alloc.h"
16 #include "dlmglue.h"
17 #include "file.h"
18 #include "inode.h"
19 #include "journal.h"
20 
21 #include "ocfs2_fs.h"
22 #include "ioctl.h"
23 #include "resize.h"
24 #include "refcounttree.h"
25 
26 #include <linux/ext2_fs.h>
27 
28 #define o2info_from_user(a, b)	\
29 		copy_from_user(&(a), (b), sizeof(a))
30 #define o2info_to_user(a, b)	\
31 		copy_to_user((typeof(a) __user *)b, &(a), sizeof(a))
32 
33 /*
34  * This call is void because we are already reporting an error that may
35  * be -EFAULT.  The error will be returned from the ioctl(2) call.  It's
36  * just a best-effort to tell userspace that this request caused the error.
37  */
__o2info_set_request_error(struct ocfs2_info_request * kreq,struct ocfs2_info_request __user * req)38 static inline void __o2info_set_request_error(struct ocfs2_info_request *kreq,
39 					struct ocfs2_info_request __user *req)
40 {
41 	kreq->ir_flags |= OCFS2_INFO_FL_ERROR;
42 	(void)put_user(kreq->ir_flags, (__u32 __user *)&(req->ir_flags));
43 }
44 
45 #define o2info_set_request_error(a, b) \
46 		__o2info_set_request_error((struct ocfs2_info_request *)&(a), b)
47 
__o2info_set_request_filled(struct ocfs2_info_request * req)48 static inline void __o2info_set_request_filled(struct ocfs2_info_request *req)
49 {
50 	req->ir_flags |= OCFS2_INFO_FL_FILLED;
51 }
52 
53 #define o2info_set_request_filled(a) \
54 		__o2info_set_request_filled((struct ocfs2_info_request *)&(a))
55 
__o2info_clear_request_filled(struct ocfs2_info_request * req)56 static inline void __o2info_clear_request_filled(struct ocfs2_info_request *req)
57 {
58 	req->ir_flags &= ~OCFS2_INFO_FL_FILLED;
59 }
60 
61 #define o2info_clear_request_filled(a) \
62 		__o2info_clear_request_filled((struct ocfs2_info_request *)&(a))
63 
ocfs2_get_inode_attr(struct inode * inode,unsigned * flags)64 static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
65 {
66 	int status;
67 
68 	status = ocfs2_inode_lock(inode, NULL, 0);
69 	if (status < 0) {
70 		mlog_errno(status);
71 		return status;
72 	}
73 	ocfs2_get_inode_flags(OCFS2_I(inode));
74 	*flags = OCFS2_I(inode)->ip_attr;
75 	ocfs2_inode_unlock(inode, 0);
76 
77 	return status;
78 }
79 
ocfs2_set_inode_attr(struct inode * inode,unsigned flags,unsigned mask)80 static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
81 				unsigned mask)
82 {
83 	struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
84 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
85 	handle_t *handle = NULL;
86 	struct buffer_head *bh = NULL;
87 	unsigned oldflags;
88 	int status;
89 
90 	mutex_lock(&inode->i_mutex);
91 
92 	status = ocfs2_inode_lock(inode, &bh, 1);
93 	if (status < 0) {
94 		mlog_errno(status);
95 		goto bail;
96 	}
97 
98 	status = -EACCES;
99 	if (!inode_owner_or_capable(inode))
100 		goto bail_unlock;
101 
102 	if (!S_ISDIR(inode->i_mode))
103 		flags &= ~OCFS2_DIRSYNC_FL;
104 
105 	handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
106 	if (IS_ERR(handle)) {
107 		status = PTR_ERR(handle);
108 		mlog_errno(status);
109 		goto bail_unlock;
110 	}
111 
112 	oldflags = ocfs2_inode->ip_attr;
113 	flags = flags & mask;
114 	flags |= oldflags & ~mask;
115 
116 	/*
117 	 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
118 	 * the relevant capability.
119 	 */
120 	status = -EPERM;
121 	if ((oldflags & OCFS2_IMMUTABLE_FL) || ((flags ^ oldflags) &
122 		(OCFS2_APPEND_FL | OCFS2_IMMUTABLE_FL))) {
123 		if (!capable(CAP_LINUX_IMMUTABLE))
124 			goto bail_unlock;
125 	}
126 
127 	ocfs2_inode->ip_attr = flags;
128 	ocfs2_set_inode_flags(inode);
129 
130 	status = ocfs2_mark_inode_dirty(handle, inode, bh);
131 	if (status < 0)
132 		mlog_errno(status);
133 
134 	ocfs2_commit_trans(osb, handle);
135 bail_unlock:
136 	ocfs2_inode_unlock(inode, 1);
137 bail:
138 	mutex_unlock(&inode->i_mutex);
139 
140 	brelse(bh);
141 
142 	return status;
143 }
144 
ocfs2_info_handle_blocksize(struct inode * inode,struct ocfs2_info_request __user * req)145 int ocfs2_info_handle_blocksize(struct inode *inode,
146 				struct ocfs2_info_request __user *req)
147 {
148 	int status = -EFAULT;
149 	struct ocfs2_info_blocksize oib;
150 
151 	if (o2info_from_user(oib, req))
152 		goto bail;
153 
154 	oib.ib_blocksize = inode->i_sb->s_blocksize;
155 
156 	o2info_set_request_filled(oib);
157 
158 	if (o2info_to_user(oib, req))
159 		goto bail;
160 
161 	status = 0;
162 bail:
163 	if (status)
164 		o2info_set_request_error(oib, req);
165 
166 	return status;
167 }
168 
ocfs2_info_handle_clustersize(struct inode * inode,struct ocfs2_info_request __user * req)169 int ocfs2_info_handle_clustersize(struct inode *inode,
170 				  struct ocfs2_info_request __user *req)
171 {
172 	int status = -EFAULT;
173 	struct ocfs2_info_clustersize oic;
174 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
175 
176 	if (o2info_from_user(oic, req))
177 		goto bail;
178 
179 	oic.ic_clustersize = osb->s_clustersize;
180 
181 	o2info_set_request_filled(oic);
182 
183 	if (o2info_to_user(oic, req))
184 		goto bail;
185 
186 	status = 0;
187 bail:
188 	if (status)
189 		o2info_set_request_error(oic, req);
190 
191 	return status;
192 }
193 
ocfs2_info_handle_maxslots(struct inode * inode,struct ocfs2_info_request __user * req)194 int ocfs2_info_handle_maxslots(struct inode *inode,
195 			       struct ocfs2_info_request __user *req)
196 {
197 	int status = -EFAULT;
198 	struct ocfs2_info_maxslots oim;
199 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
200 
201 	if (o2info_from_user(oim, req))
202 		goto bail;
203 
204 	oim.im_max_slots = osb->max_slots;
205 
206 	o2info_set_request_filled(oim);
207 
208 	if (o2info_to_user(oim, req))
209 		goto bail;
210 
211 	status = 0;
212 bail:
213 	if (status)
214 		o2info_set_request_error(oim, req);
215 
216 	return status;
217 }
218 
ocfs2_info_handle_label(struct inode * inode,struct ocfs2_info_request __user * req)219 int ocfs2_info_handle_label(struct inode *inode,
220 			    struct ocfs2_info_request __user *req)
221 {
222 	int status = -EFAULT;
223 	struct ocfs2_info_label oil;
224 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
225 
226 	if (o2info_from_user(oil, req))
227 		goto bail;
228 
229 	memcpy(oil.il_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN);
230 
231 	o2info_set_request_filled(oil);
232 
233 	if (o2info_to_user(oil, req))
234 		goto bail;
235 
236 	status = 0;
237 bail:
238 	if (status)
239 		o2info_set_request_error(oil, req);
240 
241 	return status;
242 }
243 
ocfs2_info_handle_uuid(struct inode * inode,struct ocfs2_info_request __user * req)244 int ocfs2_info_handle_uuid(struct inode *inode,
245 			   struct ocfs2_info_request __user *req)
246 {
247 	int status = -EFAULT;
248 	struct ocfs2_info_uuid oiu;
249 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
250 
251 	if (o2info_from_user(oiu, req))
252 		goto bail;
253 
254 	memcpy(oiu.iu_uuid_str, osb->uuid_str, OCFS2_TEXT_UUID_LEN + 1);
255 
256 	o2info_set_request_filled(oiu);
257 
258 	if (o2info_to_user(oiu, req))
259 		goto bail;
260 
261 	status = 0;
262 bail:
263 	if (status)
264 		o2info_set_request_error(oiu, req);
265 
266 	return status;
267 }
268 
ocfs2_info_handle_fs_features(struct inode * inode,struct ocfs2_info_request __user * req)269 int ocfs2_info_handle_fs_features(struct inode *inode,
270 				  struct ocfs2_info_request __user *req)
271 {
272 	int status = -EFAULT;
273 	struct ocfs2_info_fs_features oif;
274 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
275 
276 	if (o2info_from_user(oif, req))
277 		goto bail;
278 
279 	oif.if_compat_features = osb->s_feature_compat;
280 	oif.if_incompat_features = osb->s_feature_incompat;
281 	oif.if_ro_compat_features = osb->s_feature_ro_compat;
282 
283 	o2info_set_request_filled(oif);
284 
285 	if (o2info_to_user(oif, req))
286 		goto bail;
287 
288 	status = 0;
289 bail:
290 	if (status)
291 		o2info_set_request_error(oif, req);
292 
293 	return status;
294 }
295 
ocfs2_info_handle_journal_size(struct inode * inode,struct ocfs2_info_request __user * req)296 int ocfs2_info_handle_journal_size(struct inode *inode,
297 				   struct ocfs2_info_request __user *req)
298 {
299 	int status = -EFAULT;
300 	struct ocfs2_info_journal_size oij;
301 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
302 
303 	if (o2info_from_user(oij, req))
304 		goto bail;
305 
306 	oij.ij_journal_size = osb->journal->j_inode->i_size;
307 
308 	o2info_set_request_filled(oij);
309 
310 	if (o2info_to_user(oij, req))
311 		goto bail;
312 
313 	status = 0;
314 bail:
315 	if (status)
316 		o2info_set_request_error(oij, req);
317 
318 	return status;
319 }
320 
ocfs2_info_handle_unknown(struct inode * inode,struct ocfs2_info_request __user * req)321 int ocfs2_info_handle_unknown(struct inode *inode,
322 			      struct ocfs2_info_request __user *req)
323 {
324 	int status = -EFAULT;
325 	struct ocfs2_info_request oir;
326 
327 	if (o2info_from_user(oir, req))
328 		goto bail;
329 
330 	o2info_clear_request_filled(oir);
331 
332 	if (o2info_to_user(oir, req))
333 		goto bail;
334 
335 	status = 0;
336 bail:
337 	if (status)
338 		o2info_set_request_error(oir, req);
339 
340 	return status;
341 }
342 
343 /*
344  * Validate and distinguish OCFS2_IOC_INFO requests.
345  *
346  * - validate the magic number.
347  * - distinguish different requests.
348  * - validate size of different requests.
349  */
ocfs2_info_handle_request(struct inode * inode,struct ocfs2_info_request __user * req)350 int ocfs2_info_handle_request(struct inode *inode,
351 			      struct ocfs2_info_request __user *req)
352 {
353 	int status = -EFAULT;
354 	struct ocfs2_info_request oir;
355 
356 	if (o2info_from_user(oir, req))
357 		goto bail;
358 
359 	status = -EINVAL;
360 	if (oir.ir_magic != OCFS2_INFO_MAGIC)
361 		goto bail;
362 
363 	switch (oir.ir_code) {
364 	case OCFS2_INFO_BLOCKSIZE:
365 		if (oir.ir_size == sizeof(struct ocfs2_info_blocksize))
366 			status = ocfs2_info_handle_blocksize(inode, req);
367 		break;
368 	case OCFS2_INFO_CLUSTERSIZE:
369 		if (oir.ir_size == sizeof(struct ocfs2_info_clustersize))
370 			status = ocfs2_info_handle_clustersize(inode, req);
371 		break;
372 	case OCFS2_INFO_MAXSLOTS:
373 		if (oir.ir_size == sizeof(struct ocfs2_info_maxslots))
374 			status = ocfs2_info_handle_maxslots(inode, req);
375 		break;
376 	case OCFS2_INFO_LABEL:
377 		if (oir.ir_size == sizeof(struct ocfs2_info_label))
378 			status = ocfs2_info_handle_label(inode, req);
379 		break;
380 	case OCFS2_INFO_UUID:
381 		if (oir.ir_size == sizeof(struct ocfs2_info_uuid))
382 			status = ocfs2_info_handle_uuid(inode, req);
383 		break;
384 	case OCFS2_INFO_FS_FEATURES:
385 		if (oir.ir_size == sizeof(struct ocfs2_info_fs_features))
386 			status = ocfs2_info_handle_fs_features(inode, req);
387 		break;
388 	case OCFS2_INFO_JOURNAL_SIZE:
389 		if (oir.ir_size == sizeof(struct ocfs2_info_journal_size))
390 			status = ocfs2_info_handle_journal_size(inode, req);
391 		break;
392 	default:
393 		status = ocfs2_info_handle_unknown(inode, req);
394 		break;
395 	}
396 
397 bail:
398 	return status;
399 }
400 
ocfs2_get_request_ptr(struct ocfs2_info * info,int idx,u64 * req_addr,int compat_flag)401 int ocfs2_get_request_ptr(struct ocfs2_info *info, int idx,
402 			  u64 *req_addr, int compat_flag)
403 {
404 	int status = -EFAULT;
405 	u64 __user *bp = NULL;
406 
407 	if (compat_flag) {
408 #ifdef CONFIG_COMPAT
409 		/*
410 		 * pointer bp stores the base address of a pointers array,
411 		 * which collects all addresses of separate request.
412 		 */
413 		bp = (u64 __user *)(unsigned long)compat_ptr(info->oi_requests);
414 #else
415 		BUG();
416 #endif
417 	} else
418 		bp = (u64 __user *)(unsigned long)(info->oi_requests);
419 
420 	if (o2info_from_user(*req_addr, bp + idx))
421 		goto bail;
422 
423 	status = 0;
424 bail:
425 	return status;
426 }
427 
428 /*
429  * OCFS2_IOC_INFO handles an array of requests passed from userspace.
430  *
431  * ocfs2_info_handle() recevies a large info aggregation, grab and
432  * validate the request count from header, then break it into small
433  * pieces, later specific handlers can handle them one by one.
434  *
435  * Idea here is to make each separate request small enough to ensure
436  * a better backward&forward compatibility, since a small piece of
437  * request will be less likely to be broken if disk layout get changed.
438  */
ocfs2_info_handle(struct inode * inode,struct ocfs2_info * info,int compat_flag)439 int ocfs2_info_handle(struct inode *inode, struct ocfs2_info *info,
440 		      int compat_flag)
441 {
442 	int i, status = 0;
443 	u64 req_addr;
444 	struct ocfs2_info_request __user *reqp;
445 
446 	if ((info->oi_count > OCFS2_INFO_MAX_REQUEST) ||
447 	    (!info->oi_requests)) {
448 		status = -EINVAL;
449 		goto bail;
450 	}
451 
452 	for (i = 0; i < info->oi_count; i++) {
453 
454 		status = ocfs2_get_request_ptr(info, i, &req_addr, compat_flag);
455 		if (status)
456 			break;
457 
458 		reqp = (struct ocfs2_info_request *)(unsigned long)req_addr;
459 		if (!reqp) {
460 			status = -EINVAL;
461 			goto bail;
462 		}
463 
464 		status = ocfs2_info_handle_request(inode, reqp);
465 		if (status)
466 			break;
467 	}
468 
469 bail:
470 	return status;
471 }
472 
ocfs2_ioctl(struct file * filp,unsigned int cmd,unsigned long arg)473 long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
474 {
475 	struct inode *inode = filp->f_path.dentry->d_inode;
476 	unsigned int flags;
477 	int new_clusters;
478 	int status;
479 	struct ocfs2_space_resv sr;
480 	struct ocfs2_new_group_input input;
481 	struct reflink_arguments args;
482 	const char *old_path, *new_path;
483 	bool preserve;
484 	struct ocfs2_info info;
485 
486 	switch (cmd) {
487 	case OCFS2_IOC_GETFLAGS:
488 		status = ocfs2_get_inode_attr(inode, &flags);
489 		if (status < 0)
490 			return status;
491 
492 		flags &= OCFS2_FL_VISIBLE;
493 		return put_user(flags, (int __user *) arg);
494 	case OCFS2_IOC_SETFLAGS:
495 		if (get_user(flags, (int __user *) arg))
496 			return -EFAULT;
497 
498 		status = mnt_want_write(filp->f_path.mnt);
499 		if (status)
500 			return status;
501 		status = ocfs2_set_inode_attr(inode, flags,
502 			OCFS2_FL_MODIFIABLE);
503 		mnt_drop_write(filp->f_path.mnt);
504 		return status;
505 	case OCFS2_IOC_RESVSP:
506 	case OCFS2_IOC_RESVSP64:
507 	case OCFS2_IOC_UNRESVSP:
508 	case OCFS2_IOC_UNRESVSP64:
509 		if (copy_from_user(&sr, (int __user *) arg, sizeof(sr)))
510 			return -EFAULT;
511 
512 		return ocfs2_change_file_space(filp, cmd, &sr);
513 	case OCFS2_IOC_GROUP_EXTEND:
514 		if (!capable(CAP_SYS_RESOURCE))
515 			return -EPERM;
516 
517 		if (get_user(new_clusters, (int __user *)arg))
518 			return -EFAULT;
519 
520 		return ocfs2_group_extend(inode, new_clusters);
521 	case OCFS2_IOC_GROUP_ADD:
522 	case OCFS2_IOC_GROUP_ADD64:
523 		if (!capable(CAP_SYS_RESOURCE))
524 			return -EPERM;
525 
526 		if (copy_from_user(&input, (int __user *) arg, sizeof(input)))
527 			return -EFAULT;
528 
529 		return ocfs2_group_add(inode, &input);
530 	case OCFS2_IOC_REFLINK:
531 		if (copy_from_user(&args, (struct reflink_arguments *)arg,
532 				   sizeof(args)))
533 			return -EFAULT;
534 		old_path = (const char *)(unsigned long)args.old_path;
535 		new_path = (const char *)(unsigned long)args.new_path;
536 		preserve = (args.preserve != 0);
537 
538 		return ocfs2_reflink_ioctl(inode, old_path, new_path, preserve);
539 	case OCFS2_IOC_INFO:
540 		if (copy_from_user(&info, (struct ocfs2_info __user *)arg,
541 				   sizeof(struct ocfs2_info)))
542 			return -EFAULT;
543 
544 		return ocfs2_info_handle(inode, &info, 0);
545 	default:
546 		return -ENOTTY;
547 	}
548 }
549 
550 #ifdef CONFIG_COMPAT
ocfs2_compat_ioctl(struct file * file,unsigned cmd,unsigned long arg)551 long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
552 {
553 	bool preserve;
554 	struct reflink_arguments args;
555 	struct inode *inode = file->f_path.dentry->d_inode;
556 	struct ocfs2_info info;
557 
558 	switch (cmd) {
559 	case OCFS2_IOC32_GETFLAGS:
560 		cmd = OCFS2_IOC_GETFLAGS;
561 		break;
562 	case OCFS2_IOC32_SETFLAGS:
563 		cmd = OCFS2_IOC_SETFLAGS;
564 		break;
565 	case OCFS2_IOC_RESVSP:
566 	case OCFS2_IOC_RESVSP64:
567 	case OCFS2_IOC_UNRESVSP:
568 	case OCFS2_IOC_UNRESVSP64:
569 	case OCFS2_IOC_GROUP_EXTEND:
570 	case OCFS2_IOC_GROUP_ADD:
571 	case OCFS2_IOC_GROUP_ADD64:
572 		break;
573 	case OCFS2_IOC_REFLINK:
574 		if (copy_from_user(&args, (struct reflink_arguments *)arg,
575 				   sizeof(args)))
576 			return -EFAULT;
577 		preserve = (args.preserve != 0);
578 
579 		return ocfs2_reflink_ioctl(inode, compat_ptr(args.old_path),
580 					   compat_ptr(args.new_path), preserve);
581 	case OCFS2_IOC_INFO:
582 		if (copy_from_user(&info, (struct ocfs2_info __user *)arg,
583 				   sizeof(struct ocfs2_info)))
584 			return -EFAULT;
585 
586 		return ocfs2_info_handle(inode, &info, 1);
587 	default:
588 		return -ENOIOCTLCMD;
589 	}
590 
591 	return ocfs2_ioctl(file, cmd, arg);
592 }
593 #endif
594