libquota: quota file read support
PATCH 1/3 libquota: quota file read support
This patch adds read quota file support, which includes:
- Improve scan dquot APIs & fix defects in scan dquot functions;
- Implement quota_file_open();
- Introduce quota_update_inode() to update usage in old quota file, and keep the limits unchanged.
Signed-off-by Niu Yawei <[email protected]>
--- lib/quota/mkquota.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++ lib/quota/mkquota.h | 1 + lib/quota/quotaio.c | 46 ++++++++++++++++++++- lib/quota/quotaio.h | 6 ++- lib/quota/quotaio_tree.c | 25 ++++++++---- lib/quota/quotaio_tree.h | 2 +- lib/quota/quotaio_v2.c | 20 ++++++++-- 7 files changed, 179 insertions(+), 18 deletions(-)
lib/quota/mkquota.c +97 -0
@@ -413,3 +413,100 @@ errcode_t quota_compute_usage(quota_ctx_t qctx)return 0 ; } + +struct scan_dquots_data { +quota_ctx_t qctx; +int limit_only;/* read limit only */ +}; + +static int scan_dquots_callback (struct dquot *dquot,void *cb_data) +{ +struct scan_dquots_data *scan_data = + (struct scan_dquots_data *)cb_data; +quota_ctx_t qctx = scan_data->qctx; +struct dquot *dq; + + dq =get_dq (qctx->quota_dict[dquot->dq_h->qh_type], dquot->dq_id); + + dq->dq_id = dquot->dq_id; +if (scan_data->limit_only) { + dq->dq_dqb.u.v2_mdqb.dqb_off = dquot->dq_dqb.u.v2_mdqb.dqb_off; + dq->dq_dqb.dqb_ihardlimit = dquot->dq_dqb.dqb_ihardlimit; + dq->dq_dqb.dqb_isoftlimit = dquot->dq_dqb.dqb_isoftlimit; + dq->dq_dqb.dqb_bhardlimit = dquot->dq_dqb.dqb_bhardlimit; + dq->dq_dqb.dqb_bsoftlimit = dquot->dq_dqb.dqb_bsoftlimit; + }else { + dq->dq_dqb = dquot->dq_dqb; + } +return 0 ; +} + +/* +* Read all dquots from quota file into memory +*/ +static errcode_t quota_read_all_dquots (struct quota_handle *qh, +quota_ctx_t qctx,int limit_only) +{ +struct scan_dquots_data scan_data; + + scan_data.qctx = qctx; + scan_data.limit_only = limit_only; + +return qh->qh_ops->scan_dquots (qh, scan_dquots_callback, &scan_data); +} + +/* +* Write all memory dquots into quota file +*/ +static errcode_t quota_write_all_dquots (struct quota_handle *qh, +quota_ctx_t qctx) +{ +errcode_t err; + + err =ext2fs_read_bitmaps (qctx->fs); +if (err) +return err; +write_dquots (qctx->quota_dict[qh->qh_type], qh); +ext2fs_mark_bb_dirty (qctx->fs); + qctx->fs->flags &= ~EXT2_FLAG_SUPER_ONLY ; +ext2fs_write_bitmaps (qctx->fs); +return 0 ; +} + +/* +* Update usage of in quota file, limits keep unchaged +*/ +errcode_t quota_update_inode (quota_ctx_t qctx,ext2_ino_t qf_ino,int type) +{ +struct quota_handle *qh; +errcode_t err; + +if (!qctx) +return 0 ; + + err =ext2fs_get_mem (sizeof (struct quota_handle ), &qh); +if (err) { +log_err ("Unable to allocate quota handle" ,"" ); +return err; + } + + err =quota_file_open (qh, qctx->fs, qf_ino, type,-1 ,EXT2_FILE_WRITE ); +if (err) { +log_err ("Open quota file failed" ,"" ); + goto out; + } + +quota_read_all_dquots (qh, qctx,1 ); +quota_write_all_dquots (qh, qctx); + + err =quota_file_close (qh); +if (err) { +log_err ("Cannot finish IO on new quotafile: %s" , +strerror (errno)); +if (qh->qh_qf.e2_file) +ext2fs_file_close (qh->qh_qf.e2_file); + } +out: +ext2fs_free_mem (&qh); +return err; +}
lib/quota/mkquota.h +1 -0
@@ -51,6 +51,7 @@ void quota_data_add(quota_ctx_t qctx, struct ext2_inode *inode, ext2_ino_t ino,void quota_data_sub (quota_ctx_t qctx,struct ext2_inode *inode,ext2_ino_t ino,qsize_t space);errcode_t quota_write_inode (quota_ctx_t qctx,int qtype); +errcode_t quota_update_inode (quota_ctx_t qctx,ext2_ino_t qf_ino,int type);errcode_t quota_compute_usage (quota_ctx_t qctx);void quota_release_context (quota_ctx_t *qctx);
lib/quota/quotaio.c +43 -3
53 lines not on this page · raw message
lib/quota/quotaio.h +4 -2
@@ -120,7 +120,8 @@ struct quotafile_ops {/* Scan quotafile and call callback on every structure */ int (*scan_dquots) (struct quota_handle *h,int (*process_dquot) (struct dquot *dquot, -char *dqname)); +void *data), +void *data);/* Function to print format specific file information */ int (*report) (struct quota_handle *h,int verbose); };
@@ -139,7 +140,8 @@ static inline void mark_quotafile_info_dirty(struct quota_handle *h)/* Open existing quotafile of given type (and verify its format) on given * filesystem. */ errcode_t quota_file_open (struct quota_handle *h,ext2_filsys fs, -int type,int fmt,int flags); +ext2_ino_t qf_ino,int type,int fmt,int flags); +/* Create new quotafile of specified format on given filesystem */ errcode_t quota_file_create(struct quota_handle *h, ext2_filsys fs,
lib/quota/quotaio_tree.c +17 -8
@@ -537,7 +537,8 @@ struct dquot *qtree_read_dquot(struct quota_handle *h, qid_t id)#define get_bit (bmp, ind) ((bmp)[(ind) >> 3] & (1 << ((ind) & 7)))static int report_block (struct dquot *dquot,uint blk,char *bitmap, -int (*process_dquot) (struct dquot *,char *)) +int (*process_dquot) (struct dquot *,void *), +void *data) {struct qtree_mem_dqinfo *info = &dquot->dq_h->qh_info.u.v2_mdqi.dqi_qtree;
@@ -557,8 +558,12 @@ static int report_block(struct dquot *dquot, uint blk, char *bitmap,for (i =0 ; i <qtree_dqstr_in_blk (info); i++, ddata += info->dqi_entry_size)if (!qtree_entry_unused (info, ddata)) { + dquot->dq_dqb.u.v2_mdqb.dqb_off = + (blk <<QT_BLKSIZE_BITS ) + +sizeof (struct qt_disk_dqdbheader ) + + i * info->dqi_entry_size; info->dqi_ops->disk2mem_dqblk (dquot, ddata); -if (process_dquot (dquot,NULL ) <0 ) +if (process_dquot (dquot, data) <0 )break ; }freedqbuf (buf);
@@ -577,7 +582,8 @@ static void check_reference(struct quota_handle *h, uint blk) }static int report_tree (struct dquot *dquot,uint blk,int depth,char *bitmap, -int (*process_dquot) (struct dquot *,char *)) +int (*process_dquot) (struct dquot *,void *), +void *data) {int entries =0 , i;dqbuf_t buf =getdqbuf ();
@@ -593,16 +599,18 @@ static int report_tree(struct dquot *dquot, uint blk, int depth, char *bitmap,check_reference (dquot->dq_h, blk);if (blk && !get_bit (bitmap, blk)) entries +=report_block (dquot, blk, bitmap, - process_dquot); + process_dquot, data); } }else { -for (i =0 ; i <QT_BLKSIZE >>2 ; i++) +for (i =0 ; i <QT_BLKSIZE >>2 ; i++) { blk =ext2fs_le32_to_cpu (ref[i]);if (blk) {check_reference (dquot->dq_h, blk); entries +=report_tree (dquot, blk, depth +1 , - bitmap, process_dquot); + bitmap, process_dquot, + data); } + } }freedqbuf (buf);return entries;
@@ -619,7 +627,8 @@ static uint find_set_bits(char *bmp, int blocks) }int qtree_scan_dquots (struct quota_handle *h, -int (*process_dquot) (struct dquot *,char *)) +int (*process_dquot) (struct dquot *,void *), +void *data) {char *bitmap;struct v2_mem_dqinfo *v2info = &h->qh_info.u.v2_mdqi;
@@ -635,7 +644,7 @@ int qtree_scan_dquots(struct quota_handle *h,return -1 ; } v2info->dqi_used_entries =report_tree (dquot,QT_TREEOFF ,0 , bitmap, - process_dquot); + process_dquot, data); v2info->dqi_data_blocks =find_set_bits (bitmap, info->dqi_blocks);ext2fs_free_mem (&bitmap);ext2fs_free_mem (&dquot);
lib/quota/quotaio_tree.h +1 -1
@@ -56,7 +56,7 @@ struct dquot *qtree_read_dquot(struct quota_handle *h, qid_t id);void qtree_delete_dquot (struct dquot *dquot);int qtree_entry_unused (struct qtree_mem_dqinfo *info,char *disk);int qtree_scan_dquots (struct quota_handle *h, -int (*process_dquot) (struct dquot *,char *)); +int (*process_dquot) (struct dquot *,void *),void *data);int qtree_dqstr_in_blk (struct qtree_mem_dqinfo *info);
lib/quota/quotaio_v2.c +16 -4
@@ -28,7 +28,8 @@ static struct dquot *v2_read_dquot(struct quota_handle *h, qid_t id);static int v2_commit_dquot (struct dquot *dquot);static int v2_scan_dquots (struct quota_handle *h,int (*process_dquot) (struct dquot *dquot, -char *dqname)); +void *data), +void *data);static int v2_report (struct quota_handle *h,int verbose);struct quotafile_ops quotafile_ops_2 = {
@@ -213,7 +214,17 @@ static int v2_check_file(struct quota_handle *h, int type, int fmt)*/ static int v2_init_io (struct quota_handle *h) { -log_err ("Not Implemented." ,"" ); +struct v2_disk_dqinfo ddqinfo; + + h->qh_info.u.v2_mdqi.dqi_qtree.dqi_entry_size = +sizeof (struct v2r1_disk_dqblk ); + h->qh_info.u.v2_mdqi.dqi_qtree.dqi_ops = &v2r1_fmt_ops; + +/* Read information about quotafile */ +if (h->e2fs_read (&h->qh_qf,V2_DQINFOOFF , &ddqinfo, +sizeof (ddqinfo)) !=sizeof (ddqinfo)) +return -1 ; +v2_disk2memdqinfo (&h->qh_info, &ddqinfo);return 0 ; }
@@ -297,9 +308,10 @@ static int v2_commit_dquot(struct dquot *dquot) }static int v2_scan_dquots (struct quota_handle *h, -int (*process_dquot) (struct dquot *,char *)) +int (*process_dquot) (struct dquot *,void *), +void *data) { -return qtree_scan_dquots (h, process_dquot); +return qtree_scan_dquots (h, process_dquot, data); }/* Report information about quotafile.
-- 1.7.1
Ted Ts'o
AppliedQuoted 7 lines · Niu
This patch adds read quota file support, which includes:
- Improve scan dquot APIs & fix defects in scan dquot functions;
- Implementquota_file_open();
- Introducequota_update_inode()to update usage in old quota file, and keep the limits unchanged.Signed-off-by Niu Yawei <[email protected]>
Thanks, applied.
- Ted