brintos

brintos / linux-shallow public Read only

0
0
Text · 3.7 KiB · 44e0448 Raw
160 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * linux/fs/ext2/ioctl.c4 *5 * Copyright (C) 1993, 1994, 19956 * Remy Card (card@masi.ibp.fr)7 * Laboratoire MASI - Institut Blaise Pascal8 * Universite Pierre et Marie Curie (Paris VI)9 */10 11#include "ext2.h"12#include <linux/capability.h>13#include <linux/time.h>14#include <linux/sched.h>15#include <linux/compat.h>16#include <linux/mount.h>17#include <asm/current.h>18#include <linux/uaccess.h>19#include <linux/fileattr.h>20 21int ext2_fileattr_get(struct dentry *dentry, struct fileattr *fa)22{23	struct ext2_inode_info *ei = EXT2_I(d_inode(dentry));24 25	fileattr_fill_flags(fa, ei->i_flags & EXT2_FL_USER_VISIBLE);26 27	return 0;28}29 30int ext2_fileattr_set(struct mnt_idmap *idmap,31		      struct dentry *dentry, struct fileattr *fa)32{33	struct inode *inode = d_inode(dentry);34	struct ext2_inode_info *ei = EXT2_I(inode);35 36	if (fileattr_has_fsx(fa))37		return -EOPNOTSUPP;38 39	/* Is it quota file? Do not allow user to mess with it */40	if (IS_NOQUOTA(inode))41		return -EPERM;42 43	ei->i_flags = (ei->i_flags & ~EXT2_FL_USER_MODIFIABLE) |44		(fa->flags & EXT2_FL_USER_MODIFIABLE);45 46	ext2_set_inode_flags(inode);47	inode_set_ctime_current(inode);48	mark_inode_dirty(inode);49 50	return 0;51}52 53 54long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)55{56	struct inode *inode = file_inode(filp);57	struct ext2_inode_info *ei = EXT2_I(inode);58	unsigned short rsv_window_size;59	int ret;60 61	ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg);62 63	switch (cmd) {64	case EXT2_IOC_GETVERSION:65		return put_user(inode->i_generation, (int __user *) arg);66	case EXT2_IOC_SETVERSION: {67		__u32 generation;68 69		if (!inode_owner_or_capable(&nop_mnt_idmap, inode))70			return -EPERM;71		ret = mnt_want_write_file(filp);72		if (ret)73			return ret;74		if (get_user(generation, (int __user *) arg)) {75			ret = -EFAULT;76			goto setversion_out;77		}78 79		inode_lock(inode);80		inode_set_ctime_current(inode);81		inode->i_generation = generation;82		inode_unlock(inode);83 84		mark_inode_dirty(inode);85setversion_out:86		mnt_drop_write_file(filp);87		return ret;88	}89	case EXT2_IOC_GETRSVSZ:90		if (test_opt(inode->i_sb, RESERVATION)91			&& S_ISREG(inode->i_mode)92			&& ei->i_block_alloc_info) {93			rsv_window_size = ei->i_block_alloc_info->rsv_window_node.rsv_goal_size;94			return put_user(rsv_window_size, (int __user *)arg);95		}96		return -ENOTTY;97	case EXT2_IOC_SETRSVSZ: {98 99		if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))100			return -ENOTTY;101 102		if (!inode_owner_or_capable(&nop_mnt_idmap, inode))103			return -EACCES;104 105		if (get_user(rsv_window_size, (int __user *)arg))106			return -EFAULT;107 108		ret = mnt_want_write_file(filp);109		if (ret)110			return ret;111 112		if (rsv_window_size > EXT2_MAX_RESERVE_BLOCKS)113			rsv_window_size = EXT2_MAX_RESERVE_BLOCKS;114 115		/*116		 * need to allocate reservation structure for this inode117		 * before set the window size118		 */119		/*120		 * XXX What lock should protect the rsv_goal_size?121		 * Accessed in ext2_get_block only.  ext3 uses i_truncate.122		 */123		mutex_lock(&ei->truncate_mutex);124		if (!ei->i_block_alloc_info)125			ext2_init_block_alloc_info(inode);126 127		if (ei->i_block_alloc_info){128			struct ext2_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node;129			rsv->rsv_goal_size = rsv_window_size;130		} else {131			ret = -ENOMEM;132		}133 134		mutex_unlock(&ei->truncate_mutex);135		mnt_drop_write_file(filp);136		return ret;137	}138	default:139		return -ENOTTY;140	}141}142 143#ifdef CONFIG_COMPAT144long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)145{146	/* These are just misnamed, they actually get/put from/to user an int */147	switch (cmd) {148	case EXT2_IOC32_GETVERSION:149		cmd = EXT2_IOC_GETVERSION;150		break;151	case EXT2_IOC32_SETVERSION:152		cmd = EXT2_IOC_SETVERSION;153		break;154	default:155		return -ENOIOCTLCMD;156	}157	return ext2_ioctl(file, cmd, (unsigned long) compat_ptr(arg));158}159#endif160