OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [quota_v1.c] - Blame information for rev 81

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
#include <linux/errno.h>
2
#include <linux/fs.h>
3
#include <linux/quota.h>
4
#include <linux/dqblk_v1.h>
5
#include <linux/quotaio_v1.h>
6
#include <linux/kernel.h>
7
#include <linux/init.h>
8
#include <linux/module.h>
9
 
10
#include <asm/byteorder.h>
11
 
12
MODULE_AUTHOR("Jan Kara");
13
MODULE_DESCRIPTION("Old quota format support");
14
MODULE_LICENSE("GPL");
15
 
16
static void v1_disk2mem_dqblk(struct mem_dqblk *m, struct v1_disk_dqblk *d)
17
{
18
        m->dqb_ihardlimit = d->dqb_ihardlimit;
19
        m->dqb_isoftlimit = d->dqb_isoftlimit;
20
        m->dqb_curinodes = d->dqb_curinodes;
21
        m->dqb_bhardlimit = d->dqb_bhardlimit;
22
        m->dqb_bsoftlimit = d->dqb_bsoftlimit;
23
        m->dqb_curspace = ((qsize_t)d->dqb_curblocks) << QUOTABLOCK_BITS;
24
        m->dqb_itime = d->dqb_itime;
25
        m->dqb_btime = d->dqb_btime;
26
}
27
 
28
static void v1_mem2disk_dqblk(struct v1_disk_dqblk *d, struct mem_dqblk *m)
29
{
30
        d->dqb_ihardlimit = m->dqb_ihardlimit;
31
        d->dqb_isoftlimit = m->dqb_isoftlimit;
32
        d->dqb_curinodes = m->dqb_curinodes;
33
        d->dqb_bhardlimit = m->dqb_bhardlimit;
34
        d->dqb_bsoftlimit = m->dqb_bsoftlimit;
35
        d->dqb_curblocks = toqb(m->dqb_curspace);
36
        d->dqb_itime = m->dqb_itime;
37
        d->dqb_btime = m->dqb_btime;
38
}
39
 
40
static int v1_read_dqblk(struct dquot *dquot)
41
{
42
        int type = dquot->dq_type;
43
        struct v1_disk_dqblk dqblk;
44
 
45
        if (!sb_dqopt(dquot->dq_sb)->files[type])
46
                return -EINVAL;
47
 
48
        /* Set structure to 0s in case read fails/is after end of file */
49
        memset(&dqblk, 0, sizeof(struct v1_disk_dqblk));
50
        dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
51
 
52
        v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk);
53
        if (dquot->dq_dqb.dqb_bhardlimit == 0 && dquot->dq_dqb.dqb_bsoftlimit == 0 &&
54
            dquot->dq_dqb.dqb_ihardlimit == 0 && dquot->dq_dqb.dqb_isoftlimit == 0)
55
                set_bit(DQ_FAKE_B, &dquot->dq_flags);
56
        dqstats.reads++;
57
 
58
        return 0;
59
}
60
 
61
static int v1_commit_dqblk(struct dquot *dquot)
62
{
63
        short type = dquot->dq_type;
64
        ssize_t ret;
65
        struct v1_disk_dqblk dqblk;
66
 
67
        v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb);
68
        if (dquot->dq_id == 0) {
69
                dqblk.dqb_btime = sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace;
70
                dqblk.dqb_itime = sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace;
71
        }
72
        ret = 0;
73
        if (sb_dqopt(dquot->dq_sb)->files[type])
74
                ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, (char *)&dqblk,
75
                                        sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
76
        if (ret != sizeof(struct v1_disk_dqblk)) {
77
                printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
78
                        dquot->dq_sb->s_id);
79
                if (ret >= 0)
80
                        ret = -EIO;
81
                goto out;
82
        }
83
        ret = 0;
84
 
85
out:
86
        dqstats.writes++;
87
 
88
        return ret;
89
}
90
 
91
/* Magics of new quota format */
92
#define V2_INITQMAGICS {\
93
        0xd9c01f11,     /* USRQUOTA */\
94
        0xd9c01927      /* GRPQUOTA */\
95
}
96
 
