1/*
2 * Definitions for diskquota-operations. When diskquota is configured these
3 * macros expand to the right source-code.
4 *
5 * Author:  Marco van Wieringen <mvw@planets.elm.net>
6 *
7 * Version: $Id: quotaops.h,v 1.1.1.1 2008/10/15 03:29:27 james26_jang Exp $
8 *
9 */
10#ifndef _LINUX_QUOTAOPS_
11#define _LINUX_QUOTAOPS_
12
13#include <linux/config.h>
14#include <linux/smp_lock.h>
15
16#if defined(CONFIG_QUOTA)
17
18#include <linux/fs.h>
19
20/*
21 * declaration of quota_function calls in kernel.
22 */
23extern void dquot_initialize(struct inode *inode, short type);
24extern void dquot_drop(struct inode *inode);
25extern int  quota_off(struct super_block *sb, short type);
26extern int  sync_dquots(kdev_t dev, short type);
27
28extern int  dquot_alloc_block(struct inode *inode, unsigned long number, char prealloc);
29extern int  dquot_alloc_inode(const struct inode *inode, unsigned long number);
30
31extern void dquot_free_block(struct inode *inode, unsigned long number);
32extern void dquot_free_inode(const struct inode *inode, unsigned long number);
33
34extern int  dquot_transfer(struct inode *inode, struct iattr *iattr);
35
36/*
37 * Operations supported for diskquotas.
38 */
39#define sb_any_quota_enabled(sb) ((sb)->s_dquot.flags & (DQUOT_USR_ENABLED | DQUOT_GRP_ENABLED))
40
41static __inline__ void DQUOT_INIT(struct inode *inode)
42{
43	if (!inode->i_sb)
44		out_of_line_bug();
45	lock_kernel();
46	if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode))
47		inode->i_sb->dq_op->initialize(inode, -1);
48	unlock_kernel();
49}
50
51static __inline__ void DQUOT_DROP(struct inode *inode)
52{
53	lock_kernel();
54	if (IS_QUOTAINIT(inode)) {
55		if (!inode->i_sb)
56			out_of_line_bug();
57		inode->i_sb->dq_op->drop(inode);	/* Ops must be set when there's any quota... */
58	}
59	unlock_kernel();
60}
61
62static __inline__ int DQUOT_PREALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
63{
64	lock_kernel();
65	if (sb_any_quota_enabled(inode->i_sb)) {
66		/* Number of used blocks is updated in alloc_block() */
67		if (inode->i_sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize), 1) == NO_QUOTA) {
68			unlock_kernel();
69			return 1;
70		}
71	}
72	else
73		inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
74	unlock_kernel();
75	return 0;
76}
77
78static __inline__ int DQUOT_PREALLOC_BLOCK(struct inode *inode, int nr)
79{
80	int ret;
81        if (!(ret =  DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr)))
82		mark_inode_dirty(inode);
83	return ret;
84}
85
86static __inline__ int DQUOT_ALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
87{
88	lock_kernel();
89	if (sb_any_quota_enabled(inode->i_sb)) {
90		/* Number of used blocks is updated in alloc_block() */
91		if (inode->i_sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize), 0) == NO_QUOTA) {
92			unlock_kernel();
93			return 1;
94		}
95	}
96	else
97		inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
98	unlock_kernel();
99	return 0;
100}
101
102static __inline__ int DQUOT_ALLOC_BLOCK(struct inode *inode, int nr)
103{
104	int ret;
105	if (!(ret = DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr)))
106		mark_inode_dirty(inode);
107	return ret;
108}
109
110static __inline__ int DQUOT_ALLOC_INODE(struct inode *inode)
111{
112	lock_kernel();
113	if (sb_any_quota_enabled(inode->i_sb)) {
114		DQUOT_INIT(inode);
115		if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) {
116			unlock_kernel();
117			return 1;
118		}
119	}
120	unlock_kernel();
121	return 0;
122}
123
124static __inline__ void DQUOT_FREE_BLOCK_NODIRTY(struct inode *inode, int nr)
125{
126	lock_kernel();
127	if (sb_any_quota_enabled(inode->i_sb))
128		inode->i_sb->dq_op->free_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize));
129	else
130		inode->i_blocks -= nr << (inode->i_sb->s_blocksize_bits - 9);
131	unlock_kernel();
132}
133
134static __inline__ void DQUOT_FREE_BLOCK(struct inode *inode, int nr)
135{
136	DQUOT_FREE_BLOCK_NODIRTY(inode, nr);
137	mark_inode_dirty(inode);
138}
139
140static __inline__ void DQUOT_FREE_INODE(struct inode *inode)
141{
142	lock_kernel();
143	if (sb_any_quota_enabled(inode->i_sb))
144		inode->i_sb->dq_op->free_inode(inode, 1);
145	unlock_kernel();
146}
147
148static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr)
149{
150	lock_kernel();
151	if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) {
152		DQUOT_INIT(inode);
153		if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA) {
154			unlock_kernel();
155			return 1;
156		}
157	}
158	unlock_kernel();
159	return 0;
160}
161
162#define DQUOT_SYNC(dev)	sync_dquots(dev, -1)
163#define DQUOT_OFF(sb)	quota_off(sb, -1)
164
165#else
166
167/*
168 * NO-OP when quota not configured.
169 */
170#define DQUOT_INIT(inode)			do { } while(0)
171#define DQUOT_DROP(inode)			do { } while(0)
172#define DQUOT_ALLOC_INODE(inode)		(0)
173#define DQUOT_FREE_INODE(inode)			do { } while(0)
174#define DQUOT_SYNC(dev)				do { } while(0)
175#define DQUOT_OFF(sb)				do { } while(0)
176#define DQUOT_TRANSFER(inode, iattr)		(0)
177extern __inline__ int DQUOT_PREALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
178{
179	lock_kernel();
180	inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
181	unlock_kernel();
182	return 0;
183}
184
185extern __inline__ int DQUOT_PREALLOC_BLOCK(struct inode *inode, int nr)
186{
187	DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr);
188	mark_inode_dirty(inode);
189	return 0;
190}
191
192extern __inline__ int DQUOT_ALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
193{
194	lock_kernel();
195	inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
196	unlock_kernel();
197	return 0;
198}
199
200extern __inline__ int DQUOT_ALLOC_BLOCK(struct inode *inode, int nr)
201{
202	DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr);
203	mark_inode_dirty(inode);
204	return 0;
205}
206
207extern __inline__ void DQUOT_FREE_BLOCK_NODIRTY(struct inode *inode, int nr)
208{
209	lock_kernel();
210	inode->i_blocks -= nr << (inode->i_sb->s_blocksize_bits - 9);
211	unlock_kernel();
212}
213
214extern __inline__ void DQUOT_FREE_BLOCK(struct inode *inode, int nr)
215{
216	DQUOT_FREE_BLOCK_NODIRTY(inode, nr);
217	mark_inode_dirty(inode);
218}
219
220#endif /* CONFIG_QUOTA */
221#endif /* _LINUX_QUOTAOPS_ */
222