ioctl.c (22603B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * linux/fs/ocfs2/ioctl.c 4 * 5 * Copyright (C) 2006 Herbert Poetzl 6 * adapted from Remy Card's ext2/ioctl.c 7 */ 8 9#include <linux/fs.h> 10#include <linux/mount.h> 11#include <linux/blkdev.h> 12#include <linux/compat.h> 13#include <linux/fileattr.h> 14 15#include <cluster/masklog.h> 16 17#include "ocfs2.h" 18#include "alloc.h" 19#include "dlmglue.h" 20#include "file.h" 21#include "inode.h" 22#include "journal.h" 23 24#include "ocfs2_fs.h" 25#include "ioctl.h" 26#include "resize.h" 27#include "refcounttree.h" 28#include "sysfile.h" 29#include "dir.h" 30#include "buffer_head_io.h" 31#include "suballoc.h" 32#include "move_extents.h" 33 34#define o2info_from_user(a, b) \ 35 copy_from_user(&(a), (b), sizeof(a)) 36#define o2info_to_user(a, b) \ 37 copy_to_user((typeof(a) __user *)b, &(a), sizeof(a)) 38 39/* 40 * This is just a best-effort to tell userspace that this request 41 * caused the error. 42 */ 43static inline void o2info_set_request_error(struct ocfs2_info_request *kreq, 44 struct ocfs2_info_request __user *req) 45{ 46 kreq->ir_flags |= OCFS2_INFO_FL_ERROR; 47 (void)put_user(kreq->ir_flags, (__u32 __user *)&(req->ir_flags)); 48} 49 50static inline void o2info_set_request_filled(struct ocfs2_info_request *req) 51{ 52 req->ir_flags |= OCFS2_INFO_FL_FILLED; 53} 54 55static inline void o2info_clear_request_filled(struct ocfs2_info_request *req) 56{ 57 req->ir_flags &= ~OCFS2_INFO_FL_FILLED; 58} 59 60static inline int o2info_coherent(struct ocfs2_info_request *req) 61{ 62 return (!(req->ir_flags & OCFS2_INFO_FL_NON_COHERENT)); 63} 64 65int ocfs2_fileattr_get(struct dentry *dentry, struct fileattr *fa) 66{ 67 struct inode *inode = d_inode(dentry); 68 unsigned int flags; 69 int status; 70 71 status = ocfs2_inode_lock(inode, NULL, 0); 72 if (status < 0) { 73 mlog_errno(status); 74 return status; 75 } 76 ocfs2_get_inode_flags(OCFS2_I(inode)); 77 flags = OCFS2_I(inode)->ip_attr; 78 ocfs2_inode_unlock(inode, 0); 79 80 fileattr_fill_flags(fa, flags & OCFS2_FL_VISIBLE); 81 82 return status; 83} 84 85int ocfs2_fileattr_set(struct user_namespace *mnt_userns, 86 struct dentry *dentry, struct fileattr *fa) 87{ 88 struct inode *inode = d_inode(dentry); 89 unsigned int flags = fa->flags; 90 struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode); 91 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 92 handle_t *handle = NULL; 93 struct buffer_head *bh = NULL; 94 unsigned oldflags; 95 int status; 96 97 if (fileattr_has_fsx(fa)) 98 return -EOPNOTSUPP; 99 100 status = ocfs2_inode_lock(inode, &bh, 1); 101 if (status < 0) { 102 mlog_errno(status); 103 goto bail; 104 } 105 106 if (!S_ISDIR(inode->i_mode)) 107 flags &= ~OCFS2_DIRSYNC_FL; 108 109 oldflags = ocfs2_inode->ip_attr; 110 flags = flags & OCFS2_FL_MODIFIABLE; 111 flags |= oldflags & ~OCFS2_FL_MODIFIABLE; 112 113 /* Check already done by VFS, but repeat with ocfs lock */ 114 status = -EPERM; 115 if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL) && 116 !capable(CAP_LINUX_IMMUTABLE)) 117 goto bail_unlock; 118 119 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); 120 if (IS_ERR(handle)) { 121 status = PTR_ERR(handle); 122 mlog_errno(status); 123 goto bail_unlock; 124 } 125 126 ocfs2_inode->ip_attr = flags; 127 ocfs2_set_inode_flags(inode); 128 129 status = ocfs2_mark_inode_dirty(handle, inode, bh); 130 if (status < 0) 131 mlog_errno(status); 132 133 ocfs2_commit_trans(osb, handle); 134 135bail_unlock: 136 ocfs2_inode_unlock(inode, 1); 137bail: 138 brelse(bh); 139 140 return status; 141} 142 143static int ocfs2_info_handle_blocksize(struct inode *inode, 144 struct ocfs2_info_request __user *req) 145{ 146 struct ocfs2_info_blocksize oib; 147 148 if (o2info_from_user(oib, req)) 149 return -EFAULT; 150 151 oib.ib_blocksize = inode->i_sb->s_blocksize; 152 153 o2info_set_request_filled(&oib.ib_req); 154 155 if (o2info_to_user(oib, req)) 156 return -EFAULT; 157 158 return 0; 159} 160 161static int ocfs2_info_handle_clustersize(struct inode *inode, 162 struct ocfs2_info_request __user *req) 163{ 164 struct ocfs2_info_clustersize oic; 165 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 166 167 if (o2info_from_user(oic, req)) 168 return -EFAULT; 169 170 oic.ic_clustersize = osb->s_clustersize; 171 172 o2info_set_request_filled(&oic.ic_req); 173 174 if (o2info_to_user(oic, req)) 175 return -EFAULT; 176 177 return 0; 178} 179 180static int ocfs2_info_handle_maxslots(struct inode *inode, 181 struct ocfs2_info_request __user *req) 182{ 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 return -EFAULT; 188 189 oim.im_max_slots = osb->max_slots; 190 191 o2info_set_request_filled(&oim.im_req); 192 193 if (o2info_to_user(oim, req)) 194 return -EFAULT; 195 196 return 0; 197} 198 199static int ocfs2_info_handle_label(struct inode *inode, 200 struct ocfs2_info_request __user *req) 201{ 202 struct ocfs2_info_label oil; 203 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 204 205 if (o2info_from_user(oil, req)) 206 return -EFAULT; 207 208 memcpy(oil.il_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN); 209 210 o2info_set_request_filled(&oil.il_req); 211 212 if (o2info_to_user(oil, req)) 213 return -EFAULT; 214 215 return 0; 216} 217 218static int ocfs2_info_handle_uuid(struct inode *inode, 219 struct ocfs2_info_request __user *req) 220{ 221 struct ocfs2_info_uuid oiu; 222 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 223 224 if (o2info_from_user(oiu, req)) 225 return -EFAULT; 226 227 memcpy(oiu.iu_uuid_str, osb->uuid_str, OCFS2_TEXT_UUID_LEN + 1); 228 229 o2info_set_request_filled(&oiu.iu_req); 230 231 if (o2info_to_user(oiu, req)) 232 return -EFAULT; 233 234 return 0; 235} 236 237static int ocfs2_info_handle_fs_features(struct inode *inode, 238 struct ocfs2_info_request __user *req) 239{ 240 struct ocfs2_info_fs_features oif; 241 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 242 243 if (o2info_from_user(oif, req)) 244 return -EFAULT; 245 246 oif.if_compat_features = osb->s_feature_compat; 247 oif.if_incompat_features = osb->s_feature_incompat; 248 oif.if_ro_compat_features = osb->s_feature_ro_compat; 249 250 o2info_set_request_filled(&oif.if_req); 251 252 if (o2info_to_user(oif, req)) 253 return -EFAULT; 254 255 return 0; 256} 257 258static int ocfs2_info_handle_journal_size(struct inode *inode, 259 struct ocfs2_info_request __user *req) 260{ 261 struct ocfs2_info_journal_size oij; 262 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 263 264 if (o2info_from_user(oij, req)) 265 return -EFAULT; 266 267 oij.ij_journal_size = i_size_read(osb->journal->j_inode); 268 269 o2info_set_request_filled(&oij.ij_req); 270 271 if (o2info_to_user(oij, req)) 272 return -EFAULT; 273 274 return 0; 275} 276 277static int ocfs2_info_scan_inode_alloc(struct ocfs2_super *osb, 278 struct inode *inode_alloc, u64 blkno, 279 struct ocfs2_info_freeinode *fi, 280 u32 slot) 281{ 282 int status = 0, unlock = 0; 283 284 struct buffer_head *bh = NULL; 285 struct ocfs2_dinode *dinode_alloc = NULL; 286 287 if (inode_alloc) 288 inode_lock(inode_alloc); 289 290 if (inode_alloc && o2info_coherent(&fi->ifi_req)) { 291 status = ocfs2_inode_lock(inode_alloc, &bh, 0); 292 if (status < 0) { 293 mlog_errno(status); 294 goto bail; 295 } 296 unlock = 1; 297 } else { 298 status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh); 299 if (status < 0) { 300 mlog_errno(status); 301 goto bail; 302 } 303 } 304 305 dinode_alloc = (struct ocfs2_dinode *)bh->b_data; 306 307 fi->ifi_stat[slot].lfi_total = 308 le32_to_cpu(dinode_alloc->id1.bitmap1.i_total); 309 fi->ifi_stat[slot].lfi_free = 310 le32_to_cpu(dinode_alloc->id1.bitmap1.i_total) - 311 le32_to_cpu(dinode_alloc->id1.bitmap1.i_used); 312 313bail: 314 if (unlock) 315 ocfs2_inode_unlock(inode_alloc, 0); 316 317 if (inode_alloc) 318 inode_unlock(inode_alloc); 319 320 brelse(bh); 321 322 return status; 323} 324 325static int ocfs2_info_handle_freeinode(struct inode *inode, 326 struct ocfs2_info_request __user *req) 327{ 328 u32 i; 329 u64 blkno = -1; 330 char namebuf[40]; 331 int status, type = INODE_ALLOC_SYSTEM_INODE; 332 struct ocfs2_info_freeinode *oifi = NULL; 333 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 334 struct inode *inode_alloc = NULL; 335 336 oifi = kzalloc(sizeof(struct ocfs2_info_freeinode), GFP_KERNEL); 337 if (!oifi) { 338 status = -ENOMEM; 339 mlog_errno(status); 340 goto out_err; 341 } 342 343 if (o2info_from_user(*oifi, req)) { 344 status = -EFAULT; 345 goto out_free; 346 } 347 348 oifi->ifi_slotnum = osb->max_slots; 349 350 for (i = 0; i < oifi->ifi_slotnum; i++) { 351 if (o2info_coherent(&oifi->ifi_req)) { 352 inode_alloc = ocfs2_get_system_file_inode(osb, type, i); 353 if (!inode_alloc) { 354 mlog(ML_ERROR, "unable to get alloc inode in " 355 "slot %u\n", i); 356 status = -EIO; 357 goto bail; 358 } 359 } else { 360 ocfs2_sprintf_system_inode_name(namebuf, 361 sizeof(namebuf), 362 type, i); 363 status = ocfs2_lookup_ino_from_name(osb->sys_root_inode, 364 namebuf, 365 strlen(namebuf), 366 &blkno); 367 if (status < 0) { 368 status = -ENOENT; 369 goto bail; 370 } 371 } 372 373 status = ocfs2_info_scan_inode_alloc(osb, inode_alloc, blkno, oifi, i); 374 375 iput(inode_alloc); 376 inode_alloc = NULL; 377 378 if (status < 0) 379 goto bail; 380 } 381 382 o2info_set_request_filled(&oifi->ifi_req); 383 384 if (o2info_to_user(*oifi, req)) { 385 status = -EFAULT; 386 goto out_free; 387 } 388 389 status = 0; 390bail: 391 if (status) 392 o2info_set_request_error(&oifi->ifi_req, req); 393out_free: 394 kfree(oifi); 395out_err: 396 return status; 397} 398 399static void o2ffg_update_histogram(struct ocfs2_info_free_chunk_list *hist, 400 unsigned int chunksize) 401{ 402 u32 index; 403 404 index = __ilog2_u32(chunksize); 405 if (index >= OCFS2_INFO_MAX_HIST) 406 index = OCFS2_INFO_MAX_HIST - 1; 407 408 hist->fc_chunks[index]++; 409 hist->fc_clusters[index] += chunksize; 410} 411 412static void o2ffg_update_stats(struct ocfs2_info_freefrag_stats *stats, 413 unsigned int chunksize) 414{ 415 if (chunksize > stats->ffs_max) 416 stats->ffs_max = chunksize; 417 418 if (chunksize < stats->ffs_min) 419 stats->ffs_min = chunksize; 420 421 stats->ffs_avg += chunksize; 422 stats->ffs_free_chunks_real++; 423} 424 425static void ocfs2_info_update_ffg(struct ocfs2_info_freefrag *ffg, 426 unsigned int chunksize) 427{ 428 o2ffg_update_histogram(&(ffg->iff_ffs.ffs_fc_hist), chunksize); 429 o2ffg_update_stats(&(ffg->iff_ffs), chunksize); 430} 431 432static int ocfs2_info_freefrag_scan_chain(struct ocfs2_super *osb, 433 struct inode *gb_inode, 434 struct ocfs2_dinode *gb_dinode, 435 struct ocfs2_chain_rec *rec, 436 struct ocfs2_info_freefrag *ffg, 437 u32 chunks_in_group) 438{ 439 int status = 0, used; 440 u64 blkno; 441 442 struct buffer_head *bh = NULL; 443 struct ocfs2_group_desc *bg = NULL; 444 445 unsigned int max_bits, num_clusters; 446 unsigned int offset = 0, cluster, chunk; 447 unsigned int chunk_free, last_chunksize = 0; 448 449 if (!le32_to_cpu(rec->c_free)) 450 goto bail; 451 452 do { 453 if (!bg) 454 blkno = le64_to_cpu(rec->c_blkno); 455 else 456 blkno = le64_to_cpu(bg->bg_next_group); 457 458 if (bh) { 459 brelse(bh); 460 bh = NULL; 461 } 462 463 if (o2info_coherent(&ffg->iff_req)) 464 status = ocfs2_read_group_descriptor(gb_inode, 465 gb_dinode, 466 blkno, &bh); 467 else 468 status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh); 469 470 if (status < 0) { 471 mlog(ML_ERROR, "Can't read the group descriptor # " 472 "%llu from device.", (unsigned long long)blkno); 473 status = -EIO; 474 goto bail; 475 } 476 477 bg = (struct ocfs2_group_desc *)bh->b_data; 478 479 if (!le16_to_cpu(bg->bg_free_bits_count)) 480 continue; 481 482 max_bits = le16_to_cpu(bg->bg_bits); 483 offset = 0; 484 485 for (chunk = 0; chunk < chunks_in_group; chunk++) { 486 /* 487 * last chunk may be not an entire one. 488 */ 489 if ((offset + ffg->iff_chunksize) > max_bits) 490 num_clusters = max_bits - offset; 491 else 492 num_clusters = ffg->iff_chunksize; 493 494 chunk_free = 0; 495 for (cluster = 0; cluster < num_clusters; cluster++) { 496 used = ocfs2_test_bit(offset, 497 (unsigned long *)bg->bg_bitmap); 498 /* 499 * - chunk_free counts free clusters in #N chunk. 500 * - last_chunksize records the size(in) clusters 501 * for the last real free chunk being counted. 502 */ 503 if (!used) { 504 last_chunksize++; 505 chunk_free++; 506 } 507 508 if (used && last_chunksize) { 509 ocfs2_info_update_ffg(ffg, 510 last_chunksize); 511 last_chunksize = 0; 512 } 513 514 offset++; 515 } 516 517 if (chunk_free == ffg->iff_chunksize) 518 ffg->iff_ffs.ffs_free_chunks++; 519 } 520 521 /* 522 * need to update the info for last free chunk. 523 */ 524 if (last_chunksize) 525 ocfs2_info_update_ffg(ffg, last_chunksize); 526 527 } while (le64_to_cpu(bg->bg_next_group)); 528 529bail: 530 brelse(bh); 531 532 return status; 533} 534 535static int ocfs2_info_freefrag_scan_bitmap(struct ocfs2_super *osb, 536 struct inode *gb_inode, u64 blkno, 537 struct ocfs2_info_freefrag *ffg) 538{ 539 u32 chunks_in_group; 540 int status = 0, unlock = 0, i; 541 542 struct buffer_head *bh = NULL; 543 struct ocfs2_chain_list *cl = NULL; 544 struct ocfs2_chain_rec *rec = NULL; 545 struct ocfs2_dinode *gb_dinode = NULL; 546 547 if (gb_inode) 548 inode_lock(gb_inode); 549 550 if (o2info_coherent(&ffg->iff_req)) { 551 status = ocfs2_inode_lock(gb_inode, &bh, 0); 552 if (status < 0) { 553 mlog_errno(status); 554 goto bail; 555 } 556 unlock = 1; 557 } else { 558 status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh); 559 if (status < 0) { 560 mlog_errno(status); 561 goto bail; 562 } 563 } 564 565 gb_dinode = (struct ocfs2_dinode *)bh->b_data; 566 cl = &(gb_dinode->id2.i_chain); 567 568 /* 569 * Chunksize(in) clusters from userspace should be 570 * less than clusters in a group. 571 */ 572 if (ffg->iff_chunksize > le16_to_cpu(cl->cl_cpg)) { 573 status = -EINVAL; 574 goto bail; 575 } 576 577 memset(&ffg->iff_ffs, 0, sizeof(struct ocfs2_info_freefrag_stats)); 578 579 ffg->iff_ffs.ffs_min = ~0U; 580 ffg->iff_ffs.ffs_clusters = 581 le32_to_cpu(gb_dinode->id1.bitmap1.i_total); 582 ffg->iff_ffs.ffs_free_clusters = ffg->iff_ffs.ffs_clusters - 583 le32_to_cpu(gb_dinode->id1.bitmap1.i_used); 584 585 chunks_in_group = le16_to_cpu(cl->cl_cpg) / ffg->iff_chunksize + 1; 586 587 for (i = 0; i < le16_to_cpu(cl->cl_next_free_rec); i++) { 588 rec = &(cl->cl_recs[i]); 589 status = ocfs2_info_freefrag_scan_chain(osb, gb_inode, 590 gb_dinode, 591 rec, ffg, 592 chunks_in_group); 593 if (status) 594 goto bail; 595 } 596 597 if (ffg->iff_ffs.ffs_free_chunks_real) 598 ffg->iff_ffs.ffs_avg = (ffg->iff_ffs.ffs_avg / 599 ffg->iff_ffs.ffs_free_chunks_real); 600bail: 601 if (unlock) 602 ocfs2_inode_unlock(gb_inode, 0); 603 604 if (gb_inode) 605 inode_unlock(gb_inode); 606 607 iput(gb_inode); 608 brelse(bh); 609 610 return status; 611} 612 613static int ocfs2_info_handle_freefrag(struct inode *inode, 614 struct ocfs2_info_request __user *req) 615{ 616 u64 blkno = -1; 617 char namebuf[40]; 618 int status, type = GLOBAL_BITMAP_SYSTEM_INODE; 619 620 struct ocfs2_info_freefrag *oiff; 621 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 622 struct inode *gb_inode = NULL; 623 624 oiff = kzalloc(sizeof(struct ocfs2_info_freefrag), GFP_KERNEL); 625 if (!oiff) { 626 status = -ENOMEM; 627 mlog_errno(status); 628 goto out_err; 629 } 630 631 if (o2info_from_user(*oiff, req)) { 632 status = -EFAULT; 633 goto out_free; 634 } 635 /* 636 * chunksize from userspace should be power of 2. 637 */ 638 if ((oiff->iff_chunksize & (oiff->iff_chunksize - 1)) || 639 (!oiff->iff_chunksize)) { 640 status = -EINVAL; 641 goto bail; 642 } 643 644 if (o2info_coherent(&oiff->iff_req)) { 645 gb_inode = ocfs2_get_system_file_inode(osb, type, 646 OCFS2_INVALID_SLOT); 647 if (!gb_inode) { 648 mlog(ML_ERROR, "unable to get global_bitmap inode\n"); 649 status = -EIO; 650 goto bail; 651 } 652 } else { 653 ocfs2_sprintf_system_inode_name(namebuf, sizeof(namebuf), type, 654 OCFS2_INVALID_SLOT); 655 status = ocfs2_lookup_ino_from_name(osb->sys_root_inode, 656 namebuf, 657 strlen(namebuf), 658 &blkno); 659 if (status < 0) { 660 status = -ENOENT; 661 goto bail; 662 } 663 } 664 665 status = ocfs2_info_freefrag_scan_bitmap(osb, gb_inode, blkno, oiff); 666 if (status < 0) 667 goto bail; 668 669 o2info_set_request_filled(&oiff->iff_req); 670 671 if (o2info_to_user(*oiff, req)) { 672 status = -EFAULT; 673 goto out_free; 674 } 675 676 status = 0; 677bail: 678 if (status) 679 o2info_set_request_error(&oiff->iff_req, req); 680out_free: 681 kfree(oiff); 682out_err: 683 return status; 684} 685 686static int ocfs2_info_handle_unknown(struct inode *inode, 687 struct ocfs2_info_request __user *req) 688{ 689 struct ocfs2_info_request oir; 690 691 if (o2info_from_user(oir, req)) 692 return -EFAULT; 693 694 o2info_clear_request_filled(&oir); 695 696 if (o2info_to_user(oir, req)) 697 return -EFAULT; 698 699 return 0; 700} 701 702/* 703 * Validate and distinguish OCFS2_IOC_INFO requests. 704 * 705 * - validate the magic number. 706 * - distinguish different requests. 707 * - validate size of different requests. 708 */ 709static int ocfs2_info_handle_request(struct inode *inode, 710 struct ocfs2_info_request __user *req) 711{ 712 int status = -EFAULT; 713 struct ocfs2_info_request oir; 714 715 if (o2info_from_user(oir, req)) 716 goto bail; 717 718 status = -EINVAL; 719 if (oir.ir_magic != OCFS2_INFO_MAGIC) 720 goto bail; 721 722 switch (oir.ir_code) { 723 case OCFS2_INFO_BLOCKSIZE: 724 if (oir.ir_size == sizeof(struct ocfs2_info_blocksize)) 725 status = ocfs2_info_handle_blocksize(inode, req); 726 break; 727 case OCFS2_INFO_CLUSTERSIZE: 728 if (oir.ir_size == sizeof(struct ocfs2_info_clustersize)) 729 status = ocfs2_info_handle_clustersize(inode, req); 730 break; 731 case OCFS2_INFO_MAXSLOTS: 732 if (oir.ir_size == sizeof(struct ocfs2_info_maxslots)) 733 status = ocfs2_info_handle_maxslots(inode, req); 734 break; 735 case OCFS2_INFO_LABEL: 736 if (oir.ir_size == sizeof(struct ocfs2_info_label)) 737 status = ocfs2_info_handle_label(inode, req); 738 break; 739 case OCFS2_INFO_UUID: 740 if (oir.ir_size == sizeof(struct ocfs2_info_uuid)) 741 status = ocfs2_info_handle_uuid(inode, req); 742 break; 743 case OCFS2_INFO_FS_FEATURES: 744 if (oir.ir_size == sizeof(struct ocfs2_info_fs_features)) 745 status = ocfs2_info_handle_fs_features(inode, req); 746 break; 747 case OCFS2_INFO_JOURNAL_SIZE: 748 if (oir.ir_size == sizeof(struct ocfs2_info_journal_size)) 749 status = ocfs2_info_handle_journal_size(inode, req); 750 break; 751 case OCFS2_INFO_FREEINODE: 752 if (oir.ir_size == sizeof(struct ocfs2_info_freeinode)) 753 status = ocfs2_info_handle_freeinode(inode, req); 754 break; 755 case OCFS2_INFO_FREEFRAG: 756 if (oir.ir_size == sizeof(struct ocfs2_info_freefrag)) 757 status = ocfs2_info_handle_freefrag(inode, req); 758 break; 759 default: 760 status = ocfs2_info_handle_unknown(inode, req); 761 break; 762 } 763 764bail: 765 return status; 766} 767 768static int ocfs2_get_request_ptr(struct ocfs2_info *info, int idx, 769 u64 *req_addr, int compat_flag) 770{ 771 int status = -EFAULT; 772 u64 __user *bp = NULL; 773 774 if (compat_flag) { 775#ifdef CONFIG_COMPAT 776 /* 777 * pointer bp stores the base address of a pointers array, 778 * which collects all addresses of separate request. 779 */ 780 bp = (u64 __user *)(unsigned long)compat_ptr(info->oi_requests); 781#else 782 BUG(); 783#endif 784 } else 785 bp = (u64 __user *)(unsigned long)(info->oi_requests); 786 787 if (o2info_from_user(*req_addr, bp + idx)) 788 goto bail; 789 790 status = 0; 791bail: 792 return status; 793} 794 795/* 796 * OCFS2_IOC_INFO handles an array of requests passed from userspace. 797 * 798 * ocfs2_info_handle() recevies a large info aggregation, grab and 799 * validate the request count from header, then break it into small 800 * pieces, later specific handlers can handle them one by one. 801 * 802 * Idea here is to make each separate request small enough to ensure 803 * a better backward&forward compatibility, since a small piece of 804 * request will be less likely to be broken if disk layout get changed. 805 */ 806static int ocfs2_info_handle(struct inode *inode, struct ocfs2_info *info, 807 int compat_flag) 808{ 809 int i, status = 0; 810 u64 req_addr; 811 struct ocfs2_info_request __user *reqp; 812 813 if ((info->oi_count > OCFS2_INFO_MAX_REQUEST) || 814 (!info->oi_requests)) { 815 status = -EINVAL; 816 goto bail; 817 } 818 819 for (i = 0; i < info->oi_count; i++) { 820 821 status = ocfs2_get_request_ptr(info, i, &req_addr, compat_flag); 822 if (status) 823 break; 824 825 reqp = (struct ocfs2_info_request __user *)(unsigned long)req_addr; 826 if (!reqp) { 827 status = -EINVAL; 828 goto bail; 829 } 830 831 status = ocfs2_info_handle_request(inode, reqp); 832 if (status) 833 break; 834 } 835 836bail: 837 return status; 838} 839 840long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 841{ 842 struct inode *inode = file_inode(filp); 843 int new_clusters; 844 int status; 845 struct ocfs2_space_resv sr; 846 struct ocfs2_new_group_input input; 847 struct reflink_arguments args; 848 const char __user *old_path; 849 const char __user *new_path; 850 bool preserve; 851 struct ocfs2_info info; 852 void __user *argp = (void __user *)arg; 853 854 switch (cmd) { 855 case OCFS2_IOC_RESVSP: 856 case OCFS2_IOC_RESVSP64: 857 case OCFS2_IOC_UNRESVSP: 858 case OCFS2_IOC_UNRESVSP64: 859 if (copy_from_user(&sr, (int __user *) arg, sizeof(sr))) 860 return -EFAULT; 861 862 return ocfs2_change_file_space(filp, cmd, &sr); 863 case OCFS2_IOC_GROUP_EXTEND: 864 if (!capable(CAP_SYS_RESOURCE)) 865 return -EPERM; 866 867 if (get_user(new_clusters, (int __user *)arg)) 868 return -EFAULT; 869 870 status = mnt_want_write_file(filp); 871 if (status) 872 return status; 873 status = ocfs2_group_extend(inode, new_clusters); 874 mnt_drop_write_file(filp); 875 return status; 876 case OCFS2_IOC_GROUP_ADD: 877 case OCFS2_IOC_GROUP_ADD64: 878 if (!capable(CAP_SYS_RESOURCE)) 879 return -EPERM; 880 881 if (copy_from_user(&input, (int __user *) arg, sizeof(input))) 882 return -EFAULT; 883 884 status = mnt_want_write_file(filp); 885 if (status) 886 return status; 887 status = ocfs2_group_add(inode, &input); 888 mnt_drop_write_file(filp); 889 return status; 890 case OCFS2_IOC_REFLINK: 891 if (copy_from_user(&args, argp, sizeof(args))) 892 return -EFAULT; 893 old_path = (const char __user *)(unsigned long)args.old_path; 894 new_path = (const char __user *)(unsigned long)args.new_path; 895 preserve = (args.preserve != 0); 896 897 return ocfs2_reflink_ioctl(inode, old_path, new_path, preserve); 898 case OCFS2_IOC_INFO: 899 if (copy_from_user(&info, argp, sizeof(struct ocfs2_info))) 900 return -EFAULT; 901 902 return ocfs2_info_handle(inode, &info, 0); 903 case FITRIM: 904 { 905 struct super_block *sb = inode->i_sb; 906 struct fstrim_range range; 907 int ret = 0; 908 909 if (!capable(CAP_SYS_ADMIN)) 910 return -EPERM; 911 912 if (!bdev_max_discard_sectors(sb->s_bdev)) 913 return -EOPNOTSUPP; 914 915 if (copy_from_user(&range, argp, sizeof(range))) 916 return -EFAULT; 917 918 range.minlen = max_t(u64, bdev_discard_granularity(sb->s_bdev), 919 range.minlen); 920 ret = ocfs2_trim_fs(sb, &range); 921 if (ret < 0) 922 return ret; 923 924 if (copy_to_user(argp, &range, sizeof(range))) 925 return -EFAULT; 926 927 return 0; 928 } 929 case OCFS2_IOC_MOVE_EXT: 930 return ocfs2_ioctl_move_extents(filp, argp); 931 default: 932 return -ENOTTY; 933 } 934} 935 936#ifdef CONFIG_COMPAT 937long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg) 938{ 939 bool preserve; 940 struct reflink_arguments args; 941 struct inode *inode = file_inode(file); 942 struct ocfs2_info info; 943 void __user *argp = (void __user *)arg; 944 945 switch (cmd) { 946 case OCFS2_IOC_RESVSP: 947 case OCFS2_IOC_RESVSP64: 948 case OCFS2_IOC_UNRESVSP: 949 case OCFS2_IOC_UNRESVSP64: 950 case OCFS2_IOC_GROUP_EXTEND: 951 case OCFS2_IOC_GROUP_ADD: 952 case OCFS2_IOC_GROUP_ADD64: 953 break; 954 case OCFS2_IOC_REFLINK: 955 if (copy_from_user(&args, argp, sizeof(args))) 956 return -EFAULT; 957 preserve = (args.preserve != 0); 958 959 return ocfs2_reflink_ioctl(inode, compat_ptr(args.old_path), 960 compat_ptr(args.new_path), preserve); 961 case OCFS2_IOC_INFO: 962 if (copy_from_user(&info, argp, sizeof(struct ocfs2_info))) 963 return -EFAULT; 964 965 return ocfs2_info_handle(inode, &info, 1); 966 case FITRIM: 967 case OCFS2_IOC_MOVE_EXT: 968 break; 969 default: 970 return -ENOIOCTLCMD; 971 } 972 973 return ocfs2_ioctl(file, cmd, arg); 974} 975#endif