97
/* Header of new quota format */
98
struct v2_disk_dqheader {
99
        __le32 dqh_magic;        /* Magic number identifying file */
100
        __le32 dqh_version;      /* File version */
101
};
102
 
103
static int v1_check_quota_file(struct super_block *sb, int type)
104
{
105
        struct inode *inode = sb_dqopt(sb)->files[type];
106
        ulong blocks;
107
        size_t off;
108
        struct v2_disk_dqheader dqhead;
109
        ssize_t size;
110
        loff_t isize;
111
        static const uint quota_magics[] = V2_INITQMAGICS;
112
 
113
        isize = i_size_read(inode);
114
        if (!isize)
115
                return 0;
116
        blocks = isize >> BLOCK_SIZE_BITS;
117
        off = isize & (BLOCK_SIZE - 1);
118
        if ((blocks % sizeof(struct v1_disk_dqblk) * BLOCK_SIZE + off) % sizeof(struct v1_disk_dqblk))
119
                return 0;
120
        /* Doublecheck whether we didn't get file with new format - with old quotactl() this could happen */
121
        size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
122
        if (size != sizeof(struct v2_disk_dqheader))
123
                return 1;       /* Probably not new format */
124
        if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type])
125
                return 1;       /* Definitely not new format */
126
        printk(KERN_INFO "VFS: %s: Refusing to turn on old quota format on given file. It probably contains newer quota format.\n", sb->s_id);
127
        return 0;                /* Seems like a new format file -> refuse it */
128
}
129
 
130
static int v1_read_file_info(struct super_block *sb, int type)
131
{
132
        struct quota_info *dqopt = sb_dqopt(sb);
133
        struct v1_disk_dqblk dqblk;
134
        int ret;
135
 
136
        if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
137
                if (ret >= 0)
138
                        ret = -EIO;
139
                goto out;
140
        }
141
        ret = 0;
142
        dqopt->info[type].dqi_igrace = dqblk.dqb_itime ? dqblk.dqb_itime : MAX_IQ_TIME;
143
        dqopt->info[type].dqi_bgrace = dqblk.dqb_btime ? dqblk.dqb_btime : MAX_DQ_TIME;
144
out:
145
        return ret;
146
}
147
 
148
static int v1_write_file_info(struct super_block *sb, int type)
149
{
150
        struct quota_info *dqopt = sb_dqopt(sb);
151
        struct v1_disk_dqblk dqblk;
152
        int ret;
153
 
154
        dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY;
155
        if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk,
156
            sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
157
                if (ret >= 0)
158
                        ret = -EIO;
159
                goto out;
160
        }
161
        dqblk.dqb_itime = dqopt->info[type].dqi_igrace;
162
        dqblk.dqb_btime = dqopt->info[type].dqi_bgrace;
163
        ret = sb->s_op->quota_write(sb, type, (char *)&dqblk,
164
              sizeof(struct v1_disk_dqblk), v1_dqoff(0));
165
        if (ret == sizeof(struct v1_disk_dqblk))
166
                ret = 0;
167
        else if (ret > 0)
168
                ret = -EIO;
169
out:
170
        return ret;
171
}
172
 
173
static struct quota_format_ops v1_format_ops = {
174
        .check_quota_file       = v1_check_quota_file,
175
        .read_file_info         = v1_read_file_info,
176
        .write_file_info        = v1_write_file_info,
177
        .free_file_info         = NULL,
178
        .read_dqblk             = v1_read_dqblk,
179
        .commit_dqblk           = v1_commit_dqblk,
180
};
181
 
182
static struct quota_format_type v1_quota_format = {
183
        .qf_fmt_id      = QFMT_VFS_OLD,
184
        .qf_ops         = &v1_format_ops,
185
        .qf_owner       = THIS_MODULE
186
};
187
 
188
static int __init init_v1_quota_format(void)
189
{
190
        return register_quota_format(&v1_quota_format);
191
}
192
 
193
static void __exit exit_v1_quota_format(void)
194
{
195
        unregister_quota_format(&v1_quota_format);
196
}
197
 
198
module_init(init_v1_quota_format);
199
module_exit(exit_v1_quota_format);
200
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.