cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ioctl.c (22603B)


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