Commit 48c39f24 authored by Jan Kara's avatar Jan Kara Committed by Linus Torvalds

[PATCH] [3/13] quota-3-register

  This patch implements list 'quota_formats' with registered quota formats
and functions register_quota_format() and unregister_quota_format() for
manipulating the list.
parent b80d2549
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
O_TARGET := fs.o 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 mod-subdirs := nls
obj-y := open.o read_write.o devices.o file_table.o buffer.o \ obj-y := open.o read_write.o devices.o file_table.o buffer.o \
......
...@@ -70,10 +70,36 @@ ...@@ -70,10 +70,36 @@
int nr_dquots, nr_free_dquots; int nr_dquots, nr_free_dquots;
static char *quotatypes[] = INITQFNAMES; 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) ...@@ -1237,6 +1263,8 @@ int quota_off(struct super_block *sb, short type)
invalidate_dquots(sb, cnt); invalidate_dquots(sb, cnt);
if (info_dirty(&dqopt->info[cnt])) if (info_dirty(&dqopt->info[cnt]))
dqopt->ops[cnt]->write_file_info(sb, 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]; filp = dqopt->files[cnt];
dqopt->files[cnt] = (struct file *)NULL; dqopt->files[cnt] = (struct file *)NULL;
...@@ -1252,30 +1280,27 @@ int quota_off(struct super_block *sb, short type) ...@@ -1252,30 +1280,27 @@ int quota_off(struct super_block *sb, short type)
return 0; 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 file *f;
struct inode *inode; struct inode *inode;
struct dquot *dquot;
struct quota_info *dqopt = sb_dqopt(sb); struct quota_info *dqopt = sb_dqopt(sb);
char *tmp; struct quota_format_type *fmt = find_quota_format(format_id);
int error; int error;
if (!fmt)
return -EINVAL;
if (is_enabled(dqopt, type)) if (is_enabled(dqopt, type))
return -EBUSY; return -EBUSY;
down(&dqopt->dqoff_sem); 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); f = filp_open(path, O_RDWR, 0600);
putname(tmp);
error = PTR_ERR(f); error = PTR_ERR(f);
if (IS_ERR(f)) if (IS_ERR(f))
goto out_lock; goto out_lock;
dqopt->files[type] = f;
error = -EIO; error = -EIO;
if (!f->f_op || !f->f_op->read || !f->f_op->write) if (!f->f_op || !f->f_op->read || !f->f_op->write)
goto out_f; goto out_f;
...@@ -1284,13 +1309,16 @@ static int quota_on(struct super_block *sb, short type, char *path) ...@@ -1284,13 +1309,16 @@ static int quota_on(struct super_block *sb, short type, char *path)
if (!S_ISREG(inode->i_mode)) if (!S_ISREG(inode->i_mode))
goto out_f; goto out_f;
error = -EINVAL; error = -EINVAL;
if (!check_quota_file(sb, type)) if (!fmt->qf_ops->check_quota_file(sb, type))
goto out_f; goto out_f;
/* We don't want quota on quota files */ /* We don't want quota on quota files */
dquot_drop(inode); dquot_drop(inode);
inode->i_flags |= S_NOQUOTA; 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; sb->dq_op = &dquot_operations;
set_enable_flags(dqopt, type); set_enable_flags(dqopt, type);
...@@ -1301,6 +1329,7 @@ static int quota_on(struct super_block *sb, short type, char *path) ...@@ -1301,6 +1329,7 @@ static int quota_on(struct super_block *sb, short type, char *path)
out_f: out_f:
filp_close(f, NULL); filp_close(f, NULL);
dqopt->files[type] = NULL;
out_lock: out_lock:
up(&dqopt->dqoff_sem); up(&dqopt->dqoff_sem);
......
...@@ -42,9 +42,6 @@ ...@@ -42,9 +42,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/types.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 */ typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */
/* /*
...@@ -116,7 +113,10 @@ struct mem_dqblk { ...@@ -116,7 +113,10 @@ struct mem_dqblk {
/* /*
* Data for one quotafile kept in memory * Data for one quotafile kept in memory
*/ */
struct quota_format_type;
struct mem_dqinfo { struct mem_dqinfo {
struct quota_format_type *dqi_format;
int dqi_flags; int dqi_flags;
unsigned int dqi_bgrace; unsigned int dqi_bgrace;
unsigned int dqi_igrace; unsigned int dqi_igrace;
...@@ -157,7 +157,6 @@ extern inline void mark_info_dirty(struct mem_dqinfo *info) ...@@ -157,7 +157,6 @@ extern inline void mark_info_dirty(struct mem_dqinfo *info)
#ifdef __KERNEL__ #ifdef __KERNEL__
extern int nr_dquots, nr_free_dquots; extern int nr_dquots, nr_free_dquots;
extern int dquot_root_squash;
struct dqstats { struct dqstats {
__u32 lookups; __u32 lookups;
...@@ -170,6 +169,8 @@ struct dqstats { ...@@ -170,6 +169,8 @@ struct dqstats {
__u32 syncs; __u32 syncs;
}; };
extern struct dqstats dqstats;
#define NR_DQHASH 43 /* Just an arbitrary number */ #define NR_DQHASH 43 /* Just an arbitrary number */
#define DQ_LOCKED 0x01 /* dquot under IO */ #define DQ_LOCKED 0x01 /* dquot under IO */
...@@ -220,6 +221,12 @@ struct quota_format_ops { ...@@ -220,6 +221,12 @@ struct quota_format_ops {
int (*commit_dqblk)(struct dquot *dquot); /* Write (or delete) structure for one user */ 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 #else
# /* nodep */ include <sys/cdefs.h> # /* nodep */ include <sys/cdefs.h>
......
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