quota: Split dquot_quota_sync() to writeback and cache flushing part
Split off part of dquot_quota_sync() which writes dquots into a quota file to a separate function. In the next patch we will use the function from filesystems and we do not want to abuse ->quota_sync quotactl callback more than necessary. Acked-by: Steven Whitehouse <swhiteho@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
6eedc70150
Коммит
ceed17236a
|
@ -1108,7 +1108,7 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int gfs2_quota_sync(struct super_block *sb, int type, int wait)
|
int gfs2_quota_sync(struct super_block *sb, int type)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = sb->s_fs_info;
|
struct gfs2_sbd *sdp = sb->s_fs_info;
|
||||||
struct gfs2_quota_data **qda;
|
struct gfs2_quota_data **qda;
|
||||||
|
@ -1154,7 +1154,7 @@ int gfs2_quota_sync(struct super_block *sb, int type, int wait)
|
||||||
|
|
||||||
static int gfs2_quota_sync_timeo(struct super_block *sb, int type)
|
static int gfs2_quota_sync_timeo(struct super_block *sb, int type)
|
||||||
{
|
{
|
||||||
return gfs2_quota_sync(sb, type, 0);
|
return gfs2_quota_sync(sb, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id)
|
int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id)
|
||||||
|
|
|
@ -26,7 +26,7 @@ extern int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid);
|
||||||
extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
|
extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
|
||||||
u32 uid, u32 gid);
|
u32 uid, u32 gid);
|
||||||
|
|
||||||
extern int gfs2_quota_sync(struct super_block *sb, int type, int wait);
|
extern int gfs2_quota_sync(struct super_block *sb, int type);
|
||||||
extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id);
|
extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id);
|
||||||
|
|
||||||
extern int gfs2_quota_init(struct gfs2_sbd *sdp);
|
extern int gfs2_quota_init(struct gfs2_sbd *sdp);
|
||||||
|
|
|
@ -838,7 +838,7 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
flush_workqueue(gfs2_delete_workqueue);
|
flush_workqueue(gfs2_delete_workqueue);
|
||||||
gfs2_quota_sync(sdp->sd_vfs, 0, 1);
|
gfs2_quota_sync(sdp->sd_vfs, 0);
|
||||||
gfs2_statfs_sync(sdp->sd_vfs, 0);
|
gfs2_statfs_sync(sdp->sd_vfs, 0);
|
||||||
|
|
||||||
error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE,
|
error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE,
|
||||||
|
|
|
@ -168,7 +168,7 @@ static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
|
||||||
if (simple_strtol(buf, NULL, 0) != 1)
|
if (simple_strtol(buf, NULL, 0) != 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
gfs2_quota_sync(sdp->sd_vfs, 0, 1);
|
gfs2_quota_sync(sdp->sd_vfs, 0);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -595,12 +595,14 @@ out:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dquot_scan_active);
|
EXPORT_SYMBOL(dquot_scan_active);
|
||||||
|
|
||||||
int dquot_quota_sync(struct super_block *sb, int type, int wait)
|
/* Write all dquot structures to quota files */
|
||||||
|
int dquot_writeback_dquots(struct super_block *sb, int type)
|
||||||
{
|
{
|
||||||
struct list_head *dirty;
|
struct list_head *dirty;
|
||||||
struct dquot *dquot;
|
struct dquot *dquot;
|
||||||
struct quota_info *dqopt = sb_dqopt(sb);
|
struct quota_info *dqopt = sb_dqopt(sb);
|
||||||
int cnt;
|
int cnt;
|
||||||
|
int err, ret = 0;
|
||||||
|
|
||||||
mutex_lock(&dqopt->dqonoff_mutex);
|
mutex_lock(&dqopt->dqonoff_mutex);
|
||||||
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
|
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
|
||||||
|
@ -624,7 +626,9 @@ int dquot_quota_sync(struct super_block *sb, int type, int wait)
|
||||||
atomic_inc(&dquot->dq_count);
|
atomic_inc(&dquot->dq_count);
|
||||||
spin_unlock(&dq_list_lock);
|
spin_unlock(&dq_list_lock);
|
||||||
dqstats_inc(DQST_LOOKUPS);
|
dqstats_inc(DQST_LOOKUPS);
|
||||||
sb->dq_op->write_dquot(dquot);
|
err = sb->dq_op->write_dquot(dquot);
|
||||||
|
if (!ret && err)
|
||||||
|
err = ret;
|
||||||
dqput(dquot);
|
dqput(dquot);
|
||||||
spin_lock(&dq_list_lock);
|
spin_lock(&dq_list_lock);
|
||||||
}
|
}
|
||||||
|
@ -638,7 +642,21 @@ int dquot_quota_sync(struct super_block *sb, int type, int wait)
|
||||||
dqstats_inc(DQST_SYNCS);
|
dqstats_inc(DQST_SYNCS);
|
||||||
mutex_unlock(&dqopt->dqonoff_mutex);
|
mutex_unlock(&dqopt->dqonoff_mutex);
|
||||||
|
|
||||||
if (!wait || (dqopt->flags & DQUOT_QUOTA_SYS_FILE))
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(dquot_writeback_dquots);
|
||||||
|
|
||||||
|
/* Write all dquot structures to disk and make them visible from userspace */
|
||||||
|
int dquot_quota_sync(struct super_block *sb, int type)
|
||||||
|
{
|
||||||
|
struct quota_info *dqopt = sb_dqopt(sb);
|
||||||
|
int cnt;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = dquot_writeback_dquots(sb, type);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
if (dqopt->flags & DQUOT_QUOTA_SYS_FILE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* This is not very clever (and fast) but currently I don't know about
|
/* This is not very clever (and fast) but currently I don't know about
|
||||||
|
|
|
@ -47,7 +47,7 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
|
||||||
static void quota_sync_one(struct super_block *sb, void *arg)
|
static void quota_sync_one(struct super_block *sb, void *arg)
|
||||||
{
|
{
|
||||||
if (sb->s_qcop && sb->s_qcop->quota_sync)
|
if (sb->s_qcop && sb->s_qcop->quota_sync)
|
||||||
sb->s_qcop->quota_sync(sb, *(int *)arg, 1);
|
sb->s_qcop->quota_sync(sb, *(int *)arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int quota_sync_all(int type)
|
static int quota_sync_all(int type)
|
||||||
|
@ -270,7 +270,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
|
||||||
case Q_SYNC:
|
case Q_SYNC:
|
||||||
if (!sb->s_qcop->quota_sync)
|
if (!sb->s_qcop->quota_sync)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
return sb->s_qcop->quota_sync(sb, type, 1);
|
return sb->s_qcop->quota_sync(sb, type);
|
||||||
case Q_XQUOTAON:
|
case Q_XQUOTAON:
|
||||||
case Q_XQUOTAOFF:
|
case Q_XQUOTAOFF:
|
||||||
case Q_XQUOTARM:
|
case Q_XQUOTARM:
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
static int __sync_filesystem(struct super_block *sb, int wait)
|
static int __sync_filesystem(struct super_block *sb, int wait)
|
||||||
{
|
{
|
||||||
if (sb->s_qcop && sb->s_qcop->quota_sync)
|
if (sb->s_qcop && sb->s_qcop->quota_sync)
|
||||||
sb->s_qcop->quota_sync(sb, -1, wait);
|
sb->s_qcop->quota_sync(sb, -1);
|
||||||
|
|
||||||
if (wait)
|
if (wait)
|
||||||
sync_inodes_sb(sb);
|
sync_inodes_sb(sb);
|
||||||
|
|
|
@ -333,7 +333,7 @@ struct quotactl_ops {
|
||||||
int (*quota_on)(struct super_block *, int, int, struct path *);
|
int (*quota_on)(struct super_block *, int, int, struct path *);
|
||||||
int (*quota_on_meta)(struct super_block *, int, int);
|
int (*quota_on_meta)(struct super_block *, int, int);
|
||||||
int (*quota_off)(struct super_block *, int);
|
int (*quota_off)(struct super_block *, int);
|
||||||
int (*quota_sync)(struct super_block *, int, int);
|
int (*quota_sync)(struct super_block *, int);
|
||||||
int (*get_info)(struct super_block *, int, struct if_dqinfo *);
|
int (*get_info)(struct super_block *, int, struct if_dqinfo *);
|
||||||
int (*set_info)(struct super_block *, int, struct if_dqinfo *);
|
int (*set_info)(struct super_block *, int, struct if_dqinfo *);
|
||||||
int (*get_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *);
|
int (*get_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *);
|
||||||
|
|
|
@ -83,7 +83,8 @@ int dquot_quota_on(struct super_block *sb, int type, int format_id,
|
||||||
int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
|
int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
|
||||||
int format_id, int type);
|
int format_id, int type);
|
||||||
int dquot_quota_off(struct super_block *sb, 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_writeback_dquots(struct super_block *sb, int type);
|
||||||
|
int dquot_quota_sync(struct super_block *sb, int type);
|
||||||
int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
|
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_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,
|
int dquot_get_dqblk(struct super_block *sb, int type, qid_t id,
|
||||||
|
@ -255,6 +256,11 @@ static inline int dquot_resume(struct super_block *sb, int type)
|
||||||
|
|
||||||
#define dquot_file_open generic_file_open
|
#define dquot_file_open generic_file_open
|
||||||
|
|
||||||
|
static inline int dquot_writeback_dquots(struct super_block *sb, int type)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_QUOTA */
|
#endif /* CONFIG_QUOTA */
|
||||||
|
|
||||||
static inline int dquot_alloc_space_nodirty(struct inode *inode, qsize_t nr)
|
static inline int dquot_alloc_space_nodirty(struct inode *inode, qsize_t nr)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче