Commit 1c5bbffe authored by Jan Kara's avatar Jan Kara Committed by Linus Torvalds

[PATCH] [12/13] quota-12-compat

This patch implements configurable backward compatible quota interface.
Maybe this isn't needed in 2.5 but as some people want to use patches
in 2.4 where it's necessary I have implemented it.
parent 736e690e
......@@ -310,7 +310,7 @@ ia32_syscall_table:
data8 sys32_ni_syscall /* init_module */
data8 sys32_ni_syscall /* delete_module */
data8 sys32_ni_syscall /* get_kernel_syms */ /* 130 */
data8 sys_quotactl
data8 sys32_quotactl
data8 sys_getpgid
data8 sys_fchdir
data8 sys32_ni_syscall /* sys_bdflush */
......
......@@ -3669,6 +3669,97 @@ getname32 (const char *filename)
return result;
}
extern asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
#ifdef CONFIG_QIFACE_COMPAT
#ifdef CONFIG_QIFACE_V1
struct user_dqblk32 {
__u32 dqb_bhardlimit;
__u32 dqb_bsoftlimit;
__u32 dqb_curblocks;
__u32 dqb_ihardlimit;
__u32 dqb_isoftlimit;
__u32 dqb_curinodes;
__kernel_time_t32 dqb_btime;
__kernel_time_t32 dqb_itime;
};
typedef struct v1c_mem_dqblk comp_dqblk_t;
#define Q_COMP_GETQUOTA Q_V1_GETQUOTA
#define Q_COMP_SETQUOTA Q_V1_SETQUOTA
#define Q_COMP_SETQLIM Q_V1_SETQLIM
#define Q_COMP_SETUSE Q_V1_SETUSE
#else
struct user_dqblk32 {
__u32 dqb_ihardlimit;
__u32 dqb_isoftlimit;
__u32 dqb_curinodes;
__u32 dqb_bhardlimit;
__u32 dqb_bsoftlimit;
__u64 dqb_curspace;
__kernel_time_t32 dqb_btime;
__kernel_time_t32 dqb_itime;
};
typedef struct v2c_mem_dqblk comp_dqblk_t;
#define Q_COMP_GETQUOTA Q_V2_GETQUOTA
#define Q_COMP_SETQUOTA Q_V2_SETQUOTA
#define Q_COMP_SETQLIM Q_V2_SETQLIM
#define Q_COMP_SETUSE Q_V2_SETUSE
#endif
asmlinkage long sys32_quotactl(int cmd, const char *special, int id, caddr_t addr)
{
int cmds = cmd >> SUBCMDSHIFT;
long err;
comp_dqblk_t d;
mm_segment_t old_fs;
char *spec;
switch (cmds) {
case Q_COMP_GETQUOTA:
break;
case Q_COMP_SETQUOTA:
case Q_COMP_SETUSE:
case Q_COMP_SETQLIM:
if (copy_from_user(&d, (struct user_dqblk32 *)addr,
sizeof (struct user_dqblk32)))
return -EFAULT;
d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime;
d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime;
break;
default:
return sys_quotactl(cmd, special, id, (__kernel_caddr_t)addr);
}
spec = getname (special);
err = PTR_ERR(spec);
if (IS_ERR(spec)) return err;
old_fs = get_fs();
set_fs (KERNEL_DS);
err = sys_quotactl(cmd, (const char *)spec, id, (__kernel_caddr_t)&d);
set_fs (old_fs);
putname (spec);
if (err)
return err;
if (cmds == Q_COMP_GETQUOTA) {
__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
((struct user_dqblk32 *)&d)->dqb_itime = i;
((struct user_dqblk32 *)&d)->dqb_btime = b;
if (copy_to_user ((struct user_dqblk32 *)addr, &d,
sizeof (struct user_dqblk32)))
return -EFAULT;
}
return 0;
}
#else
/* No conversion needed for new interface */
asmlinkage long sys32_quotactl(int cmd, const char *special, int id, caddr_t addr)
{
return sys_quotactl(cmd, special, id, addr);
}
#endif
asmlinkage long
sys32_sched_rr_get_interval (pid_t pid, struct timespec32 *interval)
{
......
......@@ -897,6 +897,97 @@ asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long a
return sys32_fcntl(fd, cmd, arg);
}
extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
#ifdef CONFIG_QIFACE_COMPAT
#ifdef CONFIG_QIFACE_V1
struct user_dqblk32 {
__u32 dqb_bhardlimit;
__u32 dqb_bsoftlimit;
__u32 dqb_curblocks;
__u32 dqb_ihardlimit;
__u32 dqb_isoftlimit;
__u32 dqb_curinodes;
__kernel_time_t32 dqb_btime;
__kernel_time_t32 dqb_itime;
};
typedef struct v1c_mem_dqblk comp_dqblk_t;
#define Q_COMP_GETQUOTA Q_V1_GETQUOTA
#define Q_COMP_SETQUOTA Q_V1_SETQUOTA
#define Q_COMP_SETQLIM Q_V1_SETQLIM
#define Q_COMP_SETUSE Q_V1_SETUSE
#else
struct user_dqblk32 {
__u32 dqb_ihardlimit;
__u32 dqb_isoftlimit;
__u32 dqb_curinodes;
__u32 dqb_bhardlimit;
__u32 dqb_bsoftlimit;
__u64 dqb_curspace;
__kernel_time_t32 dqb_btime;
__kernel_time_t32 dqb_itime;
};
typedef struct v2c_mem_dqblk comp_dqblk_t;
#define Q_COMP_GETQUOTA Q_V2_GETQUOTA
#define Q_COMP_SETQUOTA Q_V2_SETQUOTA
#define Q_COMP_SETQLIM Q_V2_SETQLIM
#define Q_COMP_SETUSE Q_V2_SETUSE
#endif
asmlinkage int sys32_quotactl(int cmd, const char *special, int id, caddr_t addr)
{
int cmds = cmd >> SUBCMDSHIFT;
int err;
comp_dqblk_t d;
mm_segment_t old_fs;
char *spec;
switch (cmds) {
case Q_COMP_GETQUOTA:
break;
case Q_COMP_SETQUOTA:
case Q_COMP_SETUSE:
case Q_COMP_SETQLIM:
if (copy_from_user(&d, (struct user_dqblk32 *)addr,
sizeof (struct user_dqblk32)))
return -EFAULT;
d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime;
d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime;
break;
default:
return sys_quotactl(cmd, special, id, (__kernel_caddr_t)addr);
}
spec = getname (special);
err = PTR_ERR(spec);
if (IS_ERR(spec)) return err;
old_fs = get_fs();
set_fs (KERNEL_DS);
err = sys_quotactl(cmd, (const char *)spec, id, (__kernel_caddr_t)&d);
set_fs (old_fs);
putname (spec);
if (err)
return err;
if (cmds == Q_COMP_GETQUOTA) {
__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
((struct user_dqblk32 *)&d)->dqb_itime = i;
((struct user_dqblk32 *)&d)->dqb_btime = b;
if (copy_to_user ((struct user_dqblk32 *)addr, &d,
sizeof (struct user_dqblk32)))
return -EFAULT;
}
return 0;
}
#else
/* No conversion needed for new interface */
asmlinkage int sys32_quotactl(int cmd, const char *special, int id, caddr_t addr)
{
return sys_quotactl(cmd, special, id, addr);
}
#endif
static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
{
int err;
......
......@@ -586,7 +586,7 @@ sys32_quotactl_wrapper:
llgtr %r3,%r3 # const char *
lgfr %r4,%r4 # int
llgtr %r5,%r5 # caddr_t
jg sys_quotactl # branch to system call
jg sys32_quotactl # branch to system call
.globl sys32_getpgid_wrapper
sys32_getpgid_wrapper:
......
......@@ -889,6 +889,97 @@ asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long a
return sys32_fcntl(fd, cmd, arg);
}
extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
#ifdef CONFIG_QIFACE_COMPAT
#ifdef CONFIG_QIFACE_V1
struct user_dqblk32 {
__u32 dqb_bhardlimit;
__u32 dqb_bsoftlimit;
__u32 dqb_curblocks;
__u32 dqb_ihardlimit;
__u32 dqb_isoftlimit;
__u32 dqb_curinodes;
__kernel_time_t32 dqb_btime;
__kernel_time_t32 dqb_itime;
};
typedef struct v1c_mem_dqblk comp_dqblk_t;
#define Q_COMP_GETQUOTA Q_V1_GETQUOTA
#define Q_COMP_SETQUOTA Q_V1_SETQUOTA
#define Q_COMP_SETQLIM Q_V1_SETQLIM
#define Q_COMP_SETUSE Q_V1_SETUSE
#else
struct user_dqblk32 {
__u32 dqb_ihardlimit;
__u32 dqb_isoftlimit;
__u32 dqb_curinodes;
__u32 dqb_bhardlimit;
__u32 dqb_bsoftlimit;
__u64 dqb_curspace;
__kernel_time_t32 dqb_btime;
__kernel_time_t32 dqb_itime;
};
typedef struct v2c_mem_dqblk comp_dqblk_t;
#define Q_COMP_GETQUOTA Q_V2_GETQUOTA
#define Q_COMP_SETQUOTA Q_V2_SETQUOTA
#define Q_COMP_SETQLIM Q_V2_SETQLIM
#define Q_COMP_SETUSE Q_V2_SETUSE
#endif
asmlinkage int sys32_quotactl(int cmd, const char *special, int id, caddr_t addr)
{
int cmds = cmd >> SUBCMDSHIFT;
int err;
comp_dqblk_t d;
mm_segment_t old_fs;
char *spec;
switch (cmds) {
case Q_COMP_GETQUOTA:
break;
case Q_COMP_SETQUOTA:
case Q_COMP_SETUSE:
case Q_COMP_SETQLIM:
if (copy_from_user(&d, (struct user_dqblk32 *)addr,
sizeof (struct user_dqblk32)))
return -EFAULT;
d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime;
d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime;
break;
default:
return sys_quotactl(cmd, special, id, (__kernel_caddr_t)addr);
}
spec = getname (special);
err = PTR_ERR(spec);
if (IS_ERR(spec)) return err;
old_fs = get_fs();
set_fs (KERNEL_DS);
err = sys_quotactl(cmd, (const char *)spec, id, (__kernel_caddr_t)&d);
set_fs (old_fs);
putname (spec);
if (err)
return err;
if (cmds == Q_COMP_GETQUOTA) {
__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
((struct user_dqblk32 *)&d)->dqb_itime = i;
((struct user_dqblk32 *)&d)->dqb_btime = b;
if (copy_to_user ((struct user_dqblk32 *)addr, &d,
sizeof (struct user_dqblk32)))
return -EFAULT;
}
return 0;
}
#else
/* No conversion needed for new interface */
asmlinkage int sys32_quotactl(int cmd, const char *special, int id, caddr_t addr)
{
return sys_quotactl(cmd, special, id, addr);
}
#endif
static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
{
int err;
......
......@@ -52,7 +52,7 @@ sys_call_table32:
/*150*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
.word sys32_fcntl64, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount
/*160*/ .word sys32_sched_setaffinity, sys32_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_nis_syscall
.word sys_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_setxattr
.word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_setxattr
/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents
.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module
......
......@@ -18,6 +18,21 @@ CONFIG_QFMT_V2
need this functionality say Y here. Note that you will need latest
quota utilities for new quota format with this kernel.
CONFIG_QIFACE_COMPAT
This option will enable old quota interface in kernel.
If you have old quota tools (version <= 3.04) and you don't want to
upgrade them say Y here.
CONFIG_QIFACE_V1
This is the oldest quota interface. It was used for old quota format.
If you have old quota tools and you use old quota format choose this
interface (if unsure, this interface is the best one to choose).
CONFIG_QIFACE_V2
This quota interface was used by VFS v0 quota format. If you need
support for VFS v0 quota format (eg. you're using quota on ReiserFS)
and you don't want to upgrade quota tools, choose this interface.
CONFIG_MINIX_FS
Minix is a simple operating system used in many classes about OS's.
The minix file system (method to organize files on a hard disk
......
......@@ -7,6 +7,12 @@ comment 'File systems'
bool 'Quota support' CONFIG_QUOTA
dep_tristate ' Old quota format support' CONFIG_QFMT_V1 $CONFIG_QUOTA
dep_tristate ' VFS v0 quota format support' CONFIG_QFMT_V2 $CONFIG_QUOTA
dep_mbool ' Compatible quota interfaces' CONFIG_QIFACE_COMPAT $CONFIG_QUOTA
if [ "$CONFIG_QUOTA" = "y" -a "$CONFIG_QIFACE_COMPAT" = "y" ]; then
choice ' Compatible quota interfaces' \
"Original CONFIG_QIFACE_V1 \
VFSv0 CONFIG_QIFACE_V2" Original
fi
tristate 'Kernel automounter support' CONFIG_AUTOFS_FS
tristate 'Kernel automounter version 4 support (also supports v3)' CONFIG_AUTOFS4_FS
......
This diff is collapsed.
/*
* Definition of symbols used for backward compatible interface
*/
#ifndef _LINUX_QUOTACOMPAT_
#define _LINUX_QUOTACOMPAT_
#include <linux/types.h>
#include <linux/quota.h>
struct v1c_mem_dqblk {
__u32 dqb_bhardlimit; /* absolute limit on disk blks alloc */
__u32 dqb_bsoftlimit; /* preferred limit on disk blks */
__u32 dqb_curblocks; /* current block count */
__u32 dqb_ihardlimit; /* maximum # allocated inodes */
__u32 dqb_isoftlimit; /* preferred inode limit */
__u32 dqb_curinodes; /* current # allocated inodes */
time_t dqb_btime; /* time limit for excessive disk use */
time_t dqb_itime; /* time limit for excessive files */
};
struct v1c_dqstats {
__u32 lookups;
__u32 drops;
__u32 reads;
__u32 writes;
__u32 cache_hits;
__u32 allocated_dquots;
__u32 free_dquots;
__u32 syncs;
};
struct v2c_mem_dqblk {
unsigned int dqb_ihardlimit;
unsigned int dqb_isoftlimit;
unsigned int dqb_curinodes;
unsigned int dqb_bhardlimit;
unsigned int dqb_bsoftlimit;
qsize_t dqb_curspace;
__kernel_time_t dqb_btime;
__kernel_time_t dqb_itime;
};
struct v2c_mem_dqinfo {
unsigned int dqi_bgrace;
unsigned int dqi_igrace;
unsigned int dqi_flags;
unsigned int dqi_blocks;
unsigned int dqi_free_blk;
unsigned int dqi_free_entry;
};
struct v2c_dqstats {
__u32 lookups;
__u32 drops;
__u32 reads;
__u32 writes;
__u32 cache_hits;
__u32 allocated_dquots;
__u32 free_dquots;
__u32 syncs;
__u32 version;
};
#define Q_COMP_QUOTAON 0x0100 /* enable quotas */
#define Q_COMP_QUOTAOFF 0x0200 /* disable quotas */
#define Q_COMP_SYNC 0x0600 /* sync disk copy of a filesystems quotas */
#define Q_V1_GETQUOTA 0x0300 /* get limits and usage */
#define Q_V1_SETQUOTA 0x0400 /* set limits and usage */
#define Q_V1_SETUSE 0x0500 /* set usage */
#define Q_V1_SETQLIM 0x0700 /* set limits */
#define Q_V1_GETSTATS 0x0800 /* get collected stats */
#define Q_V1_RSQUASH 0x1000 /* set root_squash option */
#define Q_V2_SETQLIM 0x0700 /* set limits */
#define Q_V2_GETINFO 0x0900 /* get info about quotas - graces, flags... */
#define Q_V2_SETINFO 0x0A00 /* set info about quotas */
#define Q_V2_SETGRACE 0x0B00 /* set inode and block grace */
#define Q_V2_SETFLAGS 0x0C00 /* set flags for quota */
#define Q_V2_GETQUOTA 0x0D00 /* get limits and usage */
#define Q_V2_SETQUOTA 0x0E00 /* set limits and usage */
#define Q_V2_SETUSE 0x0F00 /* set usage */
#define Q_V2_GETSTATS 0x1100 /* get collected stats */
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment