⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioctl.c

📁 linux 内核源代码
💻 C
字号:
/* * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README */#include <linux/capability.h>#include <linux/fs.h>#include <linux/reiserfs_fs.h>#include <linux/time.h>#include <asm/uaccess.h>#include <linux/pagemap.h>#include <linux/smp_lock.h>#include <linux/compat.h>static int reiserfs_unpack(struct inode *inode, struct file *filp);/*** reiserfs_ioctl - handler for ioctl for inode** supported commands:**  1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect**                           and prevent packing file (argument arg has to be non-zero)**  2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION**  3) That's all for a while ...*/int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,		   unsigned long arg){	unsigned int flags;	switch (cmd) {	case REISERFS_IOC_UNPACK:		if (S_ISREG(inode->i_mode)) {			if (arg)				return reiserfs_unpack(inode, filp);			else				return 0;		} else			return -ENOTTY;		/* following two cases are taken from fs/ext2/ioctl.c by Remy		   Card (card@masi.ibp.fr) */	case REISERFS_IOC_GETFLAGS:		if (!reiserfs_attrs(inode->i_sb))			return -ENOTTY;		flags = REISERFS_I(inode)->i_attrs;		i_attrs_to_sd_attrs(inode, (__u16 *) & flags);		return put_user(flags, (int __user *)arg);	case REISERFS_IOC_SETFLAGS:{			if (!reiserfs_attrs(inode->i_sb))				return -ENOTTY;			if (IS_RDONLY(inode))				return -EROFS;			if (!is_owner_or_cap(inode))				return -EPERM;			if (get_user(flags, (int __user *)arg))				return -EFAULT;			/* Is it quota file? Do not allow user to mess with it. */			if (IS_NOQUOTA(inode))				return -EPERM;			if (((flags ^ REISERFS_I(inode)->			      i_attrs) & (REISERFS_IMMUTABLE_FL |					  REISERFS_APPEND_FL))			    && !capable(CAP_LINUX_IMMUTABLE))				return -EPERM;			if ((flags & REISERFS_NOTAIL_FL) &&			    S_ISREG(inode->i_mode)) {				int result;				result = reiserfs_unpack(inode, filp);				if (result)					return result;			}			sd_attrs_to_i_attrs(flags, inode);			REISERFS_I(inode)->i_attrs = flags;			inode->i_ctime = CURRENT_TIME_SEC;			mark_inode_dirty(inode);			return 0;		}	case REISERFS_IOC_GETVERSION:		return put_user(inode->i_generation, (int __user *)arg);	case REISERFS_IOC_SETVERSION:		if (!is_owner_or_cap(inode))			return -EPERM;		if (IS_RDONLY(inode))			return -EROFS;		if (get_user(inode->i_generation, (int __user *)arg))			return -EFAULT;		inode->i_ctime = CURRENT_TIME_SEC;		mark_inode_dirty(inode);		return 0;	default:		return -ENOTTY;	}}#ifdef CONFIG_COMPATlong reiserfs_compat_ioctl(struct file *file, unsigned int cmd,				unsigned long arg){	struct inode *inode = file->f_path.dentry->d_inode;	int ret;	/* These are just misnamed, they actually get/put from/to user an int */	switch (cmd) {	case REISERFS_IOC32_UNPACK:		cmd = REISERFS_IOC_UNPACK;		break;	case REISERFS_IOC32_GETFLAGS:		cmd = REISERFS_IOC_GETFLAGS;		break;	case REISERFS_IOC32_SETFLAGS:		cmd = REISERFS_IOC_SETFLAGS;		break;	case REISERFS_IOC32_GETVERSION:		cmd = REISERFS_IOC_GETVERSION;		break;	case REISERFS_IOC32_SETVERSION:		cmd = REISERFS_IOC_SETVERSION;		break;	default:		return -ENOIOCTLCMD;	}	lock_kernel();	ret = reiserfs_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg));	unlock_kernel();	return ret;}#endifint reiserfs_commit_write(struct file *f, struct page *page,			  unsigned from, unsigned to);int reiserfs_prepare_write(struct file *f, struct page *page,			   unsigned from, unsigned to);/*** reiserfs_unpack** Function try to convert tail from direct item into indirect.** It set up nopack attribute in the REISERFS_I(inode)->nopack*/static int reiserfs_unpack(struct inode *inode, struct file *filp){	int retval = 0;	int index;	struct page *page;	struct address_space *mapping;	unsigned long write_from;	unsigned long blocksize = inode->i_sb->s_blocksize;	if (inode->i_size == 0) {		REISERFS_I(inode)->i_flags |= i_nopack_mask;		return 0;	}	/* ioctl already done */	if (REISERFS_I(inode)->i_flags & i_nopack_mask) {		return 0;	}	/* we need to make sure nobody is changing the file size beneath	 ** us	 */	mutex_lock(&inode->i_mutex);	reiserfs_write_lock(inode->i_sb);	write_from = inode->i_size & (blocksize - 1);	/* if we are on a block boundary, we are already unpacked.  */	if (write_from == 0) {		REISERFS_I(inode)->i_flags |= i_nopack_mask;		goto out;	}	/* we unpack by finding the page with the tail, and calling	 ** reiserfs_prepare_write on that page.  This will force a 	 ** reiserfs_get_block to unpack the tail for us.	 */	index = inode->i_size >> PAGE_CACHE_SHIFT;	mapping = inode->i_mapping;	page = grab_cache_page(mapping, index);	retval = -ENOMEM;	if (!page) {		goto out;	}	retval = reiserfs_prepare_write(NULL, page, write_from, write_from);	if (retval)		goto out_unlock;	/* conversion can change page contents, must flush */	flush_dcache_page(page);	retval = reiserfs_commit_write(NULL, page, write_from, write_from);	REISERFS_I(inode)->i_flags |= i_nopack_mask;      out_unlock:	unlock_page(page);	page_cache_release(page);      out:	mutex_unlock(&inode->i_mutex);	reiserfs_write_unlock(inode->i_sb);	return retval;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -