Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * linux/fs/ocfs2/ioctl.c
0004  *
0005  * Copyright (C) 2006 Herbert Poetzl
0006  * adapted from Remy Card's ext2/ioctl.c
0007  */
0008 
0009 #include <linux/fs.h>
0010 #include <linux/mount.h>
0011 #include <linux/blkdev.h>
0012 #include <linux/compat.h>
0013 #include <linux/fileattr.h>
0014 
0015 #include <cluster/masklog.h>
0016 
0017 #include "ocfs2.h"
0018 #include "alloc.h"
0019 #include "dlmglue.h"
0020 #include "file.h"
0021 #include "inode.h"
0022 #include "journal.h"
0023 
0024 #include "ocfs2_fs.h"
0025 #include "ioctl.h"
0026 #include "resize.h"
0027 #include "refcounttree.h"
0028 #include "sysfile.h"
0029 #include "dir.h"
0030 #include "buffer_head_io.h"
0031 #include "suballoc.h"
0032 #include "move_extents.h"
0033 
0034 #define o2info_from_user(a, b)  \
0035         copy_from_user(&(a), (b), sizeof(a))
0036 #define o2info_to_user(a, b)    \
0037         copy_to_user((typeof(a) __user *)b, &(a), sizeof(a))
0038 
0039 /*
0040  * This is just a best-effort to tell userspace that this request
0041  * caused the error.
0042  */
0043 static inline void o2info_set_request_error(struct ocfs2_info_request *kreq,
0044                     struct ocfs2_info_request __user *req)
0045 {
0046     kreq->ir_flags |= OCFS2_INFO_FL_ERROR;
0047     (void)put_user(kreq->ir_flags, (__u32 __user *)&(req->ir_flags));
0048 }
0049 
0050 static inline void o2info_set_request_filled(struct ocfs2_info_request *req)
0051 {
0052     req->ir_flags |= OCFS2_INFO_FL_FILLED;
0053 }
0054 
0055 static inline void o2info_clear_request_filled(struct ocfs2_info_request *req)
0056 {
0057     req->ir_flags &= ~OCFS2_INFO_FL_FILLED;
0058 }
0059 
0060 static inline int o2info_coherent(struct ocfs2_info_request *req)
0061 {
0062     return (!(req->ir_flags & OCFS2_INFO_FL_NON_COHERENT));
0063 }
0064 
0065 int ocfs2_fileattr_get(struct dentry *dentry, struct fileattr *fa)
0066 {
0067     struct inode *inode = d_inode(dentry);
0068     unsigned int flags;
0069     int status;
0070 
0071     status = ocfs2_inode_lock(inode, NULL, 0);
0072     if (status < 0) {
0073         mlog_errno(status);
0074         return status;
0075     }
0076     ocfs2_get_inode_flags(OCFS2_I(inode));
0077     flags = OCFS2_I(inode)->ip_attr;
0078     ocfs2_inode_unlock(inode, 0);
0079 
0080     fileattr_fill_flags(fa, flags & OCFS2_FL_VISIBLE);
0081 
0082     return status;
0083 }
0084 
0085 int ocfs2_fileattr_set(struct user_namespace *mnt_userns,
0086                struct dentry *dentry, struct fileattr *fa)
0087 {
0088     struct inode *inode = d_inode(dentry);
0089     unsigned int flags = fa->flags;
0090     struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
0091     struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
0092     handle_t *handle = NULL;
0093     struct buffer_head *bh = NULL;
0094     unsigned oldflags;
0095     int status;
0096 
0097     if (fileattr_has_fsx(fa))
0098         return -EOPNOTSUPP;
0099 
0100     status = ocfs2_inode_lock(inode, &bh, 1);
0101     if (status < 0) {
0102         mlog_errno(status);
0103         goto bail;
0104     }
0105 
0106     if (!S_ISDIR(inode->i_mode))
0107         flags &= ~OCFS2_DIRSYNC_FL;
0108 
0109     oldflags = ocfs2_inode->ip_attr;
0110     flags = flags & OCFS2_FL_MODIFIABLE;
0111     flags |= oldflags & ~OCFS2_FL_MODIFIABLE;
0112 
0113     /* Check already done by VFS, but repeat with ocfs lock */
0114     status = -EPERM;
0115     if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL) &&
0116         !capable(CAP_LINUX_IMMUTABLE))
0117         goto bail_unlock;
0118 
0119     handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
0120     if (IS_ERR(handle)) {
0121         status = PTR_ERR(handle);
0122         mlog_errno(status);
0123         goto bail_unlock;
0124     }
0125 
0126     ocfs2_inode->ip_attr = flags;
0127     ocfs2_set_inode_flags(inode);
0128 
0129     status = ocfs2_mark_inode_dirty(handle, inode, bh);
0130     if (status < 0)
0131         mlog_errno(status);
0132 
0133     ocfs2_commit_trans(osb, handle);
0134 
0135 bail_unlock:
0136     ocfs2_inode_unlock(inode, 1);
0137 bail:
0138     brelse(bh);
0139 
0140     return status;
0141 }
0142 
0143 static int ocfs2_info_handle_blocksize(struct inode *inode,
0144                        struct ocfs2_info_request __user *req)
0145 {
0146     struct ocfs2_info_blocksize oib;
0147 
0148     if (o2info_from_user(oib, req))
0149         return -EFAULT;
0150 
0151     oib.ib_blocksize = inode->i_sb->s_blocksize;
0152 
0153     o2info_set_request_filled(&oib.ib_req);
0154 
0155     if (o2info_to_user(oib, req))
0156         return -EFAULT;
0157 
0158     return 0;
0159 }
0160 
0161 static int ocfs2_info_handle_clustersize(struct inode *inode,
0162                      struct ocfs2_info_request __user *req)
0163 {
0164     struct ocfs2_info_clustersize oic;
0165     struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
0166 
0167     if (o2info_from_user(oic, req))
0168         return -EFAULT;
0169 
0170     oic.ic_clustersize = osb->s_clustersize;
0171 
0172     o2info_set_request_filled(&oic.ic_req);
0173 
0174     if (o2info_to_user(oic, req))
0175         return -EFAULT;
0176 
0177     return 0;
0178 }
0179 
0180 static int ocfs2_info_handle_maxslots(struct inode *inode,
0181                       struct ocfs2_info_request __user *req)
0182 {
0183     struct ocfs2_info_maxslots oim;
0184     struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
0185 
0186     if (o2info_from_user(oim, req))
0187         return -EFAULT;
0188 
0189     oim.im_max_slots = osb->max_slots;
0190 
0191     o2info_set_request_filled(&oim.im_req);
0192 
0193     if (o2info_to_user(oim, req))
0194         return -EFAULT;
0195 
0196     return 0;
0197 }
0198 
0199 static int ocfs2_info_handle_label(struct inode *inode,
0200                    struct ocfs2_info_request __user *req)
0201 {
0202     struct ocfs2_info_label oil;
0203     struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
0204 
0205     if (o2info_from_user(oil, req))
0206         return -EFAULT;
0207 
0208     memcpy(oil.il_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN);
0209 
0210     o2info_set_request_filled(&oil.il_req);
0211 
0212     if (o2info_to_user(oil, req))
0213         return -EFAULT;
0214 
0215     return 0;
0216 }
0217 
0218 static int ocfs2_info_handle_uuid(struct inode *inode,
0219                   struct ocfs2_info_request __user *req)
0220 {
0221     struct ocfs2_info_uuid oiu;
0222     struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
0223 
0224     if (o2info_from_user(oiu, req))
0225         return -EFAULT;
0226 
0227     memcpy(oiu.iu_uuid_str, osb->uuid_str, OCFS2_TEXT_UUID_LEN + 1);
0228 
0229     o2info_set_request_filled(&oiu.iu_req);
0230 
0231     if (o2info_to_user(oiu, req))
0232         return -EFAULT;
0233 
0234     return 0;
0235 }
0236 
0237 static int ocfs2_info_handle_fs_features(struct inode *inode,
0238                      struct ocfs2_info_request __user *req)
0239 {
0240     struct ocfs2_info_fs_features oif;
0241     struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
0242 
0243     if (o2info_from_user(oif, req))
0244         return -EFAULT;
0245 
0246     oif.if_compat_features = osb->s_feature_compat;
0247     oif.if_incompat_features = osb->s_feature_incompat;
0248     oif.if_ro_compat_features = osb->s_feature_ro_compat;
0249 
0250     o2info_set_request_filled(&oif.if_req);
0251 
0252     if (o2info_to_user(oif, req))
0253         return -EFAULT;
0254 
0255     return 0;
0256 }
0257 
0258 static int ocfs2_info_handle_journal_size(struct inode *inode,
0259                       struct ocfs2_info_request __user *req)
0260 {
0261     struct ocfs2_info_journal_size oij;
0262     struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
0263 
0264     if (o2info_from_user(oij, req))
0265         return -EFAULT;
0266 
0267     oij.ij_journal_size = i_size_read(osb->journal->j_inode);
0268 
0269     o2info_set_request_filled(&oij.ij_req);
0270 
0271     if (o2info_to_user(oij, req))
0272         return -EFAULT;
0273 
0274     return 0;
0275 }
0276 
0277 static int ocfs2_info_scan_inode_alloc(struct ocfs2_super *osb,
0278                        struct inode *inode_alloc, u64 blkno,
0279                        struct ocfs2_info_freeinode *fi,
0280                        u32 slot)
0281 {
0282     int status = 0, unlock = 0;
0283 
0284     struct buffer_head *bh = NULL;
0285     struct ocfs2_dinode *dinode_alloc = NULL;
0286 
0287     if (inode_alloc)
0288         inode_lock(inode_alloc);
0289 
0290     if (inode_alloc && o2info_coherent(&fi->ifi_req)) {
0291         status = ocfs2_inode_lock(inode_alloc, &bh, 0);
0292         if (status < 0) {
0293             mlog_errno(status);
0294             goto bail;
0295         }
0296         unlock = 1;
0297     } else {
0298         status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
0299         if (status < 0) {
0300             mlog_errno(status);
0301             goto bail;
0302         }
0303     }
0304 
0305     dinode_alloc = (struct ocfs2_dinode *)bh->b_data;
0306 
0307     fi->ifi_stat[slot].lfi_total =
0308         le32_to_cpu(dinode_alloc->id1.bitmap1.i_total);
0309     fi->ifi_stat[slot].lfi_free =
0310         le32_to_cpu(dinode_alloc->id1.bitmap1.i_total) -
0311         le32_to_cpu(dinode_alloc->id1.bitmap1.i_used);
0312 
0313 bail:
0314     if (unlock)
0315         ocfs2_inode_unlock(inode_alloc, 0);
0316 
0317     if (inode_alloc)
0318         inode_unlock(inode_alloc);
0319 
0320     brelse(bh);
0321 
0322     return status;
0323 }
0324 
0325 static int ocfs2_info_handle_freeinode(struct inode *inode,
0326                        struct ocfs2_info_request __user *req)
0327 {
0328     u32 i;
0329     u64 blkno = -1;
0330     char namebuf[40];
0331     int status, type = INODE_ALLOC_SYSTEM_INODE;
0332     struct ocfs2_info_freeinode *oifi = NULL;
0333     struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
0334     struct inode *inode_alloc = NULL;
0335 
0336     oifi = kzalloc(sizeof(struct ocfs2_info_freeinode), GFP_KERNEL);
0337     if (!oifi) {
0338         status = -ENOMEM;
0339         mlog_errno(status);
0340         goto out_err;
0341     }
0342 
0343     if (o2info_from_user(*oifi, req)) {
0344         status = -EFAULT;
0345         goto out_free;
0346     }
0347 
0348     oifi->ifi_slotnum = osb->max_slots;
0349 
0350     for (i = 0; i < oifi->ifi_slotnum; i++) {
0351         if (o2info_coherent(&oifi->ifi_req)) {
0352             inode_alloc = ocfs2_get_system_file_inode(osb, type, i);
0353             if (!inode_alloc) {
0354                 mlog(ML_ERROR, "unable to get alloc inode in "
0355                     "slot %u\n", i);
0356                 status = -EIO;
0357                 goto bail;
0358             }
0359         } else {
0360             ocfs2_sprintf_system_inode_name(namebuf,
0361                             sizeof(namebuf),
0362                             type, i);
0363             status = ocfs2_lookup_ino_from_name(osb->sys_root_inode,
0364                                 namebuf,
0365                                 strlen(namebuf),
0366                                 &blkno);
0367             if (status < 0) {
0368                 status = -ENOENT;
0369                 goto bail;
0370             }
0371         }
0372 
0373         status = ocfs2_info_scan_inode_alloc(osb, inode_alloc, blkno, oifi, i);
0374 
0375         iput(inode_alloc);
0376         inode_alloc = NULL;
0377 
0378         if (status < 0)
0379             goto bail;
0380     }
0381 
0382     o2info_set_request_filled(&oifi->ifi_req);
0383 
0384     if (o2info_to_user(*oifi, req)) {
0385         status = -EFAULT;
0386         goto out_free;
0387     }
0388 
0389     status = 0;
0390 bail:
0391     if (status)
0392         o2info_set_request_error(&oifi->ifi_req, req);
0393 out_free:
0394     kfree(oifi);
0395 out_err:
0396     return status;
0397 }
0398 
0399 static void o2ffg_update_histogram(struct ocfs2_info_free_chunk_list *hist,
0400                    unsigned int chunksize)
0401 {
0402     u32 index;
0403 
0404     index = __ilog2_u32(chunksize);
0405     if (index >= OCFS2_INFO_MAX_HIST)
0406         index = OCFS2_INFO_MAX_HIST - 1;
0407 
0408     hist->fc_chunks[index]++;
0409     hist->fc_clusters[index] += chunksize;
0410 }
0411 
0412 static void o2ffg_update_stats(struct ocfs2_info_freefrag_stats *stats,
0413                    unsigned int chunksize)
0414 {
0415     if (chunksize > stats->ffs_max)
0416         stats->ffs_max = chunksize;
0417 
0418     if (chunksize < stats->ffs_min)
0419         stats->ffs_min = chunksize;
0420 
0421     stats->ffs_avg += chunksize;
0422     stats->ffs_free_chunks_real++;
0423 }
0424 
0425 static void ocfs2_info_update_ffg(struct ocfs2_info_freefrag *ffg,
0426                   unsigned int chunksize)
0427 {
0428     o2ffg_update_histogram(&(ffg->iff_ffs.ffs_fc_hist), chunksize);
0429     o2ffg_update_stats(&(ffg->iff_ffs), chunksize);
0430 }
0431 
0432 static int ocfs2_info_freefrag_scan_chain(struct ocfs2_super *osb,
0433                       struct inode *gb_inode,
0434                       struct ocfs2_dinode *gb_dinode,
0435                       struct ocfs2_chain_rec *rec,
0436                       struct ocfs2_info_freefrag *ffg,
0437                       u32 chunks_in_group)
0438 {
0439     int status = 0, used;
0440     u64 blkno;
0441 
0442     struct buffer_head *bh = NULL;
0443     struct ocfs2_group_desc *bg = NULL;
0444 
0445     unsigned int max_bits, num_clusters;
0446     unsigned int offset = 0, cluster, chunk;
0447     unsigned int chunk_free, last_chunksize = 0;
0448 
0449     if (!le32_to_cpu(rec->c_free))
0450         goto bail;
0451 
0452     do {
0453         if (!bg)
0454             blkno = le64_to_cpu(rec->c_blkno);
0455         else
0456             blkno = le64_to_cpu(bg->bg_next_group);
0457 
0458         if (bh) {
0459             brelse(bh);
0460             bh = NULL;
0461         }
0462 
0463         if (o2info_coherent(&ffg->iff_req))
0464             status = ocfs2_read_group_descriptor(gb_inode,
0465                                  gb_dinode,
0466                                  blkno, &bh);
0467         else
0468             status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
0469 
0470         if (status < 0) {
0471             mlog(ML_ERROR, "Can't read the group descriptor # "
0472                  "%llu from device.", (unsigned long long)blkno);
0473             status = -EIO;
0474             goto bail;
0475         }
0476 
0477         bg = (struct ocfs2_group_desc *)bh->b_data;
0478 
0479         if (!le16_to_cpu(bg->bg_free_bits_count))
0480             continue;
0481 
0482         max_bits = le16_to_cpu(bg->bg_bits);
0483         offset = 0;
0484 
0485         for (chunk = 0; chunk < chunks_in_group; chunk++) {
0486             /*
0487              * last chunk may be not an entire one.
0488              */
0489             if ((offset + ffg->iff_chunksize) > max_bits)
0490                 num_clusters = max_bits - offset;
0491             else
0492                 num_clusters = ffg->iff_chunksize;
0493 
0494             chunk_free = 0;
0495             for (cluster = 0; cluster < num_clusters; cluster++) {
0496                 used = ocfs2_test_bit(offset,
0497                         (unsigned long *)bg->bg_bitmap);
0498                 /*
0499                  * - chunk_free counts free clusters in #N chunk.
0500                  * - last_chunksize records the size(in) clusters
0501                  *   for the last real free chunk being counted.
0502                  */
0503                 if (!used) {
0504                     last_chunksize++;
0505                     chunk_free++;
0506                 }
0507 
0508                 if (used && last_chunksize) {
0509                     ocfs2_info_update_ffg(ffg,
0510                                   last_chunksize);
0511                     last_chunksize = 0;
0512                 }
0513 
0514                 offset++;
0515             }
0516 
0517             if (chunk_free == ffg->iff_chunksize)
0518                 ffg->iff_ffs.ffs_free_chunks++;
0519         }
0520 
0521         /*
0522          * need to update the info for last free chunk.
0523          */
0524         if (last_chunksize)
0525             ocfs2_info_update_ffg(ffg, last_chunksize);
0526 
0527     } while (le64_to_cpu(bg->bg_next_group));
0528 
0529 bail:
0530     brelse(bh);
0531 
0532     return status;
0533 }
0534 
0535 static int ocfs2_info_freefrag_scan_bitmap(struct ocfs2_super *osb,
0536                        struct inode *gb_inode, u64 blkno,
0537                        struct ocfs2_info_freefrag *ffg)
0538 {
0539     u32 chunks_in_group;
0540     int status = 0, unlock = 0, i;
0541 
0542     struct buffer_head *bh = NULL;
0543     struct ocfs2_chain_list *cl = NULL;
0544     struct ocfs2_chain_rec *rec = NULL;
0545     struct ocfs2_dinode *gb_dinode = NULL;
0546 
0547     if (gb_inode)
0548         inode_lock(gb_inode);
0549 
0550     if (o2info_coherent(&ffg->iff_req)) {
0551         status = ocfs2_inode_lock(gb_inode, &bh, 0);
0552         if (status < 0) {
0553             mlog_errno(status);
0554             goto bail;
0555         }
0556         unlock = 1;
0557     } else {
0558         status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
0559         if (status < 0) {
0560             mlog_errno(status);
0561             goto bail;
0562         }
0563     }
0564 
0565     gb_dinode = (struct ocfs2_dinode *)bh->b_data;
0566     cl = &(gb_dinode->id2.i_chain);
0567 
0568     /*
0569      * Chunksize(in) clusters from userspace should be
0570      * less than clusters in a group.
0571      */
0572     if (ffg->iff_chunksize > le16_to_cpu(cl->cl_cpg)) {
0573         status = -EINVAL;
0574         goto bail;
0575     }
0576 
0577     memset(&ffg->iff_ffs, 0, sizeof(struct ocfs2_info_freefrag_stats));
0578 
0579     ffg->iff_ffs.ffs_min = ~0U;
0580     ffg->iff_ffs.ffs_clusters =
0581             le32_to_cpu(gb_dinode->id1.bitmap1.i_total);
0582     ffg->iff_ffs.ffs_free_clusters = ffg->iff_ffs.ffs_clusters -
0583             le32_to_cpu(gb_dinode->id1.bitmap1.i_used);
0584 
0585     chunks_in_group = le16_to_cpu(cl->cl_cpg) / ffg->iff_chunksize + 1;
0586 
0587     for (i = 0; i < le16_to_cpu(cl->cl_next_free_rec); i++) {
0588         rec = &(cl->cl_recs[i]);
0589         status = ocfs2_info_freefrag_scan_chain(osb, gb_inode,
0590                             gb_dinode,
0591                             rec, ffg,
0592                             chunks_in_group);
0593         if (status)
0594             goto bail;
0595     }
0596 
0597     if (ffg->iff_ffs.ffs_free_chunks_real)
0598         ffg->iff_ffs.ffs_avg = (ffg->iff_ffs.ffs_avg /
0599                     ffg->iff_ffs.ffs_free_chunks_real);
0600 bail:
0601     if (unlock)
0602         ocfs2_inode_unlock(gb_inode, 0);
0603 
0604     if (gb_inode)
0605         inode_unlock(gb_inode);
0606 
0607     iput(gb_inode);
0608     brelse(bh);
0609 
0610     return status;
0611 }
0612 
0613 static int ocfs2_info_handle_freefrag(struct inode *inode,
0614                       struct ocfs2_info_request __user *req)
0615 {
0616     u64 blkno = -1;
0617     char namebuf[40];
0618     int status, type = GLOBAL_BITMAP_SYSTEM_INODE;
0619 
0620     struct ocfs2_info_freefrag *oiff;
0621     struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
0622     struct inode *gb_inode = NULL;
0623 
0624     oiff = kzalloc(sizeof(struct ocfs2_info_freefrag), GFP_KERNEL);
0625     if (!oiff) {
0626         status = -ENOMEM;
0627         mlog_errno(status);
0628         goto out_err;
0629     }
0630 
0631     if (o2info_from_user(*oiff, req)) {
0632         status = -EFAULT;
0633         goto out_free;
0634     }
0635     /*
0636      * chunksize from userspace should be power of 2.
0637      */
0638     if ((oiff->iff_chunksize & (oiff->iff_chunksize - 1)) ||
0639         (!oiff->iff_chunksize)) {
0640         status = -EINVAL;
0641         goto bail;
0642     }
0643 
0644     if (o2info_coherent(&oiff->iff_req)) {
0645         gb_inode = ocfs2_get_system_file_inode(osb, type,
0646                                OCFS2_INVALID_SLOT);
0647         if (!gb_inode) {
0648             mlog(ML_ERROR, "unable to get global_bitmap inode\n");
0649             status = -EIO;
0650             goto bail;
0651         }
0652     } else {
0653         ocfs2_sprintf_system_inode_name(namebuf, sizeof(namebuf), type,
0654                         OCFS2_INVALID_SLOT);
0655         status = ocfs2_lookup_ino_from_name(osb->sys_root_inode,
0656                             namebuf,
0657                             strlen(namebuf),
0658                             &blkno);
0659         if (status < 0) {
0660             status = -ENOENT;
0661             goto bail;
0662         }
0663     }
0664 
0665     status = ocfs2_info_freefrag_scan_bitmap(osb, gb_inode, blkno, oiff);
0666     if (status < 0)
0667         goto bail;
0668 
0669     o2info_set_request_filled(&oiff->iff_req);
0670 
0671     if (o2info_to_user(*oiff, req)) {
0672         status = -EFAULT;
0673         goto out_free;
0674     }
0675 
0676     status = 0;
0677 bail:
0678     if (status)
0679         o2info_set_request_error(&oiff->iff_req, req);
0680 out_free:
0681     kfree(oiff);
0682 out_err:
0683     return status;
0684 }
0685 
0686 static int ocfs2_info_handle_unknown(struct inode *inode,
0687                      struct ocfs2_info_request __user *req)
0688 {
0689     struct ocfs2_info_request oir;
0690 
0691     if (o2info_from_user(oir, req))
0692         return -EFAULT;
0693 
0694     o2info_clear_request_filled(&oir);
0695 
0696     if (o2info_to_user(oir, req))
0697         return -EFAULT;
0698 
0699     return 0;
0700 }
0701 
0702 /*
0703  * Validate and distinguish OCFS2_IOC_INFO requests.
0704  *
0705  * - validate the magic number.
0706  * - distinguish different requests.
0707  * - validate size of different requests.
0708  */
0709 static int ocfs2_info_handle_request(struct inode *inode,
0710                      struct ocfs2_info_request __user *req)
0711 {
0712     int status = -EFAULT;
0713     struct ocfs2_info_request oir;
0714 
0715     if (o2info_from_user(oir, req))
0716         goto bail;
0717 
0718     status = -EINVAL;
0719     if (oir.ir_magic != OCFS2_INFO_MAGIC)
0720         goto bail;
0721 
0722     switch (oir.ir_code) {
0723     case OCFS2_INFO_BLOCKSIZE:
0724         if (oir.ir_size == sizeof(struct ocfs2_info_blocksize))
0725             status = ocfs2_info_handle_blocksize(inode, req);
0726         break;
0727     case OCFS2_INFO_CLUSTERSIZE:
0728         if (oir.ir_size == sizeof(struct ocfs2_info_clustersize))
0729             status = ocfs2_info_handle_clustersize(inode, req);
0730         break;
0731     case OCFS2_INFO_MAXSLOTS:
0732         if (oir.ir_size == sizeof(struct ocfs2_info_maxslots))
0733             status = ocfs2_info_handle_maxslots(inode, req);
0734         break;
0735     case OCFS2_INFO_LABEL:
0736         if (oir.ir_size == sizeof(struct ocfs2_info_label))
0737             status = ocfs2_info_handle_label(inode, req);
0738         break;
0739     case OCFS2_INFO_UUID:
0740         if (oir.ir_size == sizeof(struct ocfs2_info_uuid))
0741             status = ocfs2_info_handle_uuid(inode, req);
0742         break;
0743     case OCFS2_INFO_FS_FEATURES:
0744         if (oir.ir_size == sizeof(struct ocfs2_info_fs_features))
0745             status = ocfs2_info_handle_fs_features(inode, req);
0746         break;
0747     case OCFS2_INFO_JOURNAL_SIZE:
0748         if (oir.ir_size == sizeof(struct ocfs2_info_journal_size))
0749             status = ocfs2_info_handle_journal_size(inode, req);
0750         break;
0751     case OCFS2_INFO_FREEINODE:
0752         if (oir.ir_size == sizeof(struct ocfs2_info_freeinode))
0753             status = ocfs2_info_handle_freeinode(inode, req);
0754         break;
0755     case OCFS2_INFO_FREEFRAG:
0756         if (oir.ir_size == sizeof(struct ocfs2_info_freefrag))
0757             status = ocfs2_info_handle_freefrag(inode, req);
0758         break;
0759     default:
0760         status = ocfs2_info_handle_unknown(inode, req);
0761         break;
0762     }
0763 
0764 bail:
0765     return status;
0766 }
0767 
0768 static int ocfs2_get_request_ptr(struct ocfs2_info *info, int idx,
0769                  u64 *req_addr, int compat_flag)
0770 {
0771     int status = -EFAULT;
0772     u64 __user *bp = NULL;
0773 
0774     if (compat_flag) {
0775 #ifdef CONFIG_COMPAT
0776         /*
0777          * pointer bp stores the base address of a pointers array,
0778          * which collects all addresses of separate request.
0779          */
0780         bp = (u64 __user *)(unsigned long)compat_ptr(info->oi_requests);
0781 #else
0782         BUG();
0783 #endif
0784     } else
0785         bp = (u64 __user *)(unsigned long)(info->oi_requests);
0786 
0787     if (o2info_from_user(*req_addr, bp + idx))
0788         goto bail;
0789 
0790     status = 0;
0791 bail:
0792     return status;
0793 }
0794 
0795 /*
0796  * OCFS2_IOC_INFO handles an array of requests passed from userspace.
0797  *
0798  * ocfs2_info_handle() recevies a large info aggregation, grab and
0799  * validate the request count from header, then break it into small
0800  * pieces, later specific handlers can handle them one by one.
0801  *
0802  * Idea here is to make each separate request small enough to ensure
0803  * a better backward&forward compatibility, since a small piece of
0804  * request will be less likely to be broken if disk layout get changed.
0805  */
0806 static int ocfs2_info_handle(struct inode *inode, struct ocfs2_info *info,
0807                  int compat_flag)
0808 {
0809     int i, status = 0;
0810     u64 req_addr;
0811     struct ocfs2_info_request __user *reqp;
0812 
0813     if ((info->oi_count > OCFS2_INFO_MAX_REQUEST) ||
0814         (!info->oi_requests)) {
0815         status = -EINVAL;
0816         goto bail;
0817     }
0818 
0819     for (i = 0; i < info->oi_count; i++) {
0820 
0821         status = ocfs2_get_request_ptr(info, i, &req_addr, compat_flag);
0822         if (status)
0823             break;
0824 
0825         reqp = (struct ocfs2_info_request __user *)(unsigned long)req_addr;
0826         if (!reqp) {
0827             status = -EINVAL;
0828             goto bail;
0829         }
0830 
0831         status = ocfs2_info_handle_request(inode, reqp);
0832         if (status)
0833             break;
0834     }
0835 
0836 bail:
0837     return status;
0838 }
0839 
0840 long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
0841 {
0842     struct inode *inode = file_inode(filp);
0843     int new_clusters;
0844     int status;
0845     struct ocfs2_space_resv sr;
0846     struct ocfs2_new_group_input input;
0847     struct reflink_arguments args;
0848     const char __user *old_path;
0849     const char __user *new_path;
0850     bool preserve;
0851     struct ocfs2_info info;
0852     void __user *argp = (void __user *)arg;
0853 
0854     switch (cmd) {
0855     case OCFS2_IOC_RESVSP:
0856     case OCFS2_IOC_RESVSP64:
0857     case OCFS2_IOC_UNRESVSP:
0858     case OCFS2_IOC_UNRESVSP64:
0859         if (copy_from_user(&sr, (int __user *) arg, sizeof(sr)))
0860             return -EFAULT;
0861 
0862         return ocfs2_change_file_space(filp, cmd, &sr);
0863     case OCFS2_IOC_GROUP_EXTEND:
0864         if (!capable(CAP_SYS_RESOURCE))
0865             return -EPERM;
0866 
0867         if (get_user(new_clusters, (int __user *)arg))
0868             return -EFAULT;
0869 
0870         status = mnt_want_write_file(filp);
0871         if (status)
0872             return status;
0873         status = ocfs2_group_extend(inode, new_clusters);
0874         mnt_drop_write_file(filp);
0875         return status;
0876     case OCFS2_IOC_GROUP_ADD:
0877     case OCFS2_IOC_GROUP_ADD64:
0878         if (!capable(CAP_SYS_RESOURCE))
0879             return -EPERM;
0880 
0881         if (copy_from_user(&input, (int __user *) arg, sizeof(input)))
0882             return -EFAULT;
0883 
0884         status = mnt_want_write_file(filp);
0885         if (status)
0886             return status;
0887         status = ocfs2_group_add(inode, &input);
0888         mnt_drop_write_file(filp);
0889         return status;
0890     case OCFS2_IOC_REFLINK:
0891         if (copy_from_user(&args, argp, sizeof(args)))
0892             return -EFAULT;
0893         old_path = (const char __user *)(unsigned long)args.old_path;
0894         new_path = (const char __user *)(unsigned long)args.new_path;
0895         preserve = (args.preserve != 0);
0896 
0897         return ocfs2_reflink_ioctl(inode, old_path, new_path, preserve);
0898     case OCFS2_IOC_INFO:
0899         if (copy_from_user(&info, argp, sizeof(struct ocfs2_info)))
0900             return -EFAULT;
0901 
0902         return ocfs2_info_handle(inode, &info, 0);
0903     case FITRIM:
0904     {
0905         struct super_block *sb = inode->i_sb;
0906         struct fstrim_range range;
0907         int ret = 0;
0908 
0909         if (!capable(CAP_SYS_ADMIN))
0910             return -EPERM;
0911 
0912         if (!bdev_max_discard_sectors(sb->s_bdev))
0913             return -EOPNOTSUPP;
0914 
0915         if (copy_from_user(&range, argp, sizeof(range)))
0916             return -EFAULT;
0917 
0918         range.minlen = max_t(u64, bdev_discard_granularity(sb->s_bdev),
0919                      range.minlen);
0920         ret = ocfs2_trim_fs(sb, &range);
0921         if (ret < 0)
0922             return ret;
0923 
0924         if (copy_to_user(argp, &range, sizeof(range)))
0925             return -EFAULT;
0926 
0927         return 0;
0928     }
0929     case OCFS2_IOC_MOVE_EXT:
0930         return ocfs2_ioctl_move_extents(filp, argp);
0931     default:
0932         return -ENOTTY;
0933     }
0934 }
0935 
0936 #ifdef CONFIG_COMPAT
0937 long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
0938 {
0939     bool preserve;
0940     struct reflink_arguments args;
0941     struct inode *inode = file_inode(file);
0942     struct ocfs2_info info;
0943     void __user *argp = (void __user *)arg;
0944 
0945     switch (cmd) {
0946     case OCFS2_IOC_RESVSP:
0947     case OCFS2_IOC_RESVSP64:
0948     case OCFS2_IOC_UNRESVSP:
0949     case OCFS2_IOC_UNRESVSP64:
0950     case OCFS2_IOC_GROUP_EXTEND:
0951     case OCFS2_IOC_GROUP_ADD:
0952     case OCFS2_IOC_GROUP_ADD64:
0953         break;
0954     case OCFS2_IOC_REFLINK:
0955         if (copy_from_user(&args, argp, sizeof(args)))
0956             return -EFAULT;
0957         preserve = (args.preserve != 0);
0958 
0959         return ocfs2_reflink_ioctl(inode, compat_ptr(args.old_path),
0960                        compat_ptr(args.new_path), preserve);
0961     case OCFS2_IOC_INFO:
0962         if (copy_from_user(&info, argp, sizeof(struct ocfs2_info)))
0963             return -EFAULT;
0964 
0965         return ocfs2_info_handle(inode, &info, 1);
0966     case FITRIM:
0967     case OCFS2_IOC_MOVE_EXT:
0968         break;
0969     default:
0970         return -ENOIOCTLCMD;
0971     }
0972 
0973     return ocfs2_ioctl(file, cmd, arg);
0974 }
0975 #endif