X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=include%2Flinux%2Fquotaops.h;h=aa36793b48bd11b80b4b33765c7b7d074a899e7f;hb=HEAD;hp=5110201a415949e5e10bd8381ff4f38e120320cf;hpb=e5f00f42f35e6f4699f105a3bd56874847cbf72f;p=safe%2Fjmp%2Flinux-2.6 diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 5110201..aa36793 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -3,243 +3,357 @@ * macros expand to the right source-code. * * Author: Marco van Wieringen - * - * Version: $Id: quotaops.h,v 1.2 1998/01/15 16:22:26 ecd Exp $ - * */ #ifndef _LINUX_QUOTAOPS_ #define _LINUX_QUOTAOPS_ -#include - #include +#define DQUOT_SPACE_WARN 0x1 +#define DQUOT_SPACE_RESERVE 0x2 +#define DQUOT_SPACE_NOFAIL 0x4 + +static inline struct quota_info *sb_dqopt(struct super_block *sb) +{ + return &sb->s_dquot; +} + +/* i_mutex must being held */ +static inline bool is_quota_modification(struct inode *inode, struct iattr *ia) +{ + return (ia->ia_valid & ATTR_SIZE && ia->ia_size != inode->i_size) || + (ia->ia_valid & ATTR_UID && ia->ia_uid != inode->i_uid) || + (ia->ia_valid & ATTR_GID && ia->ia_gid != inode->i_gid); +} + #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); -extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name, - int format_id, int type); -extern int vfs_quota_off(struct super_block *sb, int type); -#define vfs_quota_off_mount(sb, type) vfs_quota_off(sb, 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); +void inode_add_rsv_space(struct inode *inode, qsize_t number); +void inode_claim_rsv_space(struct inode *inode, qsize_t number); +void inode_sub_rsv_space(struct inode *inode, qsize_t number); + +void dquot_initialize(struct inode *inode); +void dquot_drop(struct inode *inode); +struct dquot *dqget(struct super_block *sb, unsigned int id, int type); +void dqput(struct dquot *dquot); +int dquot_scan_active(struct super_block *sb, + int (*fn)(struct dquot *dquot, unsigned long priv), + unsigned long priv); +struct dquot *dquot_alloc(struct super_block *sb, int type); +void dquot_destroy(struct dquot *dquot); + +int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags); +void __dquot_free_space(struct inode *inode, qsize_t number, int flags); + +int dquot_alloc_inode(const struct inode *inode); + +int dquot_claim_space_nodirty(struct inode *inode, qsize_t number); +void dquot_free_inode(const struct inode *inode); + +int dquot_disable(struct super_block *sb, int type, unsigned int flags); +/* Suspend quotas on remount RO */ +static inline int dquot_suspend(struct super_block *sb, int type) +{ + return dquot_disable(sb, type, DQUOT_SUSPENDED); +} +int dquot_resume(struct super_block *sb, int type); + +int dquot_commit(struct dquot *dquot); +int dquot_acquire(struct dquot *dquot); +int dquot_release(struct dquot *dquot); +int dquot_commit_info(struct super_block *sb, int type); +int dquot_mark_dquot_dirty(struct dquot *dquot); + +int dquot_file_open(struct inode *inode, struct file *file); + +int dquot_quota_on(struct super_block *sb, int type, int format_id, + char *path); +int dquot_enable(struct inode *inode, int type, int format_id, + unsigned int flags); +int dquot_quota_on_path(struct super_block *sb, int type, int format_id, + struct path *path); +int dquot_quota_on_mount(struct super_block *sb, char *qf_name, + int format_id, int type); +int dquot_quota_off(struct super_block *sb, int type); +int dquot_quota_sync(struct super_block *sb, int type, int wait); +int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); +int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); +int dquot_get_dqblk(struct super_block *sb, int type, qid_t id, + struct fs_disk_quota *di); +int dquot_set_dqblk(struct super_block *sb, int type, qid_t id, + struct fs_disk_quota *di); + +int __dquot_transfer(struct inode *inode, struct dquot **transfer_to); +int dquot_transfer(struct inode *inode, struct iattr *iattr); + +static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type) +{ + return sb_dqopt(sb)->info + type; +} + +/* + * Functions for checking status of quota + */ + +static inline bool sb_has_quota_usage_enabled(struct super_block *sb, int type) +{ + return sb_dqopt(sb)->flags & + dquot_state_flag(DQUOT_USAGE_ENABLED, type); +} + +static inline bool sb_has_quota_limits_enabled(struct super_block *sb, int type) +{ + return sb_dqopt(sb)->flags & + dquot_state_flag(DQUOT_LIMITS_ENABLED, type); +} + +static inline bool sb_has_quota_suspended(struct super_block *sb, int type) +{ + return sb_dqopt(sb)->flags & + dquot_state_flag(DQUOT_SUSPENDED, type); +} + +static inline unsigned sb_any_quota_suspended(struct super_block *sb) +{ + unsigned type, tmsk = 0; + for (type = 0; type < MAXQUOTAS; type++) + tmsk |= sb_has_quota_suspended(sb, type) << type; + return tmsk; +} + +/* Does kernel know about any quota information for given sb + type? */ +static inline bool sb_has_quota_loaded(struct super_block *sb, int type) +{ + /* Currently if anything is on, then quota usage is on as well */ + return sb_has_quota_usage_enabled(sb, type); +} + +static inline unsigned sb_any_quota_loaded(struct super_block *sb) +{ + unsigned type, tmsk = 0; + for (type = 0; type < MAXQUOTAS; type++) + tmsk |= sb_has_quota_loaded(sb, type) << type; + return tmsk; +} + +static inline bool sb_has_quota_active(struct super_block *sb, int type) +{ + return sb_has_quota_loaded(sb, type) && + !sb_has_quota_suspended(sb, type); +} + +static inline unsigned sb_any_quota_active(struct super_block *sb) +{ + return sb_any_quota_loaded(sb) & ~sb_any_quota_suspended(sb); +} /* * 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. */ -static __inline__ void DQUOT_INIT(struct inode *inode) -{ - 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 */ -static __inline__ void DQUOT_DROP(struct inode *inode) -{ - /* 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) */ -static __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) -{ - 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); +extern const struct dquot_operations dquot_operations; +extern const struct quotactl_ops dquot_quotactl_ops; + +#else + +static inline int sb_has_quota_usage_enabled(struct super_block *sb, int type) +{ return 0; } -static __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr) +static inline int sb_has_quota_limits_enabled(struct super_block *sb, int type) { - int ret; - if (!(ret = DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr))) - mark_inode_dirty(inode); - return ret; + return 0; } -static __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) +static inline int sb_has_quota_suspended(struct super_block *sb, int type) { - 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; } -static __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr) +static inline int sb_any_quota_suspended(struct super_block *sb) { - int ret; - if (!(ret = DQUOT_ALLOC_SPACE_NODIRTY(inode, nr))) - mark_inode_dirty(inode); - return ret; + return 0; } -static __inline__ int DQUOT_ALLOC_INODE(struct inode *inode) +/* Does kernel know about any quota information for given sb + type? */ +static inline int sb_has_quota_loaded(struct super_block *sb, int type) { - 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; } -static __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr) +static inline int sb_any_quota_loaded(struct super_block *sb) { - if (sb_any_quota_enabled(inode->i_sb)) - inode->i_sb->dq_op->free_space(inode, nr); - else - inode_sub_bytes(inode, nr); + return 0; } -static __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr) +static inline int sb_has_quota_active(struct super_block *sb, int type) +{ + return 0; +} + +static inline int sb_any_quota_active(struct super_block *sb) +{ + return 0; +} + +static inline void dquot_initialize(struct inode *inode) { - DQUOT_FREE_SPACE_NODIRTY(inode, nr); - mark_inode_dirty(inode); } -static __inline__ void DQUOT_FREE_INODE(struct inode *inode) +static inline void dquot_drop(struct inode *inode) { - if (sb_any_quota_enabled(inode->i_sb)) - inode->i_sb->dq_op->free_inode(inode, 1); } -static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr) +static inline int dquot_alloc_inode(const struct inode *inode) { - 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 */ -#define DQUOT_SYNC(sb) sync_dquots(sb, -1) +static inline void dquot_free_inode(const struct inode *inode) +{ +} -static __inline__ int DQUOT_OFF(struct super_block *sb) +static inline int dquot_transfer(struct inode *inode, struct iattr *iattr) { - int ret = -ENOSYS; + return 0; +} - if (sb_any_quota_enabled(sb) && sb->s_qcop && sb->s_qcop->quota_off) - ret = sb->s_qcop->quota_off(sb, -1); - return ret; +static inline int __dquot_alloc_space(struct inode *inode, qsize_t number, + int flags) +{ + if (!(flags & DQUOT_SPACE_RESERVE)) + inode_add_bytes(inode, number); + return 0; } -#else +static inline void __dquot_free_space(struct inode *inode, qsize_t number, + int flags) +{ + if (!(flags & DQUOT_SPACE_RESERVE)) + inode_sub_bytes(inode, number); +} -/* - * 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) -#define DQUOT_OFF(sb) do { } while(0) -#define DQUOT_TRANSFER(inode, iattr) (0) -static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) -{ - inode_add_bytes(inode, nr); +static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) +{ + inode_add_bytes(inode, number); return 0; } -static inline int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr) +static inline int dquot_disable(struct super_block *sb, int type, + unsigned int flags) { - DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr); - mark_inode_dirty(inode); return 0; } -static inline int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) +static inline int dquot_suspend(struct super_block *sb, int type) { - inode_add_bytes(inode, nr); return 0; } -static inline int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr) +static inline int dquot_resume(struct super_block *sb, int type) { - DQUOT_ALLOC_SPACE_NODIRTY(inode, nr); - mark_inode_dirty(inode); return 0; } -static inline void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr) +#define dquot_file_open generic_file_open + +#endif /* CONFIG_QUOTA */ + +static inline int dquot_alloc_space_nodirty(struct inode *inode, qsize_t nr) { - inode_sub_bytes(inode, nr); + return __dquot_alloc_space(inode, nr, DQUOT_SPACE_WARN); } -static inline void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr) +static inline void dquot_alloc_space_nofail(struct inode *inode, qsize_t nr) { - DQUOT_FREE_SPACE_NODIRTY(inode, nr); + __dquot_alloc_space(inode, nr, DQUOT_SPACE_WARN|DQUOT_SPACE_NOFAIL); mark_inode_dirty(inode); -} +} -#endif /* CONFIG_QUOTA */ +static inline int dquot_alloc_space(struct inode *inode, qsize_t nr) +{ + int ret; + + ret = dquot_alloc_space_nodirty(inode, nr); + if (!ret) + mark_inode_dirty(inode); + return ret; +} + +static inline int dquot_alloc_block_nodirty(struct inode *inode, qsize_t nr) +{ + return dquot_alloc_space_nodirty(inode, nr << inode->i_blkbits); +} + +static inline void dquot_alloc_block_nofail(struct inode *inode, qsize_t nr) +{ + dquot_alloc_space_nofail(inode, nr << inode->i_blkbits); +} + +static inline int dquot_alloc_block(struct inode *inode, qsize_t nr) +{ + return dquot_alloc_space(inode, nr << inode->i_blkbits); +} + +static inline int dquot_prealloc_block_nodirty(struct inode *inode, qsize_t nr) +{ + return __dquot_alloc_space(inode, nr << inode->i_blkbits, 0); +} -#define DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr) DQUOT_PREALLOC_SPACE_NODIRTY(inode, ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits) -#define DQUOT_PREALLOC_BLOCK(inode, nr) DQUOT_PREALLOC_SPACE(inode, ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits) -#define DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr) DQUOT_ALLOC_SPACE_NODIRTY(inode, ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits) -#define DQUOT_ALLOC_BLOCK(inode, nr) DQUOT_ALLOC_SPACE(inode, ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits) -#define DQUOT_FREE_BLOCK_NODIRTY(inode, nr) DQUOT_FREE_SPACE_NODIRTY(inode, ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits) -#define DQUOT_FREE_BLOCK(inode, nr) DQUOT_FREE_SPACE(inode, ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits) +static inline int dquot_prealloc_block(struct inode *inode, qsize_t nr) +{ + int ret; + + ret = dquot_prealloc_block_nodirty(inode, nr); + if (!ret) + mark_inode_dirty(inode); + return ret; +} + +static inline int dquot_reserve_block(struct inode *inode, qsize_t nr) +{ + return __dquot_alloc_space(inode, nr << inode->i_blkbits, + DQUOT_SPACE_WARN|DQUOT_SPACE_RESERVE); +} + +static inline int dquot_claim_block(struct inode *inode, qsize_t nr) +{ + int ret; + + ret = dquot_claim_space_nodirty(inode, nr << inode->i_blkbits); + if (!ret) + mark_inode_dirty(inode); + return ret; +} + +static inline void dquot_free_space_nodirty(struct inode *inode, qsize_t nr) +{ + __dquot_free_space(inode, nr, 0); +} + +static inline void dquot_free_space(struct inode *inode, qsize_t nr) +{ + dquot_free_space_nodirty(inode, nr); + mark_inode_dirty(inode); +} + +static inline void dquot_free_block_nodirty(struct inode *inode, qsize_t nr) +{ + dquot_free_space_nodirty(inode, nr << inode->i_blkbits); +} + +static inline void dquot_free_block(struct inode *inode, qsize_t nr) +{ + dquot_free_space(inode, nr << inode->i_blkbits); +} + +static inline void dquot_release_reservation_block(struct inode *inode, + qsize_t nr) +{ + __dquot_free_space(inode, nr << inode->i_blkbits, DQUOT_SPACE_RESERVE); +} #endif /* _LINUX_QUOTAOPS_ */