2005-04-16 15:20:36 -07: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>
# include <asm/uaccess.h>
2007-07-15 23:41:12 -07:00
# include <linux/compat.h>
2005-04-16 15:20:36 -07:00
# include <linux/kernel.h>
# include <linux/security.h>
# include <linux/syscalls.h>
# include <linux/buffer_head.h>
2006-01-11 12:17:46 -08:00
# include <linux/capability.h>
2005-11-07 00:59:35 -08:00
# include <linux/quotaops.h>
2007-07-15 23:41:12 -07:00
# include <linux/types.h>
2009-09-28 12:35:17 +01:00
# include <net/netlink.h>
# include <net/genetlink.h>
2005-04-16 15:20:36 -07:00
/* Check validity of generic quotactl commands */
2009-01-27 15:47:22 +01:00
static int generic_quotactl_valid ( struct super_block * sb , int type , int cmd ,
qid_t id )
2005-04-16 15:20:36 -07:00
{
if ( type > = MAXQUOTAS )
return - EINVAL ;
if ( ! sb & & cmd ! = Q_SYNC )
return - ENODEV ;
/* Is operation supported? */
if ( sb & & ! sb - > s_qcop )
return - ENOSYS ;
switch ( cmd ) {
case Q_GETFMT :
break ;
case Q_QUOTAON :
if ( ! sb - > s_qcop - > quota_on )
return - ENOSYS ;
break ;
case Q_QUOTAOFF :
if ( ! sb - > s_qcop - > quota_off )
return - ENOSYS ;
break ;
case Q_SETINFO :
if ( ! sb - > s_qcop - > set_info )
return - ENOSYS ;
break ;
case Q_GETINFO :
if ( ! sb - > s_qcop - > get_info )
return - ENOSYS ;
break ;
case Q_SETQUOTA :
if ( ! sb - > s_qcop - > set_dqblk )
return - ENOSYS ;
break ;
case Q_GETQUOTA :
if ( ! sb - > s_qcop - > get_dqblk )
return - ENOSYS ;
break ;
case Q_SYNC :
if ( sb & & ! sb - > s_qcop - > quota_sync )
return - ENOSYS ;
break ;
default :
return - EINVAL ;
}
/* Is quota turned on for commands which need it? */
switch ( cmd ) {
case Q_GETFMT :
case Q_GETINFO :
case Q_SETINFO :
case Q_SETQUOTA :
case Q_GETQUOTA :
2009-01-27 15:47:22 +01:00
/* This is just an informative test so we are satisfied
* without the lock */
2008-08-20 17:50:32 +02:00
if ( ! sb_has_quota_active ( sb , type ) )
2005-04-16 15:20:36 -07:00
return - ESRCH ;
}
/* Check privileges */
if ( cmd = = Q_GETQUOTA ) {
2008-11-14 10:39:05 +11:00
if ( ( ( type = = USRQUOTA & & current_euid ( ) ! = id ) | |
2005-04-16 15:20:36 -07:00
( type = = GRPQUOTA & & ! in_egroup_p ( id ) ) ) & &
! capable ( CAP_SYS_ADMIN ) )
return - EPERM ;
}
else if ( cmd ! = Q_GETFMT & & cmd ! = Q_SYNC & & cmd ! = Q_GETINFO )
if ( ! capable ( CAP_SYS_ADMIN ) )
return - EPERM ;
return 0 ;
}
/* Check validity of XFS Quota Manager commands */
2009-01-27 15:47:22 +01:00
static int xqm_quotactl_valid ( struct super_block * sb , int type , int cmd ,
qid_t id )
2005-04-16 15:20:36 -07:00
{
if ( type > = XQM_MAXQUOTAS )
return - EINVAL ;
if ( ! sb )
return - ENODEV ;
if ( ! sb - > s_qcop )
return - ENOSYS ;
switch ( cmd ) {
case Q_XQUOTAON :
case Q_XQUOTAOFF :
case Q_XQUOTARM :
if ( ! sb - > s_qcop - > set_xstate )
return - ENOSYS ;
break ;
case Q_XGETQSTAT :
if ( ! sb - > s_qcop - > get_xstate )
return - ENOSYS ;
break ;
case Q_XSETQLIM :
if ( ! sb - > s_qcop - > set_xquota )
return - ENOSYS ;
break ;
case Q_XGETQUOTA :
if ( ! sb - > s_qcop - > get_xquota )
return - ENOSYS ;
break ;
2005-11-03 13:53:34 +11:00
case Q_XQUOTASYNC :
if ( ! sb - > s_qcop - > quota_sync )
return - ENOSYS ;
break ;
2005-04-16 15:20:36 -07:00
default :
return - EINVAL ;
}
/* Check privileges */
if ( cmd = = Q_XGETQUOTA ) {
2008-11-14 10:39:05 +11:00
if ( ( ( type = = XQM_USRQUOTA & & current_euid ( ) ! = id ) | |
2005-04-16 15:20:36 -07:00
( type = = XQM_GRPQUOTA & & ! in_egroup_p ( id ) ) ) & &
! capable ( CAP_SYS_ADMIN ) )
return - EPERM ;
2005-11-03 13:53:34 +11:00
} else if ( cmd ! = Q_XGETQSTAT & & cmd ! = Q_XQUOTASYNC ) {
2005-04-16 15:20:36 -07:00
if ( ! capable ( CAP_SYS_ADMIN ) )
return - EPERM ;
}
return 0 ;
}
2009-01-27 15:47:22 +01:00
static int check_quotactl_valid ( struct super_block * sb , int type , int cmd ,
qid_t id )
2005-04-16 15:20:36 -07:00
{
int error ;
if ( XQM_COMMAND ( cmd ) )
error = xqm_quotactl_valid ( sb , type , cmd , id ) ;
else
error = generic_quotactl_valid ( sb , type , cmd , id ) ;
if ( ! error )
error = security_quotactl ( cmd , type , id , sb ) ;
return error ;
}
2009-04-27 16:43:54 +02:00
# ifdef CONFIG_QUOTA
void sync_quota_sb ( struct super_block * sb , int type )
2005-04-16 15:20:36 -07:00
{
int cnt ;
2009-04-27 16:43:54 +02:00
if ( ! sb - > s_qcop - > quota_sync )
return ;
2005-04-16 15:20:36 -07:00
sb - > s_qcop - > quota_sync ( sb , type ) ;
2008-09-30 17:53:37 +02:00
if ( sb_dqopt ( sb ) - > flags & DQUOT_QUOTA_SYS_FILE )
return ;
2005-04-16 15:20:36 -07:00
/* This is not very clever (and fast) but currently I don't know about
* any other simple way of getting quota data to disk and we must get
* them there for userspace to be visible . . . */
if ( sb - > s_op - > sync_fs )
sb - > s_op - > sync_fs ( sb , 1 ) ;
sync_blockdev ( sb - > s_bdev ) ;
2007-05-16 22:11:19 -07:00
/*
* Now when everything is written we can discard the pagecache so
* that userspace sees the changes .
*/
2006-03-23 03:00:29 -08:00
mutex_lock ( & sb_dqopt ( sb ) - > dqonoff_mutex ) ;
2005-04-16 15:20:36 -07:00
for ( cnt = 0 ; cnt < MAXQUOTAS ; cnt + + ) {
if ( type ! = - 1 & & cnt ! = type )
continue ;
2008-08-20 17:50:32 +02:00
if ( ! sb_has_quota_active ( sb , cnt ) )
2005-04-16 15:20:36 -07:00
continue ;
2009-01-27 15:47:22 +01:00
mutex_lock_nested ( & sb_dqopt ( sb ) - > files [ cnt ] - > i_mutex ,
I_MUTEX_QUOTA ) ;
2007-05-16 22:11:19 -07:00
truncate_inode_pages ( & sb_dqopt ( sb ) - > files [ cnt ] - > i_data , 0 ) ;
mutex_unlock ( & sb_dqopt ( sb ) - > files [ cnt ] - > i_mutex ) ;
2005-04-16 15:20:36 -07:00
}
2006-03-23 03:00:29 -08:00
mutex_unlock ( & sb_dqopt ( sb ) - > dqonoff_mutex ) ;
2005-04-16 15:20:36 -07:00
}
2009-04-27 16:43:54 +02:00
# endif
2005-04-16 15:20:36 -07:00
2009-04-27 16:43:54 +02:00
static void sync_dquots ( int type )
2005-04-16 15:20:36 -07:00
{
2009-04-27 16:43:54 +02:00
struct super_block * sb ;
2008-07-25 01:46:50 -07:00
int cnt ;
2005-06-23 00:09:54 -07:00
spin_lock ( & sb_lock ) ;
restart :
list_for_each_entry ( sb , & super_blocks , s_list ) {
2009-01-27 15:47:22 +01:00
/* This test just improves performance so it needn't be
* reliable . . . */
2008-07-25 01:46:50 -07:00
for ( cnt = 0 ; cnt < MAXQUOTAS ; cnt + + ) {
if ( type ! = - 1 & & type ! = cnt )
continue ;
2008-08-20 17:50:32 +02:00
if ( ! sb_has_quota_active ( sb , cnt ) )
2008-07-25 01:46:50 -07:00
continue ;
if ( ! info_dirty ( & sb_dqopt ( sb ) - > info [ cnt ] ) & &
2009-01-27 15:47:22 +01:00
list_empty ( & sb_dqopt ( sb ) - > info [ cnt ] . dqi_dirty_list ) )
2008-07-25 01:46:50 -07:00
continue ;
break ;
}
if ( cnt = = MAXQUOTAS )
2005-06-23 00:09:54 -07:00
continue ;
sb - > s_count + + ;
spin_unlock ( & sb_lock ) ;
down_read ( & sb - > s_umount ) ;
2009-04-27 16:43:54 +02:00
if ( sb - > s_root )
sync_quota_sb ( sb , type ) ;
2005-06-23 00:09:54 -07:00
up_read ( & sb - > s_umount ) ;
spin_lock ( & sb_lock ) ;
if ( __put_super_and_need_restart ( sb ) )
goto restart ;
2005-04-16 15:20:36 -07:00
}
2005-06-23 00:09:54 -07:00
spin_unlock ( & sb_lock ) ;
2005-04-16 15:20:36 -07:00
}
/* Copy parameters and call proper function */
2009-01-27 15:47:22 +01:00
static int do_quotactl ( struct super_block * sb , int type , int cmd , qid_t id ,
void __user * addr )
2005-04-16 15:20:36 -07:00
{
int ret ;
switch ( cmd ) {
case Q_QUOTAON : {
char * pathname ;
2009-01-27 15:47:22 +01:00
pathname = getname ( addr ) ;
if ( IS_ERR ( pathname ) )
2005-04-16 15:20:36 -07:00
return PTR_ERR ( pathname ) ;
2008-04-28 02:14:33 -07:00
ret = sb - > s_qcop - > quota_on ( sb , type , id , pathname , 0 ) ;
2005-04-16 15:20:36 -07:00
putname ( pathname ) ;
return ret ;
}
case Q_QUOTAOFF :
2008-04-28 02:14:33 -07:00
return sb - > s_qcop - > quota_off ( sb , type , 0 ) ;
2005-04-16 15:20:36 -07:00
case Q_GETFMT : {
__u32 fmt ;
down_read ( & sb_dqopt ( sb ) - > dqptr_sem ) ;
2008-08-20 17:50:32 +02:00
if ( ! sb_has_quota_active ( sb , type ) ) {
2005-04-16 15:20:36 -07:00
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 ;
}
case Q_GETINFO : {
struct if_dqinfo info ;
2009-01-27 15:47:22 +01:00
ret = sb - > s_qcop - > get_info ( sb , type , & info ) ;
if ( ret )
2005-04-16 15:20:36 -07:00
return ret ;
if ( copy_to_user ( addr , & info , sizeof ( info ) ) )
return - EFAULT ;
return 0 ;
}
case Q_SETINFO : {
struct if_dqinfo info ;
if ( copy_from_user ( & info , addr , sizeof ( info ) ) )
return - EFAULT ;
return sb - > s_qcop - > set_info ( sb , type , & info ) ;
}
case Q_GETQUOTA : {
struct if_dqblk idq ;
2009-01-27 15:47:22 +01:00
ret = sb - > s_qcop - > get_dqblk ( sb , type , id , & idq ) ;
if ( ret )
2005-04-16 15:20:36 -07:00
return ret ;
if ( copy_to_user ( addr , & idq , sizeof ( idq ) ) )
return - EFAULT ;
return 0 ;
}
case Q_SETQUOTA : {
struct if_dqblk idq ;
if ( copy_from_user ( & idq , addr , sizeof ( idq ) ) )
return - EFAULT ;
return sb - > s_qcop - > set_dqblk ( sb , type , id , & idq ) ;
}
case Q_SYNC :
2009-04-27 16:43:54 +02:00
if ( sb )
sync_quota_sb ( sb , type ) ;
else
sync_dquots ( type ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
case Q_XQUOTAON :
case Q_XQUOTAOFF :
case Q_XQUOTARM : {
__u32 flags ;
if ( copy_from_user ( & flags , addr , sizeof ( flags ) ) )
return - EFAULT ;
return sb - > s_qcop - > set_xstate ( sb , flags , cmd ) ;
}
case Q_XGETQSTAT : {
struct fs_quota_stat fqs ;
if ( ( ret = sb - > s_qcop - > get_xstate ( sb , & fqs ) ) )
return ret ;
if ( copy_to_user ( addr , & fqs , sizeof ( fqs ) ) )
return - EFAULT ;
return 0 ;
}
case Q_XSETQLIM : {
struct fs_disk_quota fdq ;
if ( copy_from_user ( & fdq , addr , sizeof ( fdq ) ) )
return - EFAULT ;
return sb - > s_qcop - > set_xquota ( sb , type , id , & fdq ) ;
}
case Q_XGETQUOTA : {
struct fs_disk_quota fdq ;
2009-01-27 15:47:22 +01:00
ret = sb - > s_qcop - > get_xquota ( sb , type , id , & fdq ) ;
if ( ret )
2005-04-16 15:20:36 -07:00
return ret ;
if ( copy_to_user ( addr , & fdq , sizeof ( fdq ) ) )
return - EFAULT ;
return 0 ;
}
2005-11-03 13:53:34 +11:00
case Q_XQUOTASYNC :
return sb - > s_qcop - > quota_sync ( sb , type ) ;
2005-04-16 15:20:36 -07:00
/* We never reach here unless validity check is broken */
default :
BUG ( ) ;
}
return 0 ;
}
[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 20:45:40 +02:00
/*
* look up a superblock on which quota ops will be performed
* - use the name of a block device to find the superblock thereon
*/
2009-01-27 01:47:11 +01:00
static struct super_block * quotactl_block ( const char __user * 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 20:45:40 +02:00
{
# ifdef CONFIG_BLOCK
struct block_device * bdev ;
struct super_block * sb ;
char * tmp = getname ( special ) ;
if ( IS_ERR ( tmp ) )
2008-02-07 00:15:26 -08:00
return ERR_CAST ( tmp ) ;
[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 20:45:40 +02:00
bdev = lookup_bdev ( tmp ) ;
putname ( tmp ) ;
if ( IS_ERR ( bdev ) )
2008-02-07 00:15:26 -08:00
return ERR_CAST ( 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 20:45:40 +02:00
sb = get_super ( bdev ) ;
bdput ( bdev ) ;
if ( ! sb )
return ERR_PTR ( - ENODEV ) ;
return sb ;
# else
return ERR_PTR ( - ENODEV ) ;
# endif
}
2005-04-16 15:20:36 -07: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 14:14:22 +01:00
SYSCALL_DEFINE4 ( quotactl , unsigned int , cmd , const char __user * , special ,
qid_t , id , void __user * , addr )
2005-04-16 15:20:36 -07:00
{
uint cmds , type ;
struct super_block * sb = NULL ;
int ret ;
cmds = cmd > > SUBCMDSHIFT ;
type = cmd & SUBCMDMASK ;
if ( cmds ! = Q_SYNC | | 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 20:45:40 +02:00
sb = quotactl_block ( special ) ;
if ( IS_ERR ( sb ) )
return PTR_ERR ( sb ) ;
2005-04-16 15:20:36 -07:00
}
ret = check_quotactl_valid ( sb , type , cmds , id ) ;
if ( ret > = 0 )
ret = do_quotactl ( sb , type , cmds , id , addr ) ;
if ( sb )
drop_super ( sb ) ;
return ret ;
}
2007-07-15 23:41:12 -07:00
2007-07-27 15:35:43 -07:00
# if defined(CONFIG_COMPAT_FOR_U64_ALIGNMENT)
2007-07-15 23:41:12 -07:00
/*
* This code works only for 32 bit quota tools over 64 bit OS ( x86_64 , ia64 )
* and is necessary due to alignment problems .
*/
struct compat_if_dqblk {
compat_u64 dqb_bhardlimit ;
compat_u64 dqb_bsoftlimit ;
compat_u64 dqb_curspace ;
compat_u64 dqb_ihardlimit ;
compat_u64 dqb_isoftlimit ;
compat_u64 dqb_curinodes ;
compat_u64 dqb_btime ;
compat_u64 dqb_itime ;
compat_uint_t dqb_valid ;
} ;
/* XFS structures */
struct compat_fs_qfilestat {
compat_u64 dqb_bhardlimit ;
compat_u64 qfs_nblks ;
compat_uint_t qfs_nextents ;
} ;
struct compat_fs_quota_stat {
__s8 qs_version ;
__u16 qs_flags ;
__s8 qs_pad ;
struct compat_fs_qfilestat qs_uquota ;
struct compat_fs_qfilestat qs_gquota ;
compat_uint_t qs_incoredqs ;
compat_int_t qs_btimelimit ;
compat_int_t qs_itimelimit ;
compat_int_t qs_rtbtimelimit ;
__u16 qs_bwarnlimit ;
__u16 qs_iwarnlimit ;
} ;
asmlinkage long sys32_quotactl ( unsigned int cmd , const char __user * special ,
qid_t id , void __user * addr )
{
unsigned int cmds ;
struct if_dqblk __user * dqblk ;
struct compat_if_dqblk __user * compat_dqblk ;
struct fs_quota_stat __user * fsqstat ;
struct compat_fs_quota_stat __user * compat_fsqstat ;
compat_uint_t data ;
u16 xdata ;
long ret ;
cmds = cmd > > SUBCMDSHIFT ;
switch ( cmds ) {
case Q_GETQUOTA :
dqblk = compat_alloc_user_space ( sizeof ( struct if_dqblk ) ) ;
compat_dqblk = addr ;
ret = sys_quotactl ( cmd , special , id , dqblk ) ;
if ( ret )
break ;
if ( copy_in_user ( compat_dqblk , dqblk , sizeof ( * compat_dqblk ) ) | |
get_user ( data , & dqblk - > dqb_valid ) | |
put_user ( data , & compat_dqblk - > dqb_valid ) )
ret = - EFAULT ;
break ;
case Q_SETQUOTA :
dqblk = compat_alloc_user_space ( sizeof ( struct if_dqblk ) ) ;
compat_dqblk = addr ;
ret = - EFAULT ;
if ( copy_in_user ( dqblk , compat_dqblk , sizeof ( * compat_dqblk ) ) | |
get_user ( data , & compat_dqblk - > dqb_valid ) | |
put_user ( data , & dqblk - > dqb_valid ) )
break ;
ret = sys_quotactl ( cmd , special , id , dqblk ) ;
break ;
case Q_XGETQSTAT :
fsqstat = compat_alloc_user_space ( sizeof ( struct fs_quota_stat ) ) ;
compat_fsqstat = addr ;
ret = sys_quotactl ( cmd , special , id , fsqstat ) ;
if ( ret )
break ;
ret = - EFAULT ;
/* Copying qs_version, qs_flags, qs_pad */
if ( copy_in_user ( compat_fsqstat , fsqstat ,
offsetof ( struct compat_fs_quota_stat , qs_uquota ) ) )
break ;
/* Copying qs_uquota */
if ( copy_in_user ( & compat_fsqstat - > qs_uquota ,
& fsqstat - > qs_uquota ,
sizeof ( compat_fsqstat - > qs_uquota ) ) | |
get_user ( data , & fsqstat - > qs_uquota . qfs_nextents ) | |
put_user ( data , & compat_fsqstat - > qs_uquota . qfs_nextents ) )
break ;
/* Copying qs_gquota */
if ( copy_in_user ( & compat_fsqstat - > qs_gquota ,
& fsqstat - > qs_gquota ,
sizeof ( compat_fsqstat - > qs_gquota ) ) | |
get_user ( data , & fsqstat - > qs_gquota . qfs_nextents ) | |
put_user ( data , & compat_fsqstat - > qs_gquota . qfs_nextents ) )
break ;
/* Copying the rest */
if ( copy_in_user ( & compat_fsqstat - > qs_incoredqs ,
& fsqstat - > qs_incoredqs ,
sizeof ( struct compat_fs_quota_stat ) -
offsetof ( struct compat_fs_quota_stat , qs_incoredqs ) ) | |
get_user ( xdata , & fsqstat - > qs_iwarnlimit ) | |
put_user ( xdata , & compat_fsqstat - > qs_iwarnlimit ) )
break ;
ret = 0 ;
break ;
default :
ret = sys_quotactl ( cmd , special , id , addr ) ;
}
return ret ;
}
# endif
2009-09-28 12:35:17 +01:00
# ifdef CONFIG_QUOTA_NETLINK_INTERFACE
/* Netlink family structure for quota */
static struct genl_family quota_genl_family = {
. id = GENL_ID_GENERATE ,
. hdrsize = 0 ,
. name = " VFS_DQUOT " ,
. version = 1 ,
. maxattr = QUOTA_NL_A_MAX ,
} ;
/**
* quota_send_warning - Send warning to userspace about exceeded quota
* @ type : The quota type : USRQQUOTA , GRPQUOTA , . . .
* @ id : The user or group id of the quota that was exceeded
* @ dev : The device on which the fs is mounted ( sb - > s_dev )
* @ warntype : The type of the warning : QUOTA_NL_ . . .
*
* This can be used by filesystems ( including those which don ' t use
* dquot ) to send a message to userspace relating to quota limits .
*
*/
void quota_send_warning ( short type , unsigned int id , dev_t dev ,
const char warntype )
{
static atomic_t seq ;
struct sk_buff * skb ;
void * msg_head ;
int ret ;
int msg_size = 4 * nla_total_size ( sizeof ( u32 ) ) +
2 * nla_total_size ( sizeof ( u64 ) ) ;
/* We have to allocate using GFP_NOFS as we are called from a
* filesystem performing write and thus further recursion into
* the fs to free some data could cause deadlocks . */
skb = genlmsg_new ( msg_size , GFP_NOFS ) ;
if ( ! skb ) {
printk ( KERN_ERR
" VFS: Not enough memory to send quota warning. \n " ) ;
return ;
}
msg_head = genlmsg_put ( skb , 0 , atomic_add_return ( 1 , & seq ) ,
& quota_genl_family , 0 , QUOTA_NL_C_WARNING ) ;
if ( ! msg_head ) {
printk ( KERN_ERR
" VFS: Cannot store netlink header in quota warning. \n " ) ;
goto err_out ;
}
ret = nla_put_u32 ( skb , QUOTA_NL_A_QTYPE , type ) ;
if ( ret )
goto attr_err_out ;
ret = nla_put_u64 ( skb , QUOTA_NL_A_EXCESS_ID , id ) ;
if ( ret )
goto attr_err_out ;
ret = nla_put_u32 ( skb , QUOTA_NL_A_WARNING , warntype ) ;
if ( ret )
goto attr_err_out ;
ret = nla_put_u32 ( skb , QUOTA_NL_A_DEV_MAJOR , MAJOR ( dev ) ) ;
if ( ret )
goto attr_err_out ;
ret = nla_put_u32 ( skb , QUOTA_NL_A_DEV_MINOR , MINOR ( dev ) ) ;
if ( ret )
goto attr_err_out ;
ret = nla_put_u64 ( skb , QUOTA_NL_A_CAUSED_ID , current_uid ( ) ) ;
if ( ret )
goto attr_err_out ;
genlmsg_end ( skb , msg_head ) ;
genlmsg_multicast ( skb , 0 , quota_genl_family . id , GFP_NOFS ) ;
return ;
attr_err_out :
printk ( KERN_ERR " VFS: Not enough space to compose quota message! \n " ) ;
err_out :
kfree_skb ( skb ) ;
}
EXPORT_SYMBOL ( quota_send_warning ) ;
static int __init quota_init ( void )
{
if ( genl_register_family ( & quota_genl_family ) ! = 0 )
printk ( KERN_ERR
" VFS: Failed to create quota netlink interface. \n " ) ;
return 0 ;
} ;
module_init ( quota_init ) ;
# endif