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