/*
 * Copyright (c) 1982, 1986 Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Robert Elz at The University of Melbourne.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *   This product includes software developed by the University of
 *   California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Version: $Id: quota.h,v 1.2 1993/05/30 18:06:54 root Exp root $
 */

#ifndef _LINUX_QUOTA_
#define _LINUX_QUOTA_

#include <linux/errno.h>

/*
 * Convert diskblocks to blocks and the other way around.
 * currently only to fool the BSD source. :-)
 */
#define dbtob(num) (num << 10)
#define btodb(num) (num >> 10)

/*
 * Definitions for disk quotas imposed on the average user
 * (big brother finally hits UNIX).
 *
 * The following constants define the amount of time given a user
 * before the soft limits are treated as hard limits (usually resulting
 * in an allocation failure). The timer is started when the user crosses
 * their soft limit, it is reset when they go below their soft limit.
 */
#define MAX_IQ_TIME  604800 /* (7*24*60*60) 1 week */
#define MAX_DQ_TIME  604800 /* (7*24*60*60) 1 week */

#define MAXQUOTAS 2
#define USRQUOTA  0 /* element used for user quotas */
#define GRPQUOTA  1 /* element used for group quotas */

#define ID_NO_QUOTA 10 /* ids for which quota isn't enabled (<=)*/

/*
 * Definitions for the default names of the quotas files.
 */
#define INITQFNAMES { \
   "user",      /* USRQUOTA */ \
   "group",   /* GRPQUOTA */ \
   "undefined", \
};
#define QUOTAFILENAME "quota"
#define QUOTAGROUP "staff"

/*
 * Command definitions for the 'quotactl' system call.
 * The commands are broken into a main command defined below
 * and a subcommand that is used to convey the type of
 * quota that is being manipulated (see above).
 */
#define SUBCMDMASK  0x00ff
#define SUBCMDSHIFT 8
#define QCMD(cmd, type)  (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))

#define Q_QUOTAON  0x0100   /* enable quotas */
#define Q_QUOTAOFF 0x0200   /* disable quotas */
#define Q_GETQUOTA 0x0300   /* get limits and usage */
#define Q_SETQUOTA 0x0400   /* set limits and usage */
#define Q_SETUSE   0x0500   /* set usage */
#define Q_SYNC     0x0600   /* sync disk copy of a filesystems quotas */
#define Q_SETQLIM  0x0700   /* set limits */

/*
 * The following structure defines the format of the disk quota file
 * (as it appears on disk) - the file is an array of these structures
 * indexed by user or group number.
 */
struct dqblk {
   u_long dqb_bhardlimit;   /* absolute limit on disk blks alloc */
   u_long dqb_bsoftlimit;   /* preferred limit on disk blks */
   u_long dqb_curblocks;    /* current block count */
   u_long dqb_ihardlimit;   /* maximum # allocated inodes */
   u_long dqb_isoftlimit;   /* preferred inode limit */
   u_long dqb_curinodes;    /* current # allocated inodes */
   time_t dqb_btime;        /* time limit for excessive disk use */
   time_t dqb_itime;        /* time limit for excessive files */
};

#define dqoff(UID)      ((off_t)((UID) * sizeof (struct dqblk)))

#ifdef __KERNEL__
#include <linux/fs.h>

#define EDQUOT  EROFS      /* Need some useful errno.. */

struct device_list {
   dev_t               dq_dev;   /* device number */
   char                dq_dirt;  /* quotas are updated since last write */
   time_t              dq_iexp;  /* expiration time of inode softlimit */
   time_t              dq_bexp;  /* expiration time of block softlimit */
   struct file         dq_file;  /* filepointer to quotafile on the device */ 
   struct dquot       *dq_quota; /* list of ids with quota on this device */
   struct device_list *next;     /* pointer to next device */
};

#define DQ_LOCKED     0x01       /* locked for I/O */
#define DQ_WANT       0x02       /* wanted */
#define DQ_MOD        0x04       /* this quota modified since read */
#define DQ_BLKS       0x10       /* has been warned about blk limit */
#define DQ_INODES     0x20       /* has been warned about inode limit */
#define DQ_REMOVE     0x40       /* sync this dqblk and remove from list */

struct dquot {
   int                dq_id;     /* id this applies to (uid, gid) */
   short              dq_flags;  /* see DQ_* */
   struct dqblk       dq_dqb;    /* diskquota for id */
   struct wait_queue *dq_wait;   /* pointer to waitqueue */
   struct dquot      *next;      /* pointer to next id */
};

/*
 * Shorthand notation.
 */
#define	dq_bhardlimit	dq_dqb.dqb_bhardlimit
#define	dq_bsoftlimit	dq_dqb.dqb_bsoftlimit
#define	dq_curblocks	dq_dqb.dqb_curblocks
#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

/*
 * Flags used for set_dqblk.
 */
#define QUOTA_SYSCALL     0x01
#define SET_QUOTA         0x02
#define SET_USE           0x04
#define SET_QLIMIT        0x08

/*
 * Return values when requesting quota.
 */
#define NO_QUOTA 0  /* no more quota available */
#define QUOTA_OK 1  /* can allocate the space */

/*
 * declaration of quota_function calls in kernel.
 */
u_long isize_to_blocks(size_t isize, size_t blksize);
int    quota_alloc(dev_t dev, uid_t uid, gid_t gid, u_long inodes, u_long blocks);
int    quota_transfer(dev_t dev, uid_t olduid, uid_t newuid, gid_t oldgid, gid_t newgid,
                      u_long inodes, u_long blocks);
void   quota_remove(dev_t dev, uid_t uid, gid_t gid, u_long inodes, u_long blocks);
int    sync_quota(dev_t dev, int type);
int    quota_off(dev_t dev, int type);

#else

#include <sys/cdefs.h>

__BEGIN_DECLS
int   quotactl __P((int, const char *, int, caddr_t *));
__END_DECLS

#endif /* __KERNEL__ */
#endif /* _QUOTA_ */
