quotaops.h 7.7 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
/*
 * Definitions for diskquota-operations. When diskquota is configured these
 * macros expand to the right source-code.
 *
 * Author:  Marco van Wieringen <mvw@planets.elm.net>
 *
 * Version: $Id: quotaops.h,v 1.2 1998/01/15 16:22:26 ecd Exp $
 *
 */
#ifndef _LINUX_QUOTAOPS_
#define _LINUX_QUOTAOPS_

#include <linux/smp_lock.h>

#include <linux/fs.h>

#if defined(CONFIG_QUOTA)

/*
 * declaration of quota_function calls in kernel.
 */
extern void sync_dquots(struct super_block *sb, int type);

extern int dquot_initialize(struct inode *inode, int type);
extern int dquot_drop(struct inode *inode);

extern int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc);
extern int dquot_alloc_inode(const struct inode *inode, unsigned long number);

extern int dquot_free_space(struct inode *inode, qsize_t number);
extern int dquot_free_inode(const struct inode *inode, unsigned long number);

extern int dquot_transfer(struct inode *inode, struct iattr *iattr);
extern int dquot_commit(struct dquot *dquot);
extern int dquot_acquire(struct dquot *dquot);
extern int dquot_release(struct dquot *dquot);
extern int dquot_commit_info(struct super_block *sb, int type);
extern int dquot_mark_dquot_dirty(struct dquot *dquot);

extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path);
41 42
extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
		int format_id, int type);
L
Linus Torvalds 已提交
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
extern int vfs_quota_off(struct super_block *sb, int type);
extern int vfs_quota_sync(struct super_block *sb, int type);
extern int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
extern int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
extern int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
extern int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);

/*
 * Operations supported for diskquotas.
 */
extern struct dquot_operations dquot_operations;
extern struct quotactl_ops vfs_quotactl_ops;

#define sb_dquot_ops (&dquot_operations)
#define sb_quotactl_ops (&vfs_quotactl_ops)

/* It is better to call this function outside of any transaction as it might
 * need a lot of space in journal for dquot structure allocation. */
J
Jan Kara 已提交
61
static inline void DQUOT_INIT(struct inode *inode)
L
Linus Torvalds 已提交
62 63 64 65 66 67 68
{
	BUG_ON(!inode->i_sb);
	if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode))
		inode->i_sb->dq_op->initialize(inode, -1);
}

/* The same as with DQUOT_INIT */
J
Jan Kara 已提交
69
static inline void DQUOT_DROP(struct inode *inode)
L
Linus Torvalds 已提交
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
{
	/* Here we can get arbitrary inode from clear_inode() so we have
	 * to be careful. OTOH we don't need locking as quota operations
	 * are allowed to change only at mount time */
	if (!IS_NOQUOTA(inode) && inode->i_sb && inode->i_sb->dq_op
	    && inode->i_sb->dq_op->drop) {
		int cnt;
		/* Test before calling to rule out calls from proc and such
                 * where we are not allowed to block. Note that this is
		 * actually reliable test even without the lock - the caller
		 * must assure that nobody can come after the DQUOT_DROP and
		 * add quota pointers back anyway */
		for (cnt = 0; cnt < MAXQUOTAS; cnt++)
			if (inode->i_dquot[cnt] != NODQUOT)
				break;
		if (cnt < MAXQUOTAS)
			inode->i_sb->dq_op->drop(inode);
	}
}

/* The following allocation/freeing/transfer functions *must* be called inside
 * a transaction (deadlocks possible otherwise) */
J
Jan Kara 已提交
92
static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
L
Linus Torvalds 已提交
93 94 95 96 97 98 99 100 101 102 103
{
	if (sb_any_quota_enabled(inode->i_sb)) {
		/* Used space is updated in alloc_space() */
		if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA)
			return 1;
	}
	else
		inode_add_bytes(inode, nr);
	return 0;
}

J
Jan Kara 已提交
104
static inline int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
L
Linus Torvalds 已提交
105 106 107 108 109 110 111
{
	int ret;
        if (!(ret =  DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr)))
		mark_inode_dirty(inode);
	return ret;
}

J
Jan Kara 已提交
112
static inline int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
L
Linus Torvalds 已提交
113 114 115 116 117 118 119 120 121 122 123
{
	if (sb_any_quota_enabled(inode->i_sb)) {
		/* Used space is updated in alloc_space() */
		if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA)
			return 1;
	}
	else
		inode_add_bytes(inode, nr);
	return 0;
}

J
Jan Kara 已提交
124
static inline int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
L
Linus Torvalds 已提交
125 126 127 128 129 130 131
{
	int ret;
	if (!(ret = DQUOT_ALLOC_SPACE_NODIRTY(inode, nr)))
		mark_inode_dirty(inode);
	return ret;
}

J
Jan Kara 已提交
132
static inline int DQUOT_ALLOC_INODE(struct inode *inode)
L
Linus Torvalds 已提交
133 134 135 136 137 138 139 140 141
{
	if (sb_any_quota_enabled(inode->i_sb)) {
		DQUOT_INIT(inode);
		if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA)
			return 1;
	}
	return 0;
}

