#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/mount.h>
#include <linux/mm.h>
#include <linux/time.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/tty.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/security.h>
#include <linux/sched.h>
#include <linux/cred.h>
#include <linux/kmod.h>
#include <linux/namei.h>
#include <linux/capability.h>
#include <linux/quotaops.h>
#include <linux/blkdev.h>
#include <linux/sched/mm.h>
#include "../internal.h"
#include <linux/uaccess.h>
static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock);
static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_state_lock);
__cacheline_aligned_in_smp DEFINE_SPINLOCK(…);
EXPORT_SYMBOL(…);
DEFINE_STATIC_SRCU(…);
static DECLARE_WAIT_QUEUE_HEAD(dquot_ref_wq);
void __quota_error(struct super_block *sb, const char *func,
const char *fmt, ...)
{ … }
EXPORT_SYMBOL(…);
#if defined(CONFIG_QUOTA_DEBUG) || defined(CONFIG_PRINT_QUOTA_WARNING)
static char *quotatypes[] = INITQFNAMES;
#endif
static struct quota_format_type *quota_formats;
static struct quota_module_name module_names[] = …;
static struct kmem_cache *dquot_cachep;
int register_quota_format(struct quota_format_type *fmt)
{ … }
EXPORT_SYMBOL(…);
void unregister_quota_format(struct quota_format_type *fmt)
{ … }
EXPORT_SYMBOL(…);
static struct quota_format_type *find_quota_format(int id)
{ … }
static void put_quota_format(struct quota_format_type *fmt)
{ … }
static LIST_HEAD(inuse_list);
static LIST_HEAD(free_dquots);
static LIST_HEAD(releasing_dquots);
static unsigned int dq_hash_bits, dq_hash_mask;
static struct hlist_head *dquot_hash;
struct dqstats dqstats;
EXPORT_SYMBOL(…);
static qsize_t inode_get_rsv_space(struct inode *inode);
static qsize_t __inode_get_rsv_space(struct inode *inode);
static int __dquot_initialize(struct inode *inode, int type);
static void quota_release_workfn(struct work_struct *work);
static DECLARE_DELAYED_WORK(quota_release_work, quota_release_workfn);
static inline unsigned int
hashfn(const struct super_block *sb, struct kqid qid)
{ … }
static inline void insert_dquot_hash(struct dquot *dquot)
{ … }
static inline void remove_dquot_hash(struct dquot *dquot)
{ … }
static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb,
struct kqid qid)
{ … }
static inline void put_dquot_last(struct dquot *dquot)
{ … }
static inline void put_releasing_dquots(struct dquot *dquot)
{ … }
static inline void remove_free_dquot(struct dquot *dquot)
{ … }
static inline void put_inuse(struct dquot *dquot)
{ … }
static inline void remove_inuse(struct dquot *dquot)
{ … }
static void wait_on_dquot(struct dquot *dquot)
{ … }
static inline int dquot_active(struct dquot *dquot)
{ … }
static inline int dquot_dirty(struct dquot *dquot)
{ … }
static inline int mark_dquot_dirty(struct dquot *dquot)
{ … }
int dquot_mark_dquot_dirty(struct dquot *dquot)
{ … }
EXPORT_SYMBOL(…);
static inline int mark_all_dquot_dirty(struct dquot __rcu * const *dquots)
{ … }
static inline void dqput_all(struct dquot **dquot)
{ … }
static inline int clear_dquot_dirty(struct dquot *dquot)
{ … }
void mark_info_dirty(struct super_block *sb, int type)
{ … }
EXPORT_SYMBOL(…);
int dquot_acquire(struct dquot *dquot)
{ … }
EXPORT_SYMBOL(…);
int dquot_commit(struct dquot *dquot)
{ … }
EXPORT_SYMBOL(…);
int dquot_release(struct dquot *dquot)
{ … }
EXPORT_SYMBOL(…);
void dquot_destroy(struct dquot *dquot)
{ … }
EXPORT_SYMBOL(…);
static inline void do_destroy_dquot(struct dquot *dquot)
{ … }
static void invalidate_dquots(struct super_block *sb, int type)
{ … }
int dquot_scan_active(struct super_block *sb,
int (*fn)(struct dquot *dquot, unsigned long priv),
unsigned long priv)
{ … }
EXPORT_SYMBOL(…);
static inline int dquot_write_dquot(struct dquot *dquot)
{ … }
int dquot_writeback_dquots(struct super_block *sb, int type)
{ … }
EXPORT_SYMBOL(…);
int dquot_quota_sync(struct super_block *sb, int type)
{ … }
EXPORT_SYMBOL(…);
static unsigned long
dqcache_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
{ … }
static unsigned long
dqcache_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
{ … }
static void quota_release_workfn(struct work_struct *work)
{ … }
void dqput(struct dquot *dquot)
{ … }
EXPORT_SYMBOL(…);
struct dquot *dquot_alloc(struct super_block *sb, int type)
{ … }
EXPORT_SYMBOL(…);
static struct dquot *get_empty_dquot(struct super_block *sb, int type)
{ … }
struct dquot *dqget(struct super_block *sb, struct kqid qid)
{ … }
EXPORT_SYMBOL(…);
static inline struct dquot __rcu **i_dquot(struct inode *inode)
{ … }
static int dqinit_needed(struct inode *inode, int type)
{ … }
static int add_dquot_ref(struct super_block *sb, int type)
{ … }
static void remove_dquot_ref(struct super_block *sb, int type)
{ … }
static void drop_dquot_ref(struct super_block *sb, int type)
{ … }
static inline
void dquot_free_reserved_space(struct dquot *dquot, qsize_t number)
{ … }
static void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
{ … }
static void dquot_decr_space(struct dquot *dquot, qsize_t number)
{ … }
struct dquot_warn { … };
static int warning_issued(struct dquot *dquot, const int warntype)
{ … }
#ifdef CONFIG_PRINT_QUOTA_WARNING
static int flag_print_warnings = 1;
static int need_print_warning(struct dquot_warn *warn)
{
if (!flag_print_warnings)
return 0;
switch (warn->w_dq_id.type) {
case USRQUOTA:
return uid_eq(current_fsuid(), warn->w_dq_id.uid);
case GRPQUOTA:
return in_group_p(warn->w_dq_id.gid);
case PRJQUOTA:
return 1;
}
return 0;
}
static void print_warning(struct dquot_warn *warn)
{
char *msg = NULL;
struct tty_struct *tty;
int warntype = warn->w_type;
if (warntype == QUOTA_NL_IHARDBELOW ||
warntype == QUOTA_NL_ISOFTBELOW ||
warntype == QUOTA_NL_BHARDBELOW ||
warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(warn))
return;
tty = get_current_tty();
if (!tty)
return;
tty_write_message(tty, warn->w_sb->s_id);
if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN)
tty_write_message(tty, ": warning, ");
else
tty_write_message(tty, ": write failed, ");
tty_write_message(tty, quotatypes[warn->w_dq_id.type]);
switch (warntype) {
case QUOTA_NL_IHARDWARN:
msg = " file limit reached.\r\n";
break;
case QUOTA_NL_ISOFTLONGWARN:
msg = " file quota exceeded too long.\r\n";
break;
case QUOTA_NL_ISOFTWARN:
msg = " file quota exceeded.\r\n";
break;
case QUOTA_NL_BHARDWARN:
msg = " block limit reached.\r\n";
break;
case QUOTA_NL_BSOFTLONGWARN:
msg = " block quota exceeded too long.\r\n";
break;
case QUOTA_NL_BSOFTWARN:
msg = " block quota exceeded.\r\n";
break;
}
tty_write_message(tty, msg);
tty_kref_put(tty);
}
#endif
static void prepare_warning(struct dquot_warn *warn, struct dquot *dquot,
int warntype)
{ … }
static void flush_warnings(struct dquot_warn *warn)
{ … }
static int ignore_hardlimit(struct dquot *dquot)
{ … }
static int dquot_add_inodes(struct dquot *dquot, qsize_t inodes,
struct dquot_warn *warn)
{ … }
static int dquot_add_space(struct dquot *dquot, qsize_t space,
qsize_t rsv_space, unsigned int flags,
struct dquot_warn *warn)
{ … }
static int info_idq_free(struct dquot *dquot, qsize_t inodes)
{ … }
static int info_bdq_free(struct dquot *dquot, qsize_t space)
{ … }
static int inode_quota_active(const struct inode *inode)
{ … }
static int __dquot_initialize(struct inode *inode, int type)
{ … }
int dquot_initialize(struct inode *inode)
{ … }
EXPORT_SYMBOL(…);
bool dquot_initialize_needed(struct inode *inode)
{ … }
EXPORT_SYMBOL(…);
static void __dquot_drop(struct inode *inode)
{ … }
void dquot_drop(struct inode *inode)
{ … }
EXPORT_SYMBOL(…);
static qsize_t *inode_reserved_space(struct inode * inode)
{ … }
static qsize_t __inode_get_rsv_space(struct inode *inode)
{ … }
static qsize_t inode_get_rsv_space(struct inode *inode)
{ … }
int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
{ … }
EXPORT_SYMBOL(…);
int dquot_alloc_inode(struct inode *inode)
{ … }
EXPORT_SYMBOL(…);
void dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
{ … }
EXPORT_SYMBOL(…);
void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
{ … }
EXPORT_SYMBOL(…);
void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
{ … }
EXPORT_SYMBOL(…);
void dquot_free_inode(struct inode *inode)
{ … }
EXPORT_SYMBOL(…);
int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
{ … }
EXPORT_SYMBOL(…);
int dquot_transfer(struct mnt_idmap *idmap, struct inode *inode,
struct iattr *iattr)
{ … }
EXPORT_SYMBOL(…);
int dquot_commit_info(struct super_block *sb, int type)
{ … }
EXPORT_SYMBOL(…);
int dquot_get_next_id(struct super_block *sb, struct kqid *qid)
{ … }
EXPORT_SYMBOL(…);
const struct dquot_operations dquot_operations = …;
EXPORT_SYMBOL(…);
int dquot_file_open(struct inode *inode, struct file *file)
{ … }
EXPORT_SYMBOL(…);
static void vfs_cleanup_quota_inode(struct super_block *sb, int type)
{ … }
int dquot_disable(struct super_block *sb, int type, unsigned int flags)
{ … }
EXPORT_SYMBOL(…);
int dquot_quota_off(struct super_block *sb, int type)
{ … }
EXPORT_SYMBOL(…);
static int vfs_setup_quota_inode(struct inode *inode, int type)
{ … }
int dquot_load_quota_sb(struct super_block *sb, int type, int format_id,
unsigned int flags)
{ … }
EXPORT_SYMBOL(…);
int dquot_load_quota_inode(struct inode *inode, int type, int format_id,
unsigned int flags)
{ … }
EXPORT_SYMBOL(…);
int dquot_resume(struct super_block *sb, int type)
{ … }
EXPORT_SYMBOL(…);
int dquot_quota_on(struct super_block *sb, int type, int format_id,
const struct path *path)
{ … }
EXPORT_SYMBOL(…);
int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
int format_id, int type)
{ … }
EXPORT_SYMBOL(…);
static int dquot_quota_enable(struct super_block *sb, unsigned int flags)
{ … }
static int dquot_quota_disable(struct super_block *sb, unsigned int flags)
{ … }
static void do_get_dqblk(struct dquot *dquot, struct qc_dqblk *di)
{ … }
int dquot_get_dqblk(struct super_block *sb, struct kqid qid,
struct qc_dqblk *di)
{ … }
EXPORT_SYMBOL(…);
int dquot_get_next_dqblk(struct super_block *sb, struct kqid *qid,
struct qc_dqblk *di)
{ … }
EXPORT_SYMBOL(…);
#define VFS_QC_MASK …
static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di)
{ … }
int dquot_set_dqblk(struct super_block *sb, struct kqid qid,
struct qc_dqblk *di)
{ … }
EXPORT_SYMBOL(…);
int dquot_get_state(struct super_block *sb, struct qc_state *state)
{ … }
EXPORT_SYMBOL(…);
int dquot_set_dqinfo(struct super_block *sb, int type, struct qc_info *ii)
{ … }
EXPORT_SYMBOL(…);
const struct quotactl_ops dquot_quotactl_sysfile_ops = …;
EXPORT_SYMBOL(…);
static int do_proc_dqstats(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{ … }
static struct ctl_table fs_dqstats_table[] = …;
static int __init dquot_init(void)
{ … }
fs_initcall(dquot_init);