summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/fs.h13
-rw-r--r--include/linux/quota.h130
-rw-r--r--include/linux/quotaops.h24
-rw-r--r--include/linux/xqm.h159
4 files changed, 284 insertions, 42 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f50388ea30dc..f30905c9a4f1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -626,7 +626,7 @@ struct quota_info {
struct semaphore dqoff_sem; /* serialize quota_off() and quota_on() on device */
struct file *files[MAXQUOTAS]; /* fp's to quotafiles */
struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */
- struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each format */
+ struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */
};
/*
@@ -659,6 +659,7 @@ struct super_block {
struct file_system_type *s_type;
struct super_operations *s_op;
struct dquot_operations *dq_op;
+ struct quotactl_ops *s_qcop;
struct export_operations *s_export_op;
unsigned long s_flags;
unsigned long s_magic;
@@ -878,16 +879,6 @@ static inline void mark_inode_dirty_sync(struct inode *inode)
__mark_inode_dirty(inode, I_DIRTY_SYNC);
}
-struct dquot_operations {
- void (*initialize) (struct inode *, short);
- void (*drop) (struct inode *);
- int (*alloc_space) (struct inode *, qsize_t, int);
- int (*alloc_inode) (const struct inode *, unsigned long);
- void (*free_space) (struct inode *, qsize_t);
- void (*free_inode) (const struct inode *, unsigned long);
- int (*transfer) (struct inode *, struct iattr *);
-};
-
/**
* &export_operations - for nfsd to communicate with file systems
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 7e481591efc4..49ceac92bc29 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -70,9 +70,6 @@ typedef __u64 qsize_t; /* Type in which we store sizes */
"undefined", \
};
-#define QUOTAFILENAME "quota"
-#define QUOTAGROUP "staff"
-
/*
* Command definitions for the 'quotactl' system call.
* The commands are broken into a main command defined below
@@ -83,7 +80,61 @@ typedef __u64 qsize_t; /* Type in which we store sizes */
#define SUBCMDSHIFT 8
#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
-#define Q_SYNC 0x0600 /* sync disk copy of a filesystems quotas */
+#define Q_SYNC 0x800001 /* sync disk copy of a filesystems quotas */
+#define Q_QUOTAON 0x800002 /* turn quotas on */
+#define Q_QUOTAOFF 0x800003 /* turn quotas off */
+#define Q_GETFMT 0x800004 /* get quota format used on given filesystem */
+#define Q_GETINFO 0x800005 /* get information about quota files */
+#define Q_SETINFO 0x800006 /* set information about quota files */
+#define Q_GETQUOTA 0x800007 /* get user quota structure */
+#define Q_SETQUOTA 0x800008 /* set user quota structure */
+
+/*
+ * Quota structure used for communication with userspace via quotactl
+ * Following flags are used to specify which fields are valid
+ */
+#define QIF_BLIMITS 1
+#define QIF_SPACE 2
+#define QIF_ILIMITS 4
+#define QIF_INODES 8
+#define QIF_BTIME 16
+#define QIF_ITIME 32
+#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
+#define QIF_USAGE (QIF_SPACE | QIF_INODES)
+#define QIF_TIMES (QIF_BTIME | QIF_ITIME)
+#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
+
+struct if_dqblk {
+ __u64 dqb_bhardlimit;
+ __u64 dqb_bsoftlimit;
+ __u64 dqb_curspace;
+ __u64 dqb_ihardlimit;
+ __u64 dqb_isoftlimit;
+ __u64 dqb_curinodes;
+ __u64 dqb_btime;
+ __u64 dqb_itime;
+ __u32 dqb_valid;
+};
+
+/*
+ * Structure used for setting quota information about file via quotactl
+ * Following flags are used to specify which fields are valid
+ */
+#define IIF_BGRACE 1
+#define IIF_IGRACE 2
+#define IIF_FLAGS 4
+#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
+
+struct if_dqinfo {
+ __u64 dqi_bgrace;
+ __u64 dqi_igrace;
+ __u32 dqi_flags;
+ __u32 dqi_valid;
+};
+
+#ifdef __KERNEL__
+
+#include <linux/xqm.h>
/*
* Data for one user/group kept in memory
@@ -105,7 +156,7 @@ struct mem_dqblk {
struct quota_format_type;
struct mem_dqinfo {
- struct quota_format_type * dqi_format;
+ struct quota_format_type *dqi_format;
int dqi_flags;
unsigned int dqi_bgrace;
unsigned int dqi_igrace;
@@ -113,8 +164,6 @@ struct mem_dqinfo {
} u;
};
-#ifdef __KERNEL__
-
#define DQF_MASK 0xffff /* Mask for format specific flags */
#define DQF_INFO_DIRTY 0x10000 /* Is info dirty? */
@@ -127,24 +176,6 @@ extern inline void mark_info_dirty(struct mem_dqinfo *info)
#define sb_dqopt(sb) (&(sb)->s_dquot)
-#endif /* __KERNEL__ */
-
-/*
- * Shorthand notation.
- */
-#define dq_bhardlimit dq_dqb.dqb_bhardlimit
-#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit
-#define dq_curspace dq_dqb.dqb_curspace
-#define dq_ihardlimit dq_dqb.dqb_ihardlimit
-#define dq_isoftlimit dq_dqb.dqb_isoftlimit
-#define dq_curinodes dq_dqb.dqb_curinodes
-#define dq_btime dq_dqb.dqb_btime
-#define dq_itime dq_dqb.dqb_itime
-
-#define dqoff(UID) ((loff_t)((UID) * sizeof (struct dqblk)))
-
-#ifdef __KERNEL__
-
extern int nr_dquots, nr_free_dquots;
struct dqstats {
@@ -203,25 +234,70 @@ extern inline void mark_dquot_dirty(struct dquot *dquot)
/* Operations which must be implemented by each quota format */
struct quota_format_ops {
int (*check_quota_file)(struct super_block *sb, int type); /* Detect whether file is in our format */
- int (*read_file_info)(struct super_block *sb, int type); /* Read main info about file */
+ int (*read_file_info)(struct super_block *sb, int type); /* Read main info about file - called on quotaon() */
int (*write_file_info)(struct super_block *sb, int type); /* Write main info about file */
int (*free_file_info)(struct super_block *sb, int type); /* Called on quotaoff() */
int (*read_dqblk)(struct dquot *dquot); /* Read structure for one user */
int (*commit_dqblk)(struct dquot *dquot); /* Write (or delete) structure for one user */
};
+/* Operations working with dquots */
+struct dquot_operations {
+ void (*initialize) (struct inode *, short);
+ void (*drop) (struct inode *);
+ int (*alloc_space) (struct inode *, qsize_t, int);
+ int (*alloc_inode) (const struct inode *, unsigned long);
+ void (*free_space) (struct inode *, qsize_t);
+ void (*free_inode) (const struct inode *, unsigned long);
+ int (*transfer) (struct inode *, struct iattr *);
+};
+
+/* Operations handling requests from userspace */
+struct quotactl_ops {
+ int (*quota_on)(struct super_block *, int, int, char *);
+ int (*quota_off)(struct super_block *, int);
+ int (*quota_sync)(struct super_block *, int);
+ int (*get_info)(struct super_block *, int, struct if_dqinfo *);
+ int (*set_info)(struct super_block *, int, struct if_dqinfo *);
+ int (*get_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
+ int (*set_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
+ int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
+ int (*set_xstate)(struct super_block *, unsigned int, int);
+ int (*get_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
+ int (*set_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
+};
+
struct quota_format_type {
int qf_fmt_id; /* Quota format id */
struct quota_format_ops *qf_ops; /* Operations of format */
+ struct module *qf_owner; /* Module implementing quota format */
struct quota_format_type *qf_next;
};
+static inline int is_enabled(struct quota_info *dqopt, int type)
+{
+ switch (type) {
+ case USRQUOTA:
+ return dqopt->flags & DQUOT_USR_ENABLED;
+ case GRPQUOTA:
+ return dqopt->flags & DQUOT_GRP_ENABLED;
+ }
+ return 0;
+}
+
+#define sb_any_quota_enabled(sb) (is_enabled(sb_dqopt(sb), USRQUOTA) | is_enabled(sb_dqopt(sb), GRPQUOTA))
+
+#define sb_has_quota_enabled(sb, type) (is_enabled(sb_dqopt(sb), type))
+
+int register_quota_format(struct quota_format_type *fmt);
+void unregister_quota_format(struct quota_format_type *fmt);
+
#else
# /* nodep */ include <sys/cdefs.h>
__BEGIN_DECLS
-long quotactl __P ((int, const char *, int, caddr_t));
+long quotactl __P ((unsigned int, const char *, int, caddr_t));
__END_DECLS
#endif /* __KERNEL__ */
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index b5da5ff5bb9a..0cd58a4fa275 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -20,10 +20,10 @@
/*
* declaration of quota_function calls in kernel.
*/
+extern int sync_dquots(kdev_t dev, short type);
+
extern void dquot_initialize(struct inode *inode, short type);
extern void dquot_drop(struct inode *inode);
-extern int quota_off(struct super_block *sb, short type);
-extern int sync_dquots(struct super_block *sb, short type);
extern int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc);
extern int dquot_alloc_inode(const struct inode *inode, unsigned long number);
@@ -36,7 +36,11 @@ extern int dquot_transfer(struct inode *inode, struct iattr *iattr);
/*
* Operations supported for diskquotas.
*/
-#define sb_any_quota_enabled(sb) ((sb)->s_dquot.flags & (DQUOT_USR_ENABLED | DQUOT_GRP_ENABLED))
+extern struct dquot_operations dquot_operations;
+extern struct quotactl_ops vfs_quotactl_ops;
+
+#define sb_dquot_ops (&dquot_operations)
+#define sb_quotactl_ops (&vfs_quotactl_ops)
static __inline__ void DQUOT_INIT(struct inode *inode)
{
@@ -160,13 +164,25 @@ static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr)
}
#define DQUOT_SYNC(sb) sync_dquots(sb, -1)
-#define DQUOT_OFF(sb) quota_off(sb, -1)
+
+static __inline__ int DQUOT_OFF(struct super_block *sb)
+{
+ int ret = -ENOSYS;
+
+ lock_kernel();
+ if (sb->s_qcop && sb->s_qcop->quota_off)
+ ret = sb->s_qcop->quota_off(sb, -1);
+ unlock_kernel();
+ return ret;
+}
#else
/*
* NO-OP when quota not configured.
*/
+#define sb_dquot_ops (NULL)
+#define sb_quotactl_ops (NULL)
#define DQUOT_INIT(inode) do { } while(0)
#define DQUOT_DROP(inode) do { } while(0)
#define DQUOT_ALLOC_INODE(inode) (0)
diff --git a/include/linux/xqm.h b/include/linux/xqm.h
new file mode 100644
index 000000000000..d077bc18a424
--- /dev/null
+++ b/include/linux/xqm.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ * USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+#ifndef _LINUX_XQM_H
+#define _LINUX_XQM_H
+
+#include <linux/types.h>
+
+/*
+ * Disk quota - quotactl(2) commands for the XFS Quota Manager (XQM).
+ */
+
+#define XQM_CMD(x) (('X'<<8)+(x)) /* note: forms first QCMD argument */
+#define Q_XQUOTAON XQM_CMD(0x1) /* enable accounting/enforcement */
+#define Q_XQUOTAOFF XQM_CMD(0x2) /* disable accounting/enforcement */
+#define Q_XGETQUOTA XQM_CMD(0x3) /* get disk limits and usage */
+#define Q_XSETQLIM XQM_CMD(0x4) /* set disk limits */
+#define Q_XGETQSTAT XQM_CMD(0x5) /* get quota subsystem status */
+#define Q_XQUOTARM XQM_CMD(0x6) /* free disk space used by dquots */
+
+/*
+ * fs_disk_quota structure:
+ *
+ * This contains the current quota information regarding a user/proj/group.
+ * It is 64-bit aligned, and all the blk units are in BBs (Basic Blocks) of
+ * 512 bytes.
+ */
+#define FS_DQUOT_VERSION 1 /* fs_disk_quota.d_version */
+typedef struct fs_disk_quota {
+ __s8 d_version; /* version of this structure */
+ __s8 d_flags; /* XFS_{USER,PROJ,GROUP}_QUOTA */
+ __u16 d_fieldmask; /* field specifier */
+ __u32 d_id; /* user, project, or group ID */
+ __u64 d_blk_hardlimit;/* absolute limit on disk blks */
+ __u64 d_blk_softlimit;/* preferred limit on disk blks */
+ __u64 d_ino_hardlimit;/* maximum # allocated inodes */
+ __u64 d_ino_softlimit;/* preferred inode limit */
+ __u64 d_bcount; /* # disk blocks owned by the user */
+ __u64 d_icount; /* # inodes owned by the user */
+ __s32 d_itimer; /* zero if within inode limits */
+ /* if not, we refuse service */
+ __s32 d_btimer; /* similar to above; for disk blocks */
+ __u16 d_iwarns; /* # warnings issued wrt num inodes */
+ __u16 d_bwarns; /* # warnings issued wrt disk blocks */
+ __s32 d_padding2; /* padding2 - for future use */
+ __u64 d_rtb_hardlimit;/* absolute limit on realtime blks */
+ __u64 d_rtb_softlimit;/* preferred limit on RT disk blks */
+ __u64 d_rtbcount; /* # realtime blocks owned */
+ __s32 d_rtbtimer; /* similar to above; for RT disk blks */
+ __u16 d_rtbwarns; /* # warnings issued wrt RT disk blks */
+ __s16 d_padding3; /* padding3 - for future use */
+ char d_padding4[8]; /* yet more padding */
+} fs_disk_quota_t;
+
+/*
+ * These fields are sent to Q_XSETQLIM to specify fields that need to change.
+ */
+#define FS_DQ_ISOFT (1<<0)
+#define FS_DQ_IHARD (1<<1)
+#define FS_DQ_BSOFT (1<<2)
+#define FS_DQ_BHARD (1<<3)
+#define FS_DQ_RTBSOFT (1<<4)
+#define FS_DQ_RTBHARD (1<<5)
+#define FS_DQ_LIMIT_MASK (FS_DQ_ISOFT | FS_DQ_IHARD | FS_DQ_BSOFT | \
+ FS_DQ_BHARD | FS_DQ_RTBSOFT | FS_DQ_RTBHARD)
+/*
+ * These timers can only be set in super user's dquot. For others, timers are
+ * automatically started and stopped. Superusers timer values set the limits
+ * for the rest. In case these values are zero, the DQ_{F,B}TIMELIMIT values
+ * defined below are used.
+ * These values also apply only to the d_fieldmask field for Q_XSETQLIM.
+ */
+#define FS_DQ_BTIMER (1<<6)
+#define FS_DQ_ITIMER (1<<7)
+#define FS_DQ_RTBTIMER (1<<8)
+#define FS_DQ_TIMER_MASK (FS_DQ_BTIMER | FS_DQ_ITIMER | FS_DQ_RTBTIMER)
+
+/*
+ * The following constants define the default amount of time given a user
+ * before the soft limits are treated as hard limits (usually resulting
+ * in an allocation failure). These may be modified by the quotactl(2)
+ * system call with the Q_XSETQLIM command.
+ */
+#define DQ_FTIMELIMIT (7 * 24*60*60) /* 1 week */
+#define DQ_BTIMELIMIT (7 * 24*60*60) /* 1 week */
+
+/*
+ * Various flags related to quotactl(2). Only relevant to XFS filesystems.
+ */
+#define XFS_QUOTA_UDQ_ACCT (1<<0) /* user quota accounting */
+#define XFS_QUOTA_UDQ_ENFD (1<<1) /* user quota limits enforcement */
+#define XFS_QUOTA_GDQ_ACCT (1<<2) /* group quota accounting */
+#define XFS_QUOTA_GDQ_ENFD (1<<3) /* group quota limits enforcement */
+
+#define XFS_USER_QUOTA (1<<0) /* user quota type */
+#define XFS_PROJ_QUOTA (1<<1) /* (IRIX) project quota type */
+#define XFS_GROUP_QUOTA (1<<2) /* group quota type */
+
+/*
+ * fs_quota_stat is the struct returned in Q_XGETQSTAT for a given file system.
+ * Provides a centralized way to get meta infomation about the quota subsystem.
+ * eg. space taken up for user and group quotas, number of dquots currently
+ * incore.
+ */
+#define FS_QSTAT_VERSION 1 /* fs_quota_stat.qs_version */
+
+/*
+ * Some basic infomation about 'quota files'.
+ */
+typedef struct fs_qfilestat {
+ __u64 qfs_ino; /* inode number */
+ __u64 qfs_nblks; /* number of BBs 512-byte-blks */
+ __u32 qfs_nextents; /* number of extents */
+} fs_qfilestat_t;
+
+typedef struct fs_quota_stat {
+ __s8 qs_version; /* version number for future changes */
+ __u16 qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
+ __s8 qs_pad; /* unused */
+ fs_qfilestat_t qs_uquota; /* user quota storage information */
+ fs_qfilestat_t qs_gquota; /* group quota storage information */
+ __u32 qs_incoredqs; /* number of dquots incore */
+ __s32 qs_btimelimit; /* limit for blks timer */
+ __s32 qs_itimelimit; /* limit for inodes timer */
+ __s32 qs_rtbtimelimit;/* limit for rt blks timer */
+ __u16 qs_bwarnlimit; /* limit for num warnings */
+ __u16 qs_iwarnlimit; /* limit for num warnings */
+} fs_quota_stat_t;
+
+#endif /* _LINUX_XQM_H */