J
Jan Kara 已提交
142
static inline void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
L
Linus Torvalds 已提交
143 144 145 146 147 148 149
{
	if (sb_any_quota_enabled(inode->i_sb))
		inode->i_sb->dq_op->free_space(inode, nr);
	else
		inode_sub_bytes(inode, nr);
}

J
Jan Kara 已提交
150
static inline void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
L
Linus Torvalds 已提交
151 152 153 154 155
{
	DQUOT_FREE_SPACE_NODIRTY(inode, nr);
	mark_inode_dirty(inode);
}

J
Jan Kara 已提交
156
static inline void DQUOT_FREE_INODE(struct inode *inode)
L
Linus Torvalds 已提交
157 158 159 160 161
{
	if (sb_any_quota_enabled(inode->i_sb))
		inode->i_sb->dq_op->free_inode(inode, 1);
}

J
Jan Kara 已提交
162
static inline int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr)
L
Linus Torvalds 已提交
163 164 165 166 167 168 169 170 171 172
{
	if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) {
		DQUOT_INIT(inode);
		if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA)
			return 1;
	}
	return 0;
}

/* The following two functions cannot be called inside a transaction */
J
Jan Kara 已提交
173 174 175 176
static inline void DQUOT_SYNC(struct super_block *sb)
{
	sync_dquots(sb, -1);
}
L
Linus Torvalds 已提交
177

J
Jan Kara 已提交
178
static inline int DQUOT_OFF(struct super_block *sb)
L
Linus Torvalds 已提交
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
{
	int ret = -ENOSYS;

	if (sb_any_quota_enabled(sb) && sb->s_qcop && sb->s_qcop->quota_off)
		ret = sb->s_qcop->quota_off(sb, -1);
	return ret;
}

#else

/*
 * NO-OP when quota not configured.
 */
#define sb_dquot_ops				(NULL)
#define sb_quotactl_ops				(NULL)
#define DQUOT_INIT(inode)			do { } while(0)
#define DQUOT_DROP(inode)			do { } while(0)
#define DQUOT_ALLOC_INODE(inode)		(0)
#define DQUOT_FREE_INODE(inode)			do { } while(0)
#define DQUOT_SYNC(sb)				do { } while(0)
J
Jan Kara 已提交
199
#define DQUOT_OFF(sb)				(0)
L
Linus Torvalds 已提交
200
#define DQUOT_TRANSFER(inode, iattr)		(0)
A
Adrian Bunk 已提交
201
static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
L
Linus Torvalds 已提交
202 203 204 205 206
{
	inode_add_bytes(inode, nr);
	return 0;
}

A
Adrian Bunk 已提交
207
static inline int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
L
Linus Torvalds 已提交
208 209 210 211 212 213
{
	DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr);
	mark_inode_dirty(inode);
	return 0;
}

A
Adrian Bunk 已提交
214
static inline int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
L
Linus Torvalds 已提交
215 216 217 218 219
{
	inode_add_bytes(inode, nr);
	return 0;
}

A
Adrian Bunk 已提交
220
static inline int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
L
Linus Torvalds 已提交
221 222 223 224 225 226
{
	DQUOT_ALLOC_SPACE_NODIRTY(inode, nr);
	mark_inode_dirty(inode);
	return 0;
}

A
Adrian Bunk 已提交
227
static inline void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
L
Linus Torvalds 已提交
228 229 230 231
{
	inode_sub_bytes(inode, nr);
}

A
Adrian Bunk 已提交
232
static inline void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
L
Linus Torvalds 已提交
233 234 235 236 237 238 239
{
	DQUOT_FREE_SPACE_NODIRTY(inode, nr);
	mark_inode_dirty(inode);
}	

#endif /* CONFIG_QUOTA */

J
Jan Kara 已提交
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
static inline int DQUOT_PREALLOC_BLOCK_NODIRTY(struct inode *inode, qsize_t nr)
{
	return DQUOT_PREALLOC_SPACE_NODIRTY(inode,
			nr << inode->i_sb->s_blocksize_bits);
}

static inline int DQUOT_PREALLOC_BLOCK(struct inode *inode, qsize_t nr)
{
	return DQUOT_PREALLOC_SPACE(inode,
			nr << inode->i_sb->s_blocksize_bits);
}

static inline int DQUOT_ALLOC_BLOCK_NODIRTY(struct inode *inode, qsize_t nr)
{
	return DQUOT_ALLOC_SPACE_NODIRTY(inode,
			nr << inode->i_sb->s_blocksize_bits);
}

static inline int DQUOT_ALLOC_BLOCK(struct inode *inode, qsize_t nr)
{
	return DQUOT_ALLOC_SPACE(inode,
			nr << inode->i_sb->s_blocksize_bits);
}

static inline void DQUOT_FREE_BLOCK_NODIRTY(struct inode *inode, qsize_t nr)
{
	DQUOT_FREE_SPACE_NODIRTY(inode, nr << inode->i_sb->s_blocksize_bits);
}

static inline void DQUOT_FREE_BLOCK(struct inode *inode, qsize_t nr)
{
	DQUOT_FREE_SPACE(inode, nr << inode->i_sb->s_blocksize_bits);
}
L
Linus Torvalds 已提交
273 274

#endif /* _LINUX_QUOTAOPS_ */