Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
[safe/jmp/linux-2.6] / include / linux / quota.h
index 6d98885..7126a15 100644 (file)
@@ -36,8 +36,7 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 
-#define __DQUOT_VERSION__      "dquot_6.5.1"
-#define __DQUOT_NUM_VERSION__  6*10000+5*100+1
+#define __DQUOT_VERSION__      "dquot_6.5.2"
 
 #define MAXQUOTAS 2
 #define USRQUOTA  0            /* element used for user quotas */
 #define Q_GETQUOTA 0x800007    /* get user quota structure */
 #define Q_SETQUOTA 0x800008    /* set user quota structure */
 
+/* Quota format type IDs */
+#define        QFMT_VFS_OLD 1
+#define        QFMT_VFS_V0 2
+#define QFMT_OCFS2 3
+#define        QFMT_VFS_V1 4
+
 /* Size of block in which space limits are passed through the quota
  * interface */
 #define QIF_DQBLKSIZE_BITS 10
@@ -169,6 +174,8 @@ enum {
 #include <linux/rwsem.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
+#include <linux/percpu.h>
+#include <linux/smp.h>
 
 #include <linux/dqblk_xfs.h>
 #include <linux/dqblk_v1.h>
@@ -195,6 +202,7 @@ struct mem_dqblk {
        qsize_t dqb_bhardlimit; /* absolute limit on disk blks alloc */
        qsize_t dqb_bsoftlimit; /* preferred limit on disk blks */
        qsize_t dqb_curspace;   /* current used space */
+       qsize_t dqb_rsvspace;   /* current reserved space for delalloc*/
        qsize_t dqb_ihardlimit; /* absolute limit on allocated inodes */
        qsize_t dqb_isoftlimit; /* preferred inode limit */
        qsize_t dqb_curinodes;  /* current # allocated inodes */
@@ -232,19 +240,43 @@ static inline int info_dirty(struct mem_dqinfo *info)
        return test_bit(DQF_INFO_DIRTY_B, &info->dqi_flags);
 }
 
+enum {
+       DQST_LOOKUPS,
+       DQST_DROPS,
+       DQST_READS,
+       DQST_WRITES,
+       DQST_CACHE_HITS,
+       DQST_ALLOC_DQUOTS,
+       DQST_FREE_DQUOTS,
+       DQST_SYNCS,
+       _DQST_DQSTAT_LAST
+};
+
 struct dqstats {
-       int lookups;
-       int drops;
-       int reads;
-       int writes;
-       int cache_hits;
-       int allocated_dquots;
-       int free_dquots;
-       int syncs;
+       int stat[_DQST_DQSTAT_LAST];
 };
 
+extern struct dqstats *dqstats_pcpu;
 extern struct dqstats dqstats;
 
+static inline void dqstats_inc(unsigned int type)
+{
+#ifdef CONFIG_SMP
+       per_cpu_ptr(dqstats_pcpu, smp_processor_id())->stat[type]++;
+#else
+       dqstats.stat[type]++;
+#endif
+}
+
+static inline void dqstats_dec(unsigned int type)
+{
+#ifdef CONFIG_SMP
+       per_cpu_ptr(dqstats_pcpu, smp_processor_id())->stat[type]--;
+#else
+       dqstats.stat[type]--;
+#endif
+}
+
 #define DQ_MOD_B       0       /* dquot modified since read */
 #define DQ_BLKS_B      1       /* uid/gid has been warned about blk limit */
 #define DQ_INODES_B    2       /* uid/gid has been warned about inode limit */
@@ -273,11 +305,6 @@ struct dquot {
        struct mem_dqblk dq_dqb;        /* Diskquota usage */
 };
 
-#define NODQUOT (struct dquot *)NULL
-
-#define QUOTA_OK          0
-#define NO_QUOTA          1
-
 /* 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 */
@@ -291,13 +318,6 @@ struct quota_format_ops {
 
 /* Operations working with dquots */
 struct dquot_operations {
-       int (*initialize) (struct inode *, int);
-       int (*drop) (struct inode *);
-       int (*alloc_space) (struct inode *, qsize_t, int);
-       int (*alloc_inode) (const struct inode *, qsize_t);
-       int (*free_space) (struct inode *, qsize_t);
-       int (*free_inode) (const struct inode *, qsize_t);
-       int (*transfer) (struct inode *, struct iattr *);
        int (*write_dquot) (struct dquot *);            /* Ordinary dquot write */
        struct dquot *(*alloc_dquot)(struct super_block *, int);        /* Allocate memory for new dquot */
        void (*destroy_dquot)(struct dquot *);          /* Free memory for dquot */
@@ -305,26 +325,27 @@ struct dquot_operations {
        int (*release_dquot) (struct dquot *);          /* Quota is going to be deleted from disk */
        int (*mark_dirty) (struct dquot *);             /* Dquot is marked dirty */
        int (*write_info) (struct super_block *, int);  /* Write of quota "superblock" */
+       /* get reserved quota for delayed alloc, value returned is managed by
+        * quota code only */
+       qsize_t *(*get_reserved_space) (struct inode *);
 };
 
 /* Operations handling requests from userspace */
 struct quotactl_ops {
        int (*quota_on)(struct super_block *, int, int, char *, int);
        int (*quota_off)(struct super_block *, int, int);
-       int (*quota_sync)(struct super_block *, int);
+       int (*quota_sync)(struct super_block *, int, 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_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *);
+       int (*set_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *);
        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 */
+       const struct quota_format_ops *qf_ops;  /* Operations of format */
        struct module *qf_owner;                /* Module implementing quota format */
        struct quota_format_type *qf_next;
 };
@@ -344,27 +365,37 @@ enum {
 #define DQUOT_STATE_FLAGS      (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \
                                 DQUOT_SUSPENDED)
 /* Other quota flags */
-#define DQUOT_QUOTA_SYS_FILE   (1 << 6)        /* Quota file is a special
+#define DQUOT_STATE_LAST       (_DQUOT_STATE_FLAGS * MAXQUOTAS)
+#define DQUOT_QUOTA_SYS_FILE   (1 << DQUOT_STATE_LAST)
+                                               /* Quota file is a special
                                                 * system file and user cannot
                                                 * touch it. Filesystem is
                                                 * responsible for setting
                                                 * S_NOQUOTA, S_NOATIME flags
                                                 */
-#define DQUOT_NEGATIVE_USAGE   (1 << 7)        /* Allow negative quota usage */
+#define DQUOT_NEGATIVE_USAGE   (1 << (DQUOT_STATE_LAST + 1))
+                                              /* Allow negative quota usage */
 
 static inline unsigned int dquot_state_flag(unsigned int flags, int type)
 {
-       if (type == USRQUOTA)
-               return flags;
-       return flags << _DQUOT_STATE_FLAGS;
+       return flags << _DQUOT_STATE_FLAGS * type;
 }
 
 static inline unsigned int dquot_generic_flag(unsigned int flags, int type)
 {
-       if (type == USRQUOTA)
-               return flags;
-       return flags >> _DQUOT_STATE_FLAGS;
+       return (flags >> _DQUOT_STATE_FLAGS * type) & DQUOT_STATE_FLAGS;
+}
+
+#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
+extern void quota_send_warning(short type, unsigned int id, dev_t dev,
+                              const char warntype);
+#else
+static inline void quota_send_warning(short type, unsigned int id, dev_t dev,
+                                     const char warntype)
+{
+       return;
 }
+#endif /* CONFIG_QUOTA_NETLINK_INTERFACE */
 
 struct quota_info {
        unsigned int flags;                     /* Flags for diskquotas on this device */
@@ -373,7 +404,7 @@ struct quota_info {
        struct rw_semaphore dqptr_sem;          /* serialize ops using quota_info struct, pointers from inode to dquots */
        struct inode *files[MAXQUOTAS];         /* inodes of quotafiles */
        struct mem_dqinfo info[MAXQUOTAS];      /* Information for each quota type */
-       struct quota_format_ops *ops[MAXQUOTAS];        /* Operations for each type */
+       const struct quota_format_ops *ops[MAXQUOTAS];  /* Operations for each type */
 };
 
 int register_quota_format(struct quota_format_type *fmt);