]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] [3/13] quota-3-register
authorJan Kara <jack@suse.cz>
Mon, 20 May 2002 02:34:00 +0000 (19:34 -0700)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Mon, 20 May 2002 02:34:00 +0000 (19:34 -0700)
  This patch implements list 'quota_formats' with registered quota formats
and functions register_quota_format() and unregister_quota_format() for
manipulating the list.

fs/Makefile
fs/dquot.c
include/linux/quota.h

index 2449b05e367ab5e5c7da8fe34bf140889b300262..83769de6e2e4f3d864520f7de082312cfbebc1d2 100644 (file)
@@ -7,7 +7,7 @@
 
 O_TARGET := fs.o
 
-export-objs := filesystems.o open.o dcache.o buffer.o bio.o
+export-objs := filesystems.o open.o dcache.o buffer.o bio.o dquot.o
 mod-subdirs := nls
 
 obj-y :=       open.o read_write.o devices.o file_table.o buffer.o \
index 55245e75b2d988b67201a0356e07e8c7eb2e6b6a..f4d8fbe1c165f8fb8cd26ae0ad17fe2ba6d5f2d3 100644 (file)
 int nr_dquots, nr_free_dquots;
 
 static char *quotatypes[] = INITQFNAMES;
+static struct quota_format_type *quota_formats;        /* List of registered formats */
 
-static inline struct quota_info *sb_dqopt(struct super_block *sb)
+int register_quota_format(struct quota_format_type *fmt)
 {
-       return &sb->s_dquot;
+       lock_kernel();
+       fmt->qf_next = quota_formats;
+       quota_formats = fmt;
+       unlock_kernel();
+       return 0;
+}
+
+void unregister_quota_format(struct quota_format_type *fmt)
+{
+       struct quota_format_type **actqf;
+
+       lock_kernel();
+       for (actqf = &quota_formats; *actqf && *actqf != fmt; actqf = &(*actqf)->qf_next);
+       if (*actqf)
+               *actqf = (*actqf)->qf_next;
+       unlock_kernel();
+}
+
+static struct quota_format_type *find_quota_format(int id)
+{
+       struct quota_format_type *actqf;
+
+       lock_kernel();
+       for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next);
+       unlock_kernel();
+       return actqf;
 }
 
 /*
@@ -1237,6 +1263,8 @@ int quota_off(struct super_block *sb, short type)
                invalidate_dquots(sb, cnt);
                 if (info_dirty(&dqopt->info[cnt]))
                         dqopt->ops[cnt]->write_file_info(sb, cnt);
+               if (dqopt->ops[cnt]->free_file_info)
+                       dqopt->ops[cnt]->free_file_info(sb, cnt);
 
                filp = dqopt->files[cnt];
                dqopt->files[cnt] = (struct file *)NULL;
@@ -1252,30 +1280,27 @@ out:
        return 0;
 }
 
-static int quota_on(struct super_block *sb, short type, char *path)
+static int quota_on(struct super_block *sb, int type, int format_id, char *path)
 {
        struct file *f;
        struct inode *inode;
-       struct dquot *dquot;
        struct quota_info *dqopt = sb_dqopt(sb);
-       char *tmp;
+       struct quota_format_type *fmt = find_quota_format(format_id);
        int error;
 
+       if (!fmt)
+               return -EINVAL;
        if (is_enabled(dqopt, type))
                return -EBUSY;
 
        down(&dqopt->dqoff_sem);
-       tmp = getname(path);
-       error = PTR_ERR(tmp);
-       if (IS_ERR(tmp))
-               goto out_lock;
 
-       f = filp_open(tmp, O_RDWR, 0600);
-       putname(tmp);
+       f = filp_open(path, O_RDWR, 0600);
 
        error = PTR_ERR(f);
        if (IS_ERR(f))
                goto out_lock;
+       dqopt->files[type] = f;
        error = -EIO;
        if (!f->f_op || !f->f_op->read || !f->f_op->write)
                goto out_f;
@@ -1284,13 +1309,16 @@ static int quota_on(struct super_block *sb, short type, char *path)
        if (!S_ISREG(inode->i_mode))
                goto out_f;
        error = -EINVAL;
-       if (!check_quota_file(sb, type))
+       if (!fmt->qf_ops->check_quota_file(sb, type))
                goto out_f;
        /* We don't want quota on quota files */
        dquot_drop(inode);
        inode->i_flags |= S_NOQUOTA;
 
-       dqopt->files[type] = f;
+       dqopt->ops[type] = fmt->qf_ops;
+       dqopt->info[type].dqi_format = format_id;
+       if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0)
+               goto out_f;
        sb->dq_op = &dquot_operations;
        set_enable_flags(dqopt, type);
 
@@ -1301,6 +1329,7 @@ static int quota_on(struct super_block *sb, short type, char *path)
 
 out_f:
        filp_close(f, NULL);
+       dqopt->files[type] = NULL;
 out_lock:
        up(&dqopt->dqoff_sem);
 
index 820b561ba086e6870af7799e8b3fc95c1075fea7..c6f1eacb9bc23cab464e8e32df56912d7b92684b 100644 (file)
@@ -42,9 +42,6 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 
-#define __DQUOT_VERSION__      "dquot_6.5.1"
-#define __DQUOT_NUM_VERSION__  6*10000+5*100+1
-
 typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */
 
 /*
@@ -116,7 +113,10 @@ struct mem_dqblk {
 /*
  * Data for one quotafile kept in memory
  */
+struct quota_format_type;
+
 struct mem_dqinfo {
+       struct quota_format_type *dqi_format;
        int dqi_flags;
        unsigned int dqi_bgrace;
        unsigned int dqi_igrace;
@@ -157,7 +157,6 @@ extern inline void mark_info_dirty(struct mem_dqinfo *info)
 #ifdef __KERNEL__
 
 extern int nr_dquots, nr_free_dquots;
-extern int dquot_root_squash;
 
 struct dqstats {
        __u32 lookups;
@@ -170,6 +169,8 @@ struct dqstats {
        __u32 syncs;
 };
 
+extern struct dqstats dqstats;
+
 #define NR_DQHASH 43            /* Just an arbitrary number */
 
 #define DQ_LOCKED     0x01     /* dquot under IO */
@@ -220,6 +221,12 @@ struct quota_format_ops {
        int (*commit_dqblk)(struct dquot *dquot);       /* Write (or delete) structure for one user */
 };
 
+struct quota_format_type {
+       int qf_fmt_id;  /* Quota format id */
+       struct quota_format_ops *qf_ops;        /* Operations of format */
+       struct quota_format_type *qf_next;
+};
+
 #else
 
 # /* nodep */ include <sys/cdefs.h>