2005-04-17 02:20:36 +04:00
/*
* Quota code necessary even when VFS quota support is not compiled
* into the kernel . The interesting stuff is over in dquot . c , here
* we have symbols for initial quotactl ( 2 ) handling , the sysctl ( 2 )
* variables , etc - things needed even when quota support disabled .
*/
# include <linux/fs.h>
# include <linux/namei.h>
# include <linux/slab.h>
# include <asm/current.h>
2012-05-28 19:40:17 +04:00
# include <linux/uaccess.h>
2005-04-17 02:20:36 +04:00
# include <linux/kernel.h>
# include <linux/security.h>
# include <linux/syscalls.h>
2006-01-11 23:17:46 +03:00
# include <linux/capability.h>
2005-11-07 11:59:35 +03:00
# include <linux/quotaops.h>
2007-07-16 10:41:12 +04:00
# include <linux/types.h>
2010-02-16 11:44:51 +03:00
# include <linux/writeback.h>
2005-04-17 02:20:36 +04:00
2010-02-16 11:44:50 +03:00
static int check_quotactl_permission ( struct super_block * sb , int type , int cmd ,
qid_t id )
2005-04-17 02:20:36 +04:00
{
2010-02-16 11:44:50 +03:00
switch ( cmd ) {
/* these commands do not require any special privilegues */
case Q_GETFMT :
case Q_SYNC :
case Q_GETINFO :
case Q_XGETQSTAT :
2013-08-07 02:27:07 +04:00
case Q_XGETQSTATV :
2010-02-16 11:44:50 +03:00
case Q_XQUOTASYNC :
break ;
/* allow to query information for dquots we "own" */
case Q_GETQUOTA :
case Q_XGETQUOTA :
2012-09-16 13:07:49 +04:00
if ( ( type = = USRQUOTA & & uid_eq ( current_euid ( ) , make_kuid ( current_user_ns ( ) , id ) ) ) | |
( type = = GRPQUOTA & & in_egroup_p ( make_kgid ( current_user_ns ( ) , id ) ) ) )
2010-02-16 11:44:50 +03:00
break ;
/*FALLTHROUGH*/
default :
2005-04-17 02:20:36 +04:00
if ( ! capable ( CAP_SYS_ADMIN ) )
return - EPERM ;
}
2010-02-16 11:44:50 +03:00
return security_quotactl ( cmd , type , id , sb ) ;
2005-04-17 02:20:36 +04:00
}
2010-03-23 13:06:58 +03:00
static void quota_sync_one ( struct super_block * sb , void * arg )
{
if ( sb - > s_qcop & & sb - > s_qcop - > quota_sync )
2012-07-03 18:45:28 +04:00
sb - > s_qcop - > quota_sync ( sb , * ( int * ) arg ) ;
2010-03-23 13:06:58 +03:00
}
2010-02-16 11:44:49 +03:00
static int quota_sync_all ( int type )
2005-04-17 02:20:36 +04:00
{
2010-02-16 11:44:49 +03:00
int ret ;
if ( type > = MAXQUOTAS )
return - EINVAL ;
ret = security_quotactl ( Q_SYNC , type , 0 , NULL ) ;
2010-03-23 13:06:58 +03:00
if ( ! ret )
iterate_supers ( quota_sync_one , & type ) ;
return ret ;
2005-04-17 02:20:36 +04:00
}
2010-02-16 11:44:47 +03:00
static int quota_quotaon ( struct super_block * sb , int type , int cmd , qid_t id ,
2010-09-15 19:38:58 +04:00
struct path * path )
2005-04-17 02:20:36 +04:00
{
2010-09-15 19:38:58 +04:00
if ( ! sb - > s_qcop - > quota_on & & ! sb - > s_qcop - > quota_on_meta )
return - ENOSYS ;
if ( sb - > s_qcop - > quota_on_meta )
return sb - > s_qcop - > quota_on_meta ( sb , type , id ) ;
if ( IS_ERR ( path ) )
return PTR_ERR ( path ) ;
return sb - > s_qcop - > quota_on ( sb , type , id , path ) ;
2010-02-16 11:44:47 +03:00
}
2005-04-17 02:20:36 +04:00
2010-02-16 11:44:47 +03:00
static int quota_getfmt ( struct super_block * sb , int type , void __user * addr )
{
__u32 fmt ;
2005-04-17 02:20:36 +04:00
2010-02-16 11:44:47 +03:00
down_read ( & sb_dqopt ( sb ) - > dqptr_sem ) ;
if ( ! sb_has_quota_active ( sb , type ) ) {
up_read ( & sb_dqopt ( sb ) - > dqptr_sem ) ;
return - ESRCH ;
}
fmt = sb_dqopt ( sb ) - > info [ type ] . dqi_format - > qf_fmt_id ;
up_read ( & sb_dqopt ( sb ) - > dqptr_sem ) ;
if ( copy_to_user ( addr , & fmt , sizeof ( fmt ) ) )
return - EFAULT ;
return 0 ;
}
2005-04-17 02:20:36 +04:00
2010-02-16 11:44:47 +03:00
static int quota_getinfo ( struct super_block * sb , int type , void __user * addr )
{
struct if_dqinfo info ;
int ret ;
2005-04-17 02:20:36 +04:00
2010-02-16 11:44:48 +03:00
if ( ! sb - > s_qcop - > get_info )
return - ENOSYS ;
2010-02-16 11:44:47 +03:00
ret = sb - > s_qcop - > get_info ( sb , type , & info ) ;
if ( ! ret & & copy_to_user ( addr , & info , sizeof ( info ) ) )
return - EFAULT ;
return ret ;
}
2005-04-17 02:20:36 +04:00
2010-02-16 11:44:47 +03:00
static int quota_setinfo ( struct super_block * sb , int type , void __user * addr )
{
struct if_dqinfo info ;
2005-04-17 02:20:36 +04:00
2010-02-16 11:44:47 +03:00
if ( copy_from_user ( & info , addr , sizeof ( info ) ) )
return - EFAULT ;
2010-02-16 11:44:48 +03:00
if ( ! sb - > s_qcop - > set_info )
return - ENOSYS ;
2010-02-16 11:44:47 +03:00
return sb - > s_qcop - > set_info ( sb , type , & info ) ;
}
2010-05-07 01:04:58 +04:00
static void copy_to_if_dqblk ( struct if_dqblk * dst , struct fs_disk_quota * src )
{
2013-11-01 14:21:54 +04:00
memset ( dst , 0 , sizeof ( * dst ) ) ;
2010-05-07 01:04:58 +04:00
dst - > dqb_bhardlimit = src - > d_blk_hardlimit ;
dst - > dqb_bsoftlimit = src - > d_blk_softlimit ;
dst - > dqb_curspace = src - > d_bcount ;
dst - > dqb_ihardlimit = src - > d_ino_hardlimit ;
dst - > dqb_isoftlimit = src - > d_ino_softlimit ;
dst - > dqb_curinodes = src - > d_icount ;
dst - > dqb_btime = src - > d_btimer ;
dst - > dqb_itime = src - > d_itimer ;
dst - > dqb_valid = QIF_ALL ;
}
2010-02-16 11:44:47 +03:00
static int quota_getquota ( struct super_block * sb , int type , qid_t id ,
void __user * addr )
{
2012-09-16 13:07:49 +04:00
struct kqid qid ;
2010-05-07 01:04:58 +04:00
struct fs_disk_quota fdq ;
2010-02-16 11:44:47 +03:00
struct if_dqblk idq ;
int ret ;
2010-02-16 11:44:48 +03:00
if ( ! sb - > s_qcop - > get_dqblk )
return - ENOSYS ;
2012-09-16 13:07:49 +04:00
qid = make_kqid ( current_user_ns ( ) , type , id ) ;
if ( ! qid_valid ( qid ) )
return - EINVAL ;
ret = sb - > s_qcop - > get_dqblk ( sb , qid , & fdq ) ;
2010-02-16 11:44:47 +03:00
if ( ret )
return ret ;
2010-05-07 01:04:58 +04:00
copy_to_if_dqblk ( & idq , & fdq ) ;
2010-02-16 11:44:47 +03:00
if ( copy_to_user ( addr , & idq , sizeof ( idq ) ) )
return - EFAULT ;
return 0 ;
}
2010-05-07 01:05:17 +04:00
static void copy_from_if_dqblk ( struct fs_disk_quota * dst , struct if_dqblk * src )
{
dst - > d_blk_hardlimit = src - > dqb_bhardlimit ;
dst - > d_blk_softlimit = src - > dqb_bsoftlimit ;
dst - > d_bcount = src - > dqb_curspace ;
dst - > d_ino_hardlimit = src - > dqb_ihardlimit ;
dst - > d_ino_softlimit = src - > dqb_isoftlimit ;
dst - > d_icount = src - > dqb_curinodes ;
dst - > d_btimer = src - > dqb_btime ;
dst - > d_itimer = src - > dqb_itime ;
dst - > d_fieldmask = 0 ;
if ( src - > dqb_valid & QIF_BLIMITS )
dst - > d_fieldmask | = FS_DQ_BSOFT | FS_DQ_BHARD ;
if ( src - > dqb_valid & QIF_SPACE )
dst - > d_fieldmask | = FS_DQ_BCOUNT ;
if ( src - > dqb_valid & QIF_ILIMITS )
dst - > d_fieldmask | = FS_DQ_ISOFT | FS_DQ_IHARD ;
if ( src - > dqb_valid & QIF_INODES )
dst - > d_fieldmask | = FS_DQ_ICOUNT ;
if ( src - > dqb_valid & QIF_BTIME )
dst - > d_fieldmask | = FS_DQ_BTIMER ;
if ( src - > dqb_valid & QIF_ITIME )
dst - > d_fieldmask | = FS_DQ_ITIMER ;
}
2010-02-16 11:44:47 +03:00
static int quota_setquota ( struct super_block * sb , int type , qid_t id ,
void __user * addr )
{
2010-05-07 01:05:17 +04:00
struct fs_disk_quota fdq ;
2010-02-16 11:44:47 +03:00
struct if_dqblk idq ;
2012-09-16 13:07:49 +04:00
struct kqid qid ;
2010-02-16 11:44:47 +03:00
if ( copy_from_user ( & idq , addr , sizeof ( idq ) ) )
return - EFAULT ;
2010-02-16 11:44:48 +03:00
if ( ! sb - > s_qcop - > set_dqblk )
return - ENOSYS ;
2012-09-16 13:07:49 +04:00
qid = make_kqid ( current_user_ns ( ) , type , id ) ;
if ( ! qid_valid ( qid ) )
return - EINVAL ;
2010-05-07 01:05:17 +04:00
copy_from_if_dqblk ( & fdq , & idq ) ;
2012-09-16 13:07:49 +04:00
return sb - > s_qcop - > set_dqblk ( sb , qid , & fdq ) ;
2010-02-16 11:44:47 +03:00
}
static int quota_setxstate ( struct super_block * sb , int cmd , void __user * addr )
{
__u32 flags ;
if ( copy_from_user ( & flags , addr , sizeof ( flags ) ) )
return - EFAULT ;
2010-02-16 11:44:48 +03:00
if ( ! sb - > s_qcop - > set_xstate )
return - ENOSYS ;
2010-02-16 11:44:47 +03:00
return sb - > s_qcop - > set_xstate ( sb , flags , cmd ) ;
}
static int quota_getxstate ( struct super_block * sb , void __user * addr )
{
struct fs_quota_stat fqs ;
int ret ;
2010-02-16 11:44:48 +03:00
if ( ! sb - > s_qcop - > get_xstate )
return - ENOSYS ;
2010-02-16 11:44:47 +03:00
ret = sb - > s_qcop - > get_xstate ( sb , & fqs ) ;
if ( ! ret & & copy_to_user ( addr , & fqs , sizeof ( fqs ) ) )
return - EFAULT ;
return ret ;
}
2005-04-17 02:20:36 +04:00
2013-08-07 02:27:07 +04:00
static int quota_getxstatev ( struct super_block * sb , void __user * addr )
{
struct fs_quota_statv fqs ;
int ret ;
if ( ! sb - > s_qcop - > get_xstatev )
return - ENOSYS ;
memset ( & fqs , 0 , sizeof ( fqs ) ) ;
if ( copy_from_user ( & fqs , addr , 1 ) ) /* Just read qs_version */
return - EFAULT ;
/* If this kernel doesn't support user specified version, fail */
switch ( fqs . qs_version ) {
case FS_QSTATV_VERSION1 :
break ;
default :
return - EINVAL ;
}
ret = sb - > s_qcop - > get_xstatev ( sb , & fqs ) ;
if ( ! ret & & copy_to_user ( addr , & fqs , sizeof ( fqs ) ) )
return - EFAULT ;
return ret ;
}
2010-02-16 11:44:47 +03:00
static int quota_setxquota ( struct super_block * sb , int type , qid_t id ,
void __user * addr )
{
struct fs_disk_quota fdq ;
2012-09-16 13:07:49 +04:00
struct kqid qid ;
2010-02-16 11:44:47 +03:00
if ( copy_from_user ( & fdq , addr , sizeof ( fdq ) ) )
return - EFAULT ;
2010-05-07 01:05:17 +04:00
if ( ! sb - > s_qcop - > set_dqblk )
2010-02-16 11:44:48 +03:00
return - ENOSYS ;
2012-09-16 13:07:49 +04:00
qid = make_kqid ( current_user_ns ( ) , type , id ) ;
if ( ! qid_valid ( qid ) )
return - EINVAL ;
return sb - > s_qcop - > set_dqblk ( sb , qid , & fdq ) ;
2010-02-16 11:44:47 +03:00
}
static int quota_getxquota ( struct super_block * sb , int type , qid_t id ,
void __user * addr )
{
struct fs_disk_quota fdq ;
2012-09-16 13:07:49 +04:00
struct kqid qid ;
2010-02-16 11:44:47 +03:00
int ret ;
2010-05-07 01:04:58 +04:00
if ( ! sb - > s_qcop - > get_dqblk )
2010-02-16 11:44:48 +03:00
return - ENOSYS ;
2012-09-16 13:07:49 +04:00
qid = make_kqid ( current_user_ns ( ) , type , id ) ;
if ( ! qid_valid ( qid ) )
return - EINVAL ;
ret = sb - > s_qcop - > get_dqblk ( sb , qid , & fdq ) ;
2010-02-16 11:44:47 +03:00
if ( ! ret & & copy_to_user ( addr , & fdq , sizeof ( fdq ) ) )
return - EFAULT ;
return ret ;
}
/* Copy parameters and call proper function */
static int do_quotactl ( struct super_block * sb , int type , int cmd , qid_t id ,
2010-09-15 19:38:58 +04:00
void __user * addr , struct path * path )
2010-02-16 11:44:47 +03:00
{
2010-02-16 11:44:50 +03:00
int ret ;
if ( type > = ( XQM_COMMAND ( cmd ) ? XQM_MAXQUOTAS : MAXQUOTAS ) )
return - EINVAL ;
if ( ! sb - > s_qcop )
return - ENOSYS ;
ret = check_quotactl_permission ( sb , type , cmd , id ) ;
if ( ret < 0 )
return ret ;
2010-02-16 11:44:47 +03:00
switch ( cmd ) {
case Q_QUOTAON :
2010-09-15 19:38:58 +04:00
return quota_quotaon ( sb , type , cmd , id , path ) ;
2010-02-16 11:44:47 +03:00
case Q_QUOTAOFF :
2010-02-16 11:44:48 +03:00
if ( ! sb - > s_qcop - > quota_off )
return - ENOSYS ;
2010-05-19 15:16:43 +04:00
return sb - > s_qcop - > quota_off ( sb , type ) ;
2010-02-16 11:44:47 +03:00
case Q_GETFMT :
return quota_getfmt ( sb , type , addr ) ;
case Q_GETINFO :
return quota_getinfo ( sb , type , addr ) ;
case Q_SETINFO :
return quota_setinfo ( sb , type , addr ) ;
case Q_GETQUOTA :
return quota_getquota ( sb , type , id , addr ) ;
case Q_SETQUOTA :
return quota_setquota ( sb , type , id , addr ) ;
case Q_SYNC :
2010-02-16 11:44:49 +03:00
if ( ! sb - > s_qcop - > quota_sync )
return - ENOSYS ;
2012-07-03 18:45:28 +04:00
return sb - > s_qcop - > quota_sync ( sb , type ) ;
2010-02-16 11:44:47 +03:00
case Q_XQUOTAON :
case Q_XQUOTAOFF :
case Q_XQUOTARM :
return quota_setxstate ( sb , cmd , addr ) ;
case Q_XGETQSTAT :
return quota_getxstate ( sb , addr ) ;
2013-08-07 02:27:07 +04:00
case Q_XGETQSTATV :
return quota_getxstatev ( sb , addr ) ;
2010-02-16 11:44:47 +03:00
case Q_XSETQLIM :
return quota_setxquota ( sb , type , id , addr ) ;
case Q_XGETQUOTA :
return quota_getxquota ( sb , type , id , addr ) ;
case Q_XQUOTASYNC :
2010-02-16 11:44:51 +03:00
if ( sb - > s_flags & MS_RDONLY )
return - EROFS ;
2012-02-20 06:28:18 +04:00
/* XFS quotas are fully coherent now, making this call a noop */
2010-02-16 11:44:51 +03:00
return 0 ;
2010-02-16 11:44:47 +03:00
default :
2010-02-16 11:44:48 +03:00
return - EINVAL ;
2005-04-17 02:20:36 +04:00
}
}
2012-11-04 02:02:28 +04:00
# ifdef CONFIG_BLOCK
2012-02-10 14:03:01 +04:00
/* Return 1 if 'cmd' will block on frozen filesystem */
static int quotactl_cmd_write ( int cmd )
{
switch ( cmd ) {
case Q_GETFMT :
case Q_GETINFO :
case Q_SYNC :
case Q_XGETQSTAT :
2013-08-07 02:27:07 +04:00
case Q_XGETQSTATV :
2012-02-10 14:03:01 +04:00
case Q_XGETQUOTA :
case Q_XQUOTASYNC :
return 0 ;
}
return 1 ;
}
2012-11-04 02:02:28 +04:00
# endif /* CONFIG_BLOCK */
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-09-30 22:45:40 +04:00
/*
* look up a superblock on which quota ops will be performed
* - use the name of a block device to find the superblock thereon
*/
2012-02-10 14:03:01 +04:00
static struct super_block * quotactl_block ( const char __user * special , int cmd )
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-09-30 22:45:40 +04:00
{
# ifdef CONFIG_BLOCK
struct block_device * bdev ;
struct super_block * sb ;
2012-10-10 23:25:28 +04:00
struct filename * tmp = getname ( special ) ;
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-09-30 22:45:40 +04:00
if ( IS_ERR ( tmp ) )
2008-02-07 11:15:26 +03:00
return ERR_CAST ( tmp ) ;
2012-10-10 23:25:28 +04:00
bdev = lookup_bdev ( tmp - > name ) ;
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-09-30 22:45:40 +04:00
putname ( tmp ) ;
if ( IS_ERR ( bdev ) )
2008-02-07 11:15:26 +03:00
return ERR_CAST ( bdev ) ;
2012-02-10 14:03:01 +04:00
if ( quotactl_cmd_write ( cmd ) )
sb = get_super_thawed ( bdev ) ;
else
sb = get_super ( bdev ) ;
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-09-30 22:45:40 +04:00
bdput ( bdev ) ;
if ( ! sb )
return ERR_PTR ( - ENODEV ) ;
return sb ;
# else
return ERR_PTR ( - ENODEV ) ;
# endif
}
2005-04-17 02:20:36 +04:00
/*
* This is the system call interface . This communicates with
* the user - level programs . Currently this only supports diskquota
* calls . Maybe we need to add the process quotas etc . in the future ,
* but we probably should use rlimits for that .
*/
2009-01-14 16:14:22 +03:00
SYSCALL_DEFINE4 ( quotactl , unsigned int , cmd , const char __user * , special ,
qid_t , id , void __user * , addr )
2005-04-17 02:20:36 +04:00
{
uint cmds , type ;
struct super_block * sb = NULL ;
2010-09-15 19:38:58 +04:00
struct path path , * pathp = NULL ;
2005-04-17 02:20:36 +04:00
int ret ;
cmds = cmd > > SUBCMDSHIFT ;
type = cmd & SUBCMDMASK ;
2010-02-16 11:44:49 +03:00
/*
* As a special case Q_SYNC can be called without a specific device .
* It will iterate all superblocks that have quota enabled and call
* the sync action on each of them .
*/
if ( ! special ) {
if ( cmds = = Q_SYNC )
return quota_sync_all ( type ) ;
return - ENODEV ;
2005-04-17 02:20:36 +04:00
}
2010-09-15 19:38:58 +04:00
/*
* Path for quotaon has to be resolved before grabbing superblock
* because that gets s_umount sem which is also possibly needed by path
* resolution ( think about autofs ) and thus deadlocks could arise .
*/
if ( cmds = = Q_QUOTAON ) {
2011-09-27 04:36:09 +04:00
ret = user_path_at ( AT_FDCWD , addr , LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT , & path ) ;
2010-09-15 19:38:58 +04:00
if ( ret )
pathp = ERR_PTR ( ret ) ;
else
pathp = & path ;
}
2012-02-10 14:03:01 +04:00
sb = quotactl_block ( special , cmds ) ;
2011-10-10 20:32:06 +04:00
if ( IS_ERR ( sb ) ) {
ret = PTR_ERR ( sb ) ;
goto out ;
}
2010-02-16 11:44:49 +03:00
2010-09-15 19:38:58 +04:00
ret = do_quotactl ( sb , type , cmds , id , addr , pathp ) ;
2005-04-17 02:20:36 +04:00
2010-02-16 11:44:49 +03:00
drop_super ( sb ) ;
2011-10-10 20:32:06 +04:00
out :
2010-09-15 19:38:58 +04:00
if ( pathp & & ! IS_ERR ( pathp ) )
path_put ( pathp ) ;
2005-04-17 02:20:36 +04:00
return ret ;
}