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