linux/fs/ocfs2/ioctl.c
<<
>>
Prefs
   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 request_queue *q = bdev_get_queue(sb->s_bdev);
 907                struct fstrim_range range;
 908                int ret = 0;
 909
 910                if (!capable(CAP_SYS_ADMIN))
 911                        return -EPERM;
 912
 913                if (!blk_queue_discard(q))
 914                        return -EOPNOTSUPP;
 915
 916                if (copy_from_user(&range, argp, sizeof(range)))
 917                        return -EFAULT;
 918
 919                range.minlen = max_t(u64, q->limits.discard_granularity,
 920                                     range.minlen);
 921                ret = ocfs2_trim_fs(sb, &range);
 922                if (ret < 0)
 923                        return ret;
 924
 925                if (copy_to_user(argp, &range, sizeof(range)))
 926                        return -EFAULT;
 927
 928                return 0;
 929        }
 930        case OCFS2_IOC_MOVE_EXT:
 931                return ocfs2_ioctl_move_extents(filp, argp);
 932        default:
 933                return -ENOTTY;
 934        }
 935}
 936
 937#ifdef CONFIG_COMPAT
 938long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 939{
 940        bool preserve;
 941        struct reflink_arguments args;
 942        struct inode *inode = file_inode(file);
 943        struct ocfs2_info info;
 944        void __user *argp = (void __user *)arg;
 945
 946        switch (cmd) {
 947        case OCFS2_IOC_RESVSP:
 948        case OCFS2_IOC_RESVSP64:
 949        case OCFS2_IOC_UNRESVSP:
 950        case OCFS2_IOC_UNRESVSP64:
 951        case OCFS2_IOC_GROUP_EXTEND:
 952        case OCFS2_IOC_GROUP_ADD:
 953        case OCFS2_IOC_GROUP_ADD64:
 954                break;
 955        case OCFS2_IOC_REFLINK:
 956                if (copy_from_user(&args, argp, sizeof(args)))
 957                        return -EFAULT;
 958                preserve = (args.preserve != 0);
 959
 960                return ocfs2_reflink_ioctl(inode, compat_ptr(args.old_path),
 961                                           compat_ptr(args.new_path), preserve);
 962        case OCFS2_IOC_INFO:
 963                if (copy_from_user(&info, argp, sizeof(struct ocfs2_info)))
 964                        return -EFAULT;
 965
 966                return ocfs2_info_handle(inode, &info, 1);
 967        case FITRIM:
 968        case OCFS2_IOC_MOVE_EXT:
 969                break;
 970        default:
 971                return -ENOIOCTLCMD;
 972        }
 973
 974        return ocfs2_ioctl(file, cmd, arg);
 975}
 976#endif
 977