From 0810df383cc006f8a06adbd3c262367bd9d9472a Mon Sep 17 00:00:00 2001 From: Johann Lombardi Date: Thu, 27 Sep 2012 15:55:53 +0200 Subject: [PATCH] LU-1842 quota: remove quota code from lvfs This patch removes the quota code from the lvfs directory. Most of this code has already been moved to ldiskfs OSD. This patch also removes the dt_init_quota_ctxt which isn't used any more. Signed-off-by: Johann Lombardi Change-Id: I6ab6a26ae877d5c0bebab674204f7d36f9d83078 Reviewed-on: http://review.whamcloud.com/4110 Reviewed-by: Alex Zhuravlev Reviewed-by: Niu Yawei Tested-by: Hudson Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/include/dt_object.h | 7 - lustre/include/linux/lustre_fsfilt.h | 64 -- lustre/lvfs/Makefile.in | 9 +- lustre/lvfs/fsfilt_ext3.c | 812 +----------------------- lustre/lvfs/lustre_quota_fmt.c | 1124 ---------------------------------- lustre/lvfs/lustre_quota_fmt.h | 193 ------ lustre/lvfs/quotafmt_test.c | 498 --------------- lustre/osd-ldiskfs/osd_handler.c | 20 - 8 files changed, 3 insertions(+), 2724 deletions(-) delete mode 100644 lustre/lvfs/lustre_quota_fmt.c delete mode 100644 lustre/lvfs/lustre_quota_fmt.h delete mode 100644 lustre/lvfs/quotafmt_test.c diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h index 3c342a8..b1fbda0 100644 --- a/lustre/include/dt_object.h +++ b/lustre/include/dt_object.h @@ -65,7 +65,6 @@ struct thandle; struct dt_device; struct dt_object; struct dt_index_features; -struct dt_quota_ctxt; struct niobuf_local; struct niobuf_remote; @@ -174,12 +173,6 @@ struct dt_device_operations { struct dt_device *dev, int mode, unsigned long timeout, __u32 alg, struct lustre_capa_key *keys); - /** - * Initialize quota context. - */ - void (*dt_init_quota_ctxt)(const struct lu_env *env, - struct dt_device *dev, - struct dt_quota_ctxt *ctxt, void *data); }; struct dt_index_features { diff --git a/lustre/include/linux/lustre_fsfilt.h b/lustre/include/linux/lustre_fsfilt.h index a83a03b..3eddc33 100644 --- a/lustre/include/linux/lustre_fsfilt.h +++ b/lustre/include/linux/lustre_fsfilt.h @@ -114,19 +114,8 @@ struct fsfilt_operations { int (* fs_read_record)(struct file *, void *, int size, loff_t *); int (* fs_setup)(struct super_block *sb); int (* fs_get_op_len)(int, struct fsfilt_objinfo *, int); - int (* fs_quotacheck)(struct super_block *sb, - struct obd_quotactl *oqctl); __u64 (* fs_get_version) (struct inode *inode); __u64 (* fs_set_version) (struct inode *inode, __u64 new_version); - int (* fs_quotactl)(struct super_block *sb, - struct obd_quotactl *oqctl); - int (* fs_quotainfo)(struct lustre_quota_info *lqi, int type, - int cmd); - int (* fs_qids)(struct file *file, struct inode *inode, int type, - cfs_list_t *list); - int (* fs_get_mblk)(struct super_block *sb, int *count, - struct inode *inode, int frags); - int (* fs_dquot)(struct lustre_dquot *dquot, int cmd); lvfs_sbdev_type (* fs_journal_sbdev)(struct super_block *sb); struct dentry *(* fs_fid2dentry)(struct vfsmount *mnt, struct fsfilt_fid *fid, @@ -413,59 +402,6 @@ static inline int fsfilt_sync(struct obd_device *obd, struct super_block *sb) return obd->obd_fsops->fs_sync(sb); } -static inline int fsfilt_quotacheck(struct obd_device *obd, - struct super_block *sb, - struct obd_quotactl *oqctl) -{ - if (obd->obd_fsops->fs_quotacheck) - return obd->obd_fsops->fs_quotacheck(sb, oqctl); - return -ENOTSUPP; -} - -static inline int fsfilt_quotactl(struct obd_device *obd, - struct super_block *sb, - struct obd_quotactl *oqctl) -{ - if (obd->obd_fsops->fs_quotactl) - return obd->obd_fsops->fs_quotactl(sb, oqctl); - return -ENOTSUPP; -} - -static inline int fsfilt_quotainfo(struct obd_device *obd, - struct lustre_quota_info *lqi, - int type, int cmd) -{ - if (obd->obd_fsops->fs_quotainfo) - return obd->obd_fsops->fs_quotainfo(lqi, type, cmd); - return -ENOTSUPP; -} - -static inline int fsfilt_qids(struct obd_device *obd, struct file *file, - struct inode *inode, int type, - cfs_list_t *list) -{ - if (obd->obd_fsops->fs_qids) - return obd->obd_fsops->fs_qids(file, inode, type, list); - return -ENOTSUPP; -} - -static inline int fsfilt_dquot(struct obd_device *obd, - struct lustre_dquot *dquot, int cmd) -{ - if (obd->obd_fsops->fs_dquot) - return obd->obd_fsops->fs_dquot(dquot, cmd); - return -ENOTSUPP; -} - -static inline int fsfilt_get_mblk(struct obd_device *obd, - struct super_block *sb, int *count, - struct inode *inode, int frags) -{ - if (obd->obd_fsops->fs_get_mblk) - return obd->obd_fsops->fs_get_mblk(sb, count, inode, frags); - return -ENOTSUPP; -} - static inline int fsfilt_map_inode_pages(struct obd_device *obd, struct inode *inode, struct page **page, int pages, diff --git a/lustre/lvfs/Makefile.in b/lustre/lvfs/Makefile.in index f1f5c2f..48b61b6 100644 --- a/lustre/lvfs/Makefile.in +++ b/lustre/lvfs/Makefile.in @@ -1,21 +1,16 @@ MODULES := lvfs @SERVER_TRUE@MODULES += fsfilt_ldiskfs -@SERVER_TRUE@MODULES += quotafmt_test lvfs-objs := lvfs_common.o lvfs_linux.o fsfilt.o lvfs_lib.o -@SERVER_TRUE@quotafmt-objs := quotafmt_test.o - fsfilt_ldiskfs-objs := fsfilt-ldiskfs.o -@SERVER_TRUE@fsfilt_ldiskfs-objs += lustre_quota_fmt.o $(obj)/fsfilt-%.c: $(obj)/fsfilt_%.c ln -s $< $@ -EXTRA_DIST = $(lvfs-objs:.o=.c) $(quotafmt-objs:.o=.c) \ +EXTRA_DIST = $(lvfs-objs:.o=.c) \ fsfilt_ext3.c \ - lvfs_internal.h lvfs_userfs.c \ - lustre_quota_fmt.c lustre_quota_fmt.h quotafmt_test.c + lvfs_internal.h lvfs_userfs.c # for on 2.6 EXTRA_PRE_CFLAGS := -I@LINUX@/fs -I@LDISKFS_DIR@ -I@LDISKFS_DIR@/ldiskfs diff --git a/lustre/lvfs/fsfilt_ext3.c b/lustre/lvfs/fsfilt_ext3.c index 6f72da5..c31a5a0 100644 --- a/lustre/lvfs/fsfilt_ext3.c +++ b/lustre/lvfs/fsfilt_ext3.c @@ -54,24 +54,6 @@ #include #include #include -#ifdef HAVE_QUOTAIO_H -# include -#elif defined(HAVE_FS_QUOTA_QUOTAIO_H) -# include -# include -# define V2_DQTREEOFF QT_TREEOFF -#elif defined(HAVE_FS_QUOTAIO_H) -# include -# include -# define V2_DQTREEOFF QT_TREEOFF -# define V2_INITQVERSIONS_R1 V2_INITQVERSIONS -#endif - -#ifdef QFMT_VFS_V1 -#define QFMT_LUSTRE QFMT_VFS_V1 -#else -#define QFMT_LUSTRE QFMT_VFS_V0 -#endif #if defined(HAVE_EXT3_XATTR_H) # include @@ -86,14 +68,11 @@ extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *, #include #include #include -#include #include #include #include -#include "lustre_quota_fmt.h" - /* for kernels 2.6.18 and later */ #define FSFILT_SINGLEDATA_TRANS_BLOCKS(sb) EXT3_SINGLEDATA_TRANS_BLOCKS(sb) @@ -1404,795 +1383,12 @@ static int fsfilt_ext3_get_op_len(int op, struct fsfilt_objinfo *fso, int logs) return 0; } -#define DQINFO_COPY(out, in) \ -do { \ - Q_COPY(out, in, dqi_bgrace); \ - Q_COPY(out, in, dqi_igrace); \ - Q_COPY(out, in, dqi_flags); \ - Q_COPY(out, in, dqi_valid); \ -} while (0) - -#define DQBLK_COPY(out, in) \ -do { \ - Q_COPY(out, in, dqb_bhardlimit); \ - Q_COPY(out, in, dqb_bsoftlimit); \ - Q_COPY(out, in, dqb_curspace); \ - Q_COPY(out, in, dqb_ihardlimit); \ - Q_COPY(out, in, dqb_isoftlimit); \ - Q_COPY(out, in, dqb_curinodes); \ - Q_COPY(out, in, dqb_btime); \ - Q_COPY(out, in, dqb_itime); \ - Q_COPY(out, in, dqb_valid); \ -} while (0) - -static int fsfilt_ext3_quotactl(struct super_block *sb, - struct obd_quotactl *oqc) -{ - int i, rc = 0, error = 0; - const struct quotactl_ops *qcop; - struct if_dqinfo *info; - struct if_dqblk *dqblk; - ENTRY; - - if (!sb->s_qcop) - RETURN(-ENOSYS); - - OBD_ALLOC_PTR(info); - if (!info) - RETURN(-ENOMEM); - OBD_ALLOC_PTR(dqblk); - if (!dqblk) { - OBD_FREE_PTR(info); - RETURN(-ENOMEM); - } - - DQINFO_COPY(info, &oqc->qc_dqinfo); - DQBLK_COPY(dqblk, &oqc->qc_dqblk); - - qcop = sb->s_qcop; - if (oqc->qc_cmd == Q_QUOTAON || oqc->qc_cmd == Q_QUOTAOFF) { - for (i = 0; i < MAXQUOTAS; i++) { - if (!Q_TYPESET(oqc, i)) - continue; - - if (oqc->qc_cmd == Q_QUOTAON) { - char *name[MAXQUOTAS] = LUSTRE_OPQFILES_NAMES_V2; - - LASSERT(oqc->qc_id == LUSTRE_QUOTA_V2); - - rc = ll_quota_on(sb, i, QFMT_LUSTRE, - name[i], 0); - } else if (oqc->qc_cmd == Q_QUOTAOFF) { - rc = ll_quota_off(sb, i, 0); - } - - if (rc == -EBUSY) - error = rc; - else if (rc) - GOTO(out, rc); - } - GOTO(out, rc ?: error); - } - - switch (oqc->qc_cmd) { - case Q_GETOINFO: - case Q_GETINFO: - if (!qcop->get_info) - GOTO(out, rc = -ENOSYS); - rc = qcop->get_info(sb, oqc->qc_type, info); - break; - case Q_SETQUOTA: - case Q_INITQUOTA: - if (!qcop->set_dqblk) - GOTO(out, rc = -ENOSYS); - rc = qcop->set_dqblk(sb, oqc->qc_type, oqc->qc_id, dqblk); - break; - case Q_GETOQUOTA: - case Q_GETQUOTA: - if (!qcop->get_dqblk) - GOTO(out, rc = -ENOSYS); - rc = qcop->get_dqblk(sb, oqc->qc_type, oqc->qc_id, dqblk); - if (!rc) - dqblk->dqb_valid = QIF_LIMITS | QIF_USAGE; - break; - case Q_SYNC: - if (!sb->s_qcop->quota_sync) - GOTO(out, rc = -ENOSYS); - qcop->quota_sync(sb, oqc->qc_type); - break; - case Q_FINVALIDATE: - CDEBUG(D_WARNING, "invalidating operational quota files\n"); - for (i = 0; i < MAXQUOTAS; i++) { - struct file *fp; - char *name[MAXQUOTAS] = LUSTRE_OPQFILES_NAMES_V2; - - LASSERT(oqc->qc_id == LUSTRE_QUOTA_V2); - - if (!Q_TYPESET(oqc, i)) - continue; - - fp = filp_open(name[i], O_CREAT | O_TRUNC | O_RDWR, 0644); - if (IS_ERR(fp)) { - rc = PTR_ERR(fp); - CERROR("error invalidating operational quota file" - " %s (rc:%d)\n", name[i], rc); - } else { - filp_close(fp, 0); - } - - } - break; - default: - CERROR("unsupported quotactl command: %d\n", oqc->qc_cmd); - LBUG(); - } -out: - DQINFO_COPY(&oqc->qc_dqinfo, info); - DQBLK_COPY(&oqc->qc_dqblk, dqblk); - - OBD_FREE_PTR(info); - OBD_FREE_PTR(dqblk); - - if (rc) - CDEBUG(D_QUOTA, "quotactl command %#x, id %u, type %u " - "failed: %d\n", - oqc->qc_cmd, oqc->qc_id, oqc->qc_type, rc); - RETURN(rc); -} - -struct chk_dqblk{ - cfs_hlist_node_t dqb_hash; /** quotacheck hash */ - cfs_list_t dqb_list; /** in list also */ - qid_t dqb_id; /** uid/gid */ - short dqb_type; /** USRQUOTA/GRPQUOTA */ - qsize_t dqb_bhardlimit; /** block hard limit */ - qsize_t dqb_bsoftlimit; /** block soft limit */ - qsize_t dqb_curspace; /** current space */ - qsize_t dqb_ihardlimit; /** inode hard limit */ - qsize_t dqb_isoftlimit; /** inode soft limit */ - qsize_t dqb_curinodes; /** current inodes */ - obd_time dqb_btime; /** block grace time */ - obd_time dqb_itime; /** inode grace time */ - __u32 dqb_valid; /** flag for above fields */ -}; - -static inline unsigned int chkquot_hash(qid_t id, int type) - __attribute__((__const__)); - -static inline unsigned int chkquot_hash(qid_t id, int type) -{ - return (id * (MAXQUOTAS - type)) % NR_DQHASH; -} - -static inline struct chk_dqblk * -find_chkquot(cfs_hlist_head_t *head, qid_t id, int type) -{ - cfs_hlist_node_t *node; - struct chk_dqblk *cdqb; - - cfs_hlist_for_each(node, head) { - cdqb = cfs_hlist_entry(node, struct chk_dqblk, dqb_hash); - if (cdqb->dqb_id == id && cdqb->dqb_type == type) - return cdqb; - } - - return NULL; -} - -static struct chk_dqblk *alloc_chkquot(qid_t id, int type) -{ - struct chk_dqblk *cdqb; - - OBD_ALLOC_PTR(cdqb); - if (cdqb) { - CFS_INIT_HLIST_NODE(&cdqb->dqb_hash); - CFS_INIT_LIST_HEAD(&cdqb->dqb_list); - cdqb->dqb_id = id; - cdqb->dqb_type = type; - } - - return cdqb; -} - -static struct chk_dqblk * -cqget(struct super_block *sb, cfs_hlist_head_t *hash, - cfs_list_t *list, qid_t id, int type, int first_check) -{ - cfs_hlist_head_t *head = hash + chkquot_hash(id, type); - struct if_dqblk dqb; - struct chk_dqblk *cdqb; - int rc; - - cdqb = find_chkquot(head, id, type); - if (cdqb) - return cdqb; - - cdqb = alloc_chkquot(id, type); - if (!cdqb) - return NULL; - - if (!first_check) { - rc = sb->s_qcop->get_dqblk(sb, type, id, &dqb); - if (rc) { - CERROR("get_dqblk of id %u, type %d failed: %d\n", - id, type, rc); - } else { - DQBLK_COPY(cdqb, &dqb); - cdqb->dqb_curspace = 0; - cdqb->dqb_curinodes = 0; - } - } - - cfs_hlist_add_head(&cdqb->dqb_hash, head); - cfs_list_add_tail(&cdqb->dqb_list, list); - - return cdqb; -} - -static inline int quota_onoff(struct super_block *sb, int cmd, int type, int qfmt) -{ - struct obd_quotactl *oqctl; - int rc; - - OBD_ALLOC_PTR(oqctl); - if (!oqctl) - RETURN(-ENOMEM); - - oqctl->qc_cmd = cmd; - oqctl->qc_id = qfmt; - oqctl->qc_type = type; - rc = fsfilt_ext3_quotactl(sb, oqctl); - - OBD_FREE_PTR(oqctl); - return rc; -} - -static inline int read_old_dqinfo(struct super_block *sb, int type, - struct if_dqinfo *dqinfo) -{ - struct obd_quotactl *oqctl; - int rc; - ENTRY; - - OBD_ALLOC_PTR(oqctl); - if (!oqctl) - RETURN(-ENOMEM); - - oqctl->qc_cmd = Q_GETINFO; - oqctl->qc_type = type; - rc = fsfilt_ext3_quotactl(sb, oqctl); - if (!rc) - ((struct obd_dqinfo *)dqinfo)[type] = oqctl->qc_dqinfo; - - OBD_FREE_PTR(oqctl); - RETURN(rc); -} - -struct qchk_ctxt { - cfs_hlist_head_t qckt_hash[NR_DQHASH]; /* quotacheck hash */ - cfs_list_t qckt_list; /* quotacheck list */ - int qckt_first_check[MAXQUOTAS]; /* 1 if no old quotafile */ - struct if_dqinfo qckt_dqinfo[MAXQUOTAS]; /* old dqinfo */ -}; - -static int add_inode_quota(struct inode *inode, struct qchk_ctxt *qctxt, - struct obd_quotactl *oqc) -{ - struct chk_dqblk *cdqb[MAXQUOTAS] = { NULL, }; - loff_t size = 0; - qid_t qid[MAXQUOTAS]; - int cnt, i, rc = 0; - - if (!inode) - return 0; - - qid[USRQUOTA] = inode->i_uid; - qid[GRPQUOTA] = inode->i_gid; - - if (S_ISDIR(inode->i_mode) || - S_ISREG(inode->i_mode) || - S_ISLNK(inode->i_mode)) - size = inode_get_bytes(inode); - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (!Q_TYPESET(oqc, cnt)) - continue; - - cdqb[cnt] = cqget(inode->i_sb, qctxt->qckt_hash, - &qctxt->qckt_list, qid[cnt], cnt, - qctxt->qckt_first_check[cnt]); - if (!cdqb[cnt]) { - rc = -ENOMEM; - break; - } - - cdqb[cnt]->dqb_curspace += size; - cdqb[cnt]->dqb_curinodes++; - } - - if (rc) { - for (i = 0; i < cnt; i++) { - if (!Q_TYPESET(oqc, i)) - continue; - LASSERT(cdqb[i]); - cdqb[i]->dqb_curspace -= size; - cdqb[i]->dqb_curinodes--; - } - } - - return rc; -} - -/* write dqinfo struct in a new quota file */ -static int v3_write_dqinfo(struct file *f, int type, struct if_dqinfo *info) -{ - struct v2_disk_dqinfo dqinfo; - __u32 blocks = V2_DQTREEOFF + 1; - loff_t offset = V2_DQINFOOFF; - - if (info) { - dqinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace); - dqinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace); - dqinfo.dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK & - ~DQF_INFO_DIRTY); - } else { - dqinfo.dqi_bgrace = cpu_to_le32(MAX_DQ_TIME); - dqinfo.dqi_igrace = cpu_to_le32(MAX_IQ_TIME); - dqinfo.dqi_flags = 0; - } - - dqinfo.dqi_blocks = cpu_to_le32(blocks); - dqinfo.dqi_free_blk = 0; - dqinfo.dqi_free_entry = 0; - - return cfs_user_write(f, (char *)&dqinfo, sizeof(dqinfo), &offset); -} - -static int v3_write_dqheader(struct file *f, int type) -{ - static const __u32 quota_magics[] = V2_INITQMAGICS; - static const __u32 quota_versions[] = LUSTRE_INITQVERSIONS_V2; - struct v2_disk_dqheader dqhead; - loff_t offset = 0; - - CLASSERT(ARRAY_SIZE(quota_magics) == ARRAY_SIZE(quota_versions)); - LASSERT(0 <= type && type < ARRAY_SIZE(quota_magics)); - - dqhead.dqh_magic = cpu_to_le32(quota_magics[type]); - dqhead.dqh_version = cpu_to_le32(quota_versions[type]); - - return cfs_user_write(f, (char *)&dqhead, sizeof(dqhead), &offset); -} - -static int create_new_quota_files(struct qchk_ctxt *qctxt, - struct obd_quotactl *oqc) -{ - int i, rc = 0; - ENTRY; - - for (i = 0; i < MAXQUOTAS; i++) { - struct if_dqinfo *info = qctxt->qckt_first_check[i]? - NULL : &qctxt->qckt_dqinfo[i]; - struct file *file; - const char *name[MAXQUOTAS] = LUSTRE_OPQFILES_NAMES_V2; - - if (!Q_TYPESET(oqc, i)) - continue; - - LASSERT(oqc->qc_id == LUSTRE_QUOTA_V2); - - file = filp_open(name[i], O_RDWR | O_CREAT | O_TRUNC, 0644); - if (IS_ERR(file)) { - rc = PTR_ERR(file); - CERROR("can't create %s file: rc = %d\n", - name[i], rc); - GOTO(out, rc); - } - - if (!S_ISREG(file->f_dentry->d_inode->i_mode)) { - CERROR("file %s is not regular", name[i]); - filp_close(file, 0); - GOTO(out, rc = -EINVAL); - } - - ll_vfs_dq_drop(file->f_dentry->d_inode); - - rc = v3_write_dqheader(file, i); - if (rc) { - filp_close(file, 0); - GOTO(out, rc); - } - - rc = v3_write_dqinfo(file, i, info); - filp_close(file, 0); - if (rc) - GOTO(out, rc); - } - -out: - RETURN(rc); -} - - -static int commit_chkquot(struct super_block *sb, struct qchk_ctxt *qctxt, - struct chk_dqblk *cdqb) -{ - struct obd_quotactl *oqc; - long now; - int rc; - ENTRY; - - OBD_ALLOC_PTR(oqc); - if (!oqc) - RETURN(-ENOMEM); - - now = cfs_time_current_sec(); - - if (cdqb->dqb_bsoftlimit && - toqb(cdqb->dqb_curspace) >= cdqb->dqb_bsoftlimit && - !cdqb->dqb_btime) - cdqb->dqb_btime = - now + qctxt->qckt_dqinfo[cdqb->dqb_type].dqi_bgrace; - - if (cdqb->dqb_isoftlimit && - cdqb->dqb_curinodes >= cdqb->dqb_isoftlimit && - !cdqb->dqb_itime) - cdqb->dqb_itime = - now + qctxt->qckt_dqinfo[cdqb->dqb_type].dqi_igrace; - - cdqb->dqb_valid = QIF_ALL; - - oqc->qc_cmd = Q_SETQUOTA; - oqc->qc_type = cdqb->dqb_type; - oqc->qc_id = cdqb->dqb_id; - DQBLK_COPY(&oqc->qc_dqblk, cdqb); - - rc = fsfilt_ext3_quotactl(sb, oqc); - OBD_FREE_PTR(oqc); - RETURN(rc); -} - -static int prune_chkquots(struct super_block *sb, - struct qchk_ctxt *qctxt, int error) -{ - struct chk_dqblk *cdqb, *tmp; - int rc; - - cfs_list_for_each_entry_safe(cdqb, tmp, &qctxt->qckt_list, dqb_list) { - if (!error) { - rc = commit_chkquot(sb, qctxt, cdqb); - if (rc) - error = rc; - } - cfs_hlist_del_init(&cdqb->dqb_hash); - cfs_list_del(&cdqb->dqb_list); - OBD_FREE_PTR(cdqb); - } - - return error; -} - -#ifndef EXT3_FEATURE_RO_COMPAT_GDT_CSUM -#define EXT3_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 -#endif - -static int fsfilt_ext3_quotacheck(struct super_block *sb, - struct obd_quotactl *oqc) -{ - struct ext3_sb_info *sbi = EXT3_SB(sb); - int i, group, uninit_feat = 0; - struct qchk_ctxt *qctxt; - struct buffer_head *bitmap_bh = NULL; - unsigned long ino, inode_inuse; - struct inode *inode; - int rc = 0; - ENTRY; - - /* turn on quota and read dqinfo if existed */ - OBD_ALLOC_PTR(qctxt); - if (!qctxt) { - oqc->qc_stat = -ENOMEM; - RETURN(-ENOMEM); - } - - for (i = 0; i < NR_DQHASH; i++) - CFS_INIT_HLIST_HEAD(&qctxt->qckt_hash[i]); - CFS_INIT_LIST_HEAD(&qctxt->qckt_list); - - for (i = 0; i < MAXQUOTAS; i++) { - if (!Q_TYPESET(oqc, i)) - continue; - - rc = quota_onoff(sb, Q_QUOTAON, i, oqc->qc_id); - if (!rc || rc == -EBUSY) { - rc = read_old_dqinfo(sb, i, qctxt->qckt_dqinfo); - if (rc) - GOTO(out, rc); - } else if (rc == -ENOENT || rc == -EINVAL || rc == -EEXIST) { - qctxt->qckt_first_check[i] = 1; - } else if (rc) { - GOTO(out, rc); - } - } - if (EXT3_HAS_RO_COMPAT_FEATURE(sb, EXT3_FEATURE_RO_COMPAT_GDT_CSUM)) - /* This filesystem supports the uninit group feature */ - uninit_feat = 1; - - /* number of inodes that have been allocated */ - inode_inuse = sbi->s_inodes_per_group * sbi->s_groups_count - - percpu_counter_sum(&sbi->s_freeinodes_counter); - - /* check quota and update in hash */ - for (group = 0; group < sbi->s_groups_count && inode_inuse > 0; - group++) { - unsigned long used_count = sbi->s_inodes_per_group; - - if (uninit_feat) { - struct ext3_group_desc *desc; - desc = ext3_get_group_desc(sb, group, NULL); - if (!desc) - GOTO(out, -EIO); - - /* we don't really need to take the group lock here, - * but it may be useful if one day we support online - * quotacheck */ - ext4_lock_group(sb, group); - if (desc->bg_flags & cpu_to_le16(EXT3_BG_INODE_UNINIT)) { - /* no inode in use in this group, just skip it */ - ext3_unlock_group(sb, group); - continue; - } - - used_count -= ext3_itable_unused_count(sb, desc); - ext3_unlock_group(sb, group); - } - - ino = group * sbi->s_inodes_per_group + 1; - bitmap_bh = ext3_read_inode_bitmap(sb, group); - if (!bitmap_bh) { - CERROR("%s: ext3_read_inode_bitmap group %d failed\n", - sb->s_id, group); - GOTO(out, -EIO); - } - - i = 0; - while (i < used_count && - (i = ext3_find_next_bit(bitmap_bh->b_data, - used_count, i)) < used_count) { - inode_inuse--; - i++; - ino = i + group * sbi->s_inodes_per_group; - if (ino < sbi->s_first_ino) - continue; - inode = ext3_iget(sb, ino); - if (!inode || IS_ERR(inode)) - continue; - - rc = add_inode_quota(inode, qctxt, oqc); - iput(inode); - if (rc) { - brelse(bitmap_bh); - GOTO(out, rc); - } - } - brelse(bitmap_bh); - } - - /* read old quota limits from old quota file. (only for the user - * has limits but hasn't file) */ - for (i = 0; i < MAXQUOTAS; i++) { - cfs_list_t id_list; - struct dquot_id *dqid, *tmp; - - if (!Q_TYPESET(oqc, i)) - continue; - - if (qctxt->qckt_first_check[i]) - continue; - - - LASSERT(sb_dqopt(sb)->files[i] != NULL); - CFS_INIT_LIST_HEAD(&id_list); - rc = lustre_get_qids(NULL, sb_dqopt(sb)->files[i], i, &id_list); - if (rc) - CERROR("read old limits failed. (rc:%d)\n", rc); - - cfs_list_for_each_entry_safe(dqid, tmp, &id_list, di_link) { - cfs_list_del_init(&dqid->di_link); - - if (!rc) - cqget(sb, qctxt->qckt_hash, &qctxt->qckt_list, - dqid->di_id, i, - qctxt->qckt_first_check[i]); - OBD_FREE_PTR(dqid); - } - } - /* turn off quota cause we are to dump chk_dqblk to files */ - quota_onoff(sb, Q_QUOTAOFF, oqc->qc_type, oqc->qc_id); - - rc = create_new_quota_files(qctxt, oqc); - if (rc) - GOTO(out, rc); - - /* we use vfs functions to set dqblk, so turn quota on */ - rc = quota_onoff(sb, Q_QUOTAON, oqc->qc_type, oqc->qc_id); -out: - /* dump and free chk_dqblk */ - rc = prune_chkquots(sb, qctxt, rc); - OBD_FREE_PTR(qctxt); - - /* turn off quota, `lfs quotacheck` will turn on when all - * nodes quotacheck finish. */ - quota_onoff(sb, Q_QUOTAOFF, oqc->qc_type, oqc->qc_id); - - oqc->qc_stat = rc; - if (rc) - CERROR("quotacheck failed: rc = %d\n", rc); - - RETURN(rc); -} - -static int fsfilt_ext3_quotainfo(struct lustre_quota_info *lqi, int type, - int cmd) -{ - int rc = 0; - ENTRY; - - if (lqi->qi_files[type] == NULL) { - CERROR("operate qinfo before it's enabled!\n"); - RETURN(-ESRCH); - } - - switch (cmd) { - case QFILE_CHK: - rc = lustre_check_quota_file(lqi, type); - break; - case QFILE_RD_INFO: - rc = lustre_read_quota_info(lqi, type); - break; - case QFILE_WR_INFO: - rc = lustre_write_quota_info(lqi, type); - break; - case QFILE_INIT_INFO: - rc = lustre_init_quota_info(lqi, type); - break; - case QFILE_CONVERT: - rc = -ENOTSUPP; - CERROR("quota CONVERT command is not supported\n"); - break; - default: - rc = -ENOTSUPP; - CERROR("Unsupported admin quota file cmd %d\n" - "Are lquota.ko and fsfilt_ldiskfs.ko modules in sync?\n", - cmd); - break; - } - RETURN(rc); -} - -static int fsfilt_ext3_qids(struct file *file, struct inode *inode, int type, - cfs_list_t *list) -{ - return lustre_get_qids(file, inode, type, list); -} - -static int fsfilt_ext3_dquot(struct lustre_dquot *dquot, int cmd) -{ - int rc = 0; - ENTRY; - - if (dquot->dq_info->qi_files[dquot->dq_type] == NULL) { - CERROR("operate dquot before it's enabled!\n"); - RETURN(-ESRCH); - } - - switch (cmd) { - case QFILE_RD_DQUOT: - rc = lustre_read_dquot(dquot); - break; - case QFILE_WR_DQUOT: - if (dquot->dq_dqb.dqb_ihardlimit || - dquot->dq_dqb.dqb_isoftlimit || - dquot->dq_dqb.dqb_bhardlimit || - dquot->dq_dqb.dqb_bsoftlimit) - cfs_clear_bit(DQ_FAKE_B, &dquot->dq_flags); - else - cfs_set_bit(DQ_FAKE_B, &dquot->dq_flags); - - rc = lustre_commit_dquot(dquot); - if (rc >= 0) - rc = 0; - break; - default: - CERROR("Unsupported admin quota file cmd %d\n", cmd); - LBUG(); - break; - } - RETURN(rc); -} - -static int fsfilt_ext3_get_mblk(struct super_block *sb, int *count, - struct inode *inode, int frags) -{ - struct ext3_ext_base *base = inode; - /* for an ost_write request, it needs <#fragments> * - * metablocks at maxium b=16542 */ - *count = frags * (EXT_DEPTH(base) + 1) * EXT3_BLOCK_SIZE(sb); - return 0; -} - lvfs_sbdev_type fsfilt_ext3_journal_sbdev(struct super_block *sb) { return (EXT3_SB(sb)->journal_bdev); } EXPORT_SYMBOL(fsfilt_ext3_journal_sbdev); -ssize_t lustre_read_quota(struct file *f, struct inode *inode, int type, - char *buf, int count, loff_t pos) -{ - loff_t p = pos; - int rc; - - if (!f && !inode) { - CERROR("lustre_read_quota failed for no quota file!\n"); - libcfs_debug_dumpstack(NULL); - return -EINVAL; - } - - /* Support for both adm and op quota files must be provided */ - if (f) { - rc = fsfilt_ext3_read_record(f, buf, count, &p); - rc = rc < 0 ? rc : p - pos; - } else { - struct super_block *sb = inode->i_sb; - rc = sb->s_op->quota_read(sb, type, buf, count, pos); - } - return rc; -} - -ssize_t lustre_write_quota(struct file *f, char *buf, int count, loff_t pos) -{ - loff_t p = pos; - int rc; - - /* Only adm quota files are supported, op updates are handled by vfs */ - rc = fsfilt_ext3_write_record(f, buf, count, &p, 0); - rc = rc < 0 ? rc : p - pos; - - return rc; -} - -void *lustre_quota_journal_start(struct inode *inode, int delete) -{ - handle_t *handle; - unsigned block_count; - - if (delete) { - /* each indirect block (+4) may become free, attaching to the - * header list of free blocks (+1); the data block (+1) may - * become a free block (+0) or a block with free dqentries (+0) */ - block_count = (4 + 1) + 1; - handle = ext3_journal_start(inode, - block_count*EXT3_DATA_TRANS_BLOCKS(inode->i_sb)+2); - } else { - /* indirect blocks are touched (+4), each causes file expansion (+0) or - * freeblk reusage with a header update (+1); dqentry is either reused - * causing update of the entry block (+1), prev (+1) and next (+1) or - * a new block allocation (+1) with a header update (+1) */ - block_count = (4 + 1) + 3; - handle = ext3_journal_start(inode, - block_count*EXT3_DATA_TRANS_BLOCKS(inode->i_sb)+2); - - } - - return handle; -} - -void lustre_quota_journal_stop(void *handle) -{ - ext3_journal_stop((handle_t *)handle); -} - static int ll_decode_fh_accept(void *context, struct dentry *de) { return 1; @@ -2215,7 +1411,7 @@ struct dentry *fsfilt_ext3_fid2dentry(struct vfsmount *mnt, { struct inode *inode; struct dentry *result; - + result = ll_exportfs_decode_fh(mnt, fid, 2, FILEID_INO32_GEN, ll_decode_fh_accept, NULL); if (IS_ERR(result)) { @@ -2286,12 +1482,6 @@ static struct fsfilt_operations fsfilt_ext3_ops = { .fs_get_version = fsfilt_ext3_get_version, .fs_set_version = fsfilt_ext3_set_version, #endif - .fs_quotactl = fsfilt_ext3_quotactl, - .fs_quotacheck = fsfilt_ext3_quotacheck, - .fs_quotainfo = fsfilt_ext3_quotainfo, - .fs_qids = fsfilt_ext3_qids, - .fs_dquot = fsfilt_ext3_dquot, - .fs_get_mblk = fsfilt_ext3_get_mblk, .fs_journal_sbdev = fsfilt_ext3_journal_sbdev, .fs_fid2dentry = fsfilt_ext3_fid2dentry, }; diff --git a/lustre/lvfs/lustre_quota_fmt.c b/lustre/lvfs/lustre_quota_fmt.c deleted file mode 100644 index b1e328e..0000000 --- a/lustre/lvfs/lustre_quota_fmt.c +++ /dev/null @@ -1,1124 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * lustre/lvfs/lustre_quota_fmt.c - * - * Lustre administrative quota format. - * from linux/fs/quota_v2.c - */ - -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_QUOTAIO_V1_H -# include -#endif - -#include -#include - -#include -#include -#include "lustre_quota_fmt.h" - -static const uint lustre_initqversions[][MAXQUOTAS] = { - [LUSTRE_QUOTA_V2] = LUSTRE_INITQVERSIONS_V2 -}; - -static const int lustre_dqstrinblk[] = { - [LUSTRE_QUOTA_V2] = LUSTRE_DQSTRINBLK_V2 -}; - -static const int lustre_disk_dqblk_sz[] = { - [LUSTRE_QUOTA_V2] = sizeof(struct lustre_disk_dqblk_v2) -}; - -static const union -{ - struct lustre_disk_dqblk_v2 r1; -} fakedquot[] = { - [LUSTRE_QUOTA_V2] = {.r1 = {.dqb_itime = __constant_cpu_to_le64(1LLU)}} -}; - -static const union -{ - struct lustre_disk_dqblk_v2 r1; -} emptydquot[] = { - [LUSTRE_QUOTA_V2] = {.r1 = { 0 }} -}; - -extern void *lustre_quota_journal_start(struct inode *inode, int delete); -extern void lustre_quota_journal_stop(void *handle); -extern ssize_t lustre_read_quota(struct file *f, struct inode *inode, int type, - char *buf, int count, loff_t pos); -extern ssize_t lustre_write_quota(struct file *f, char *buf, int count, loff_t pos); - -int check_quota_file(struct file *f, struct inode *inode, int type, - lustre_quota_version_t version) -{ - struct lustre_disk_dqheader dqhead; - ssize_t size; - static const uint quota_magics[] = LUSTRE_INITQMAGICS; - const uint *quota_versions = lustre_initqversions[version]; - - size = lustre_read_quota(f, inode, type, (char *)&dqhead, - sizeof(struct lustre_disk_dqheader), 0); - if (size != sizeof(struct lustre_disk_dqheader)) - return -EINVAL; - if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] || - le32_to_cpu(dqhead.dqh_version) != quota_versions[type]) - return -EINVAL; - return 0; -} - -/** - * Check whether given file is really lustre admin quotafile - */ -int lustre_check_quota_file(struct lustre_quota_info *lqi, int type) -{ - struct file *f = lqi->qi_files[type]; - return check_quota_file(f, NULL, type, lqi->qi_version); -} -EXPORT_SYMBOL(lustre_check_quota_file); - -int lustre_read_quota_file_info(struct file* f, struct lustre_mem_dqinfo* info) -{ - struct lustre_disk_dqinfo dinfo; - ssize_t size; - - size = lustre_read_quota(f, NULL, 0, (char *)&dinfo, - sizeof(struct lustre_disk_dqinfo), - LUSTRE_DQINFOOFF); - - if (size != sizeof(struct lustre_disk_dqinfo)) { - CDEBUG(D_ERROR, "Can't read info structure on device %s.\n", - f->f_vfsmnt->mnt_sb->s_id); - return -EINVAL; - } - info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace); - info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace); - info->dqi_flags = le32_to_cpu(dinfo.dqi_flags); - info->dqi_blocks = le32_to_cpu(dinfo.dqi_blocks); - info->dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk); - info->dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry); - return 0; -} - -/** - * Read information header from quota file - */ -int lustre_read_quota_info(struct lustre_quota_info *lqi, int type) -{ - return lustre_read_quota_file_info(lqi->qi_files[type], - &lqi->qi_info[type]); -} -EXPORT_SYMBOL(lustre_read_quota_info); - -/** - * Write information header to quota file - */ -int lustre_write_quota_info(struct lustre_quota_info *lqi, int type) -{ - struct lustre_disk_dqinfo dinfo; - struct lustre_mem_dqinfo *info = &lqi->qi_info[type]; - struct file *f = lqi->qi_files[type]; - ssize_t size; - - info->dqi_flags &= ~DQF_INFO_DIRTY; - dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace); - dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace); - dinfo.dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK); - dinfo.dqi_blocks = cpu_to_le32(info->dqi_blocks); - dinfo.dqi_free_blk = cpu_to_le32(info->dqi_free_blk); - dinfo.dqi_free_entry = cpu_to_le32(info->dqi_free_entry); - - size = lustre_write_quota(f, (char *)&dinfo, - sizeof(struct lustre_disk_dqinfo), - LUSTRE_DQINFOOFF); - - if (size != sizeof(struct lustre_disk_dqinfo)) { - CDEBUG(D_WARNING, - "Can't write info structure on device %s.\n", - f->f_vfsmnt->mnt_sb->s_id); - return -1; - } - return 0; -} -EXPORT_SYMBOL(lustre_write_quota_info); - -void disk2memdqb(struct lustre_mem_dqblk *m, void *d, - lustre_quota_version_t version) -{ - struct lustre_disk_dqblk_v2 *dqblk = (struct lustre_disk_dqblk_v2 *)d; - - LASSERT(version == LUSTRE_QUOTA_V2); - - m->dqb_ihardlimit = le64_to_cpu(dqblk->dqb_ihardlimit); - m->dqb_isoftlimit = le64_to_cpu(dqblk->dqb_isoftlimit); - m->dqb_curinodes = le64_to_cpu(dqblk->dqb_curinodes); - m->dqb_itime = le64_to_cpu(dqblk->dqb_itime); - m->dqb_bhardlimit = le64_to_cpu(dqblk->dqb_bhardlimit); - m->dqb_bsoftlimit = le64_to_cpu(dqblk->dqb_bsoftlimit); - m->dqb_curspace = le64_to_cpu(dqblk->dqb_curspace); - m->dqb_btime = le64_to_cpu(dqblk->dqb_btime); -} - -static int mem2diskdqb(void *d, struct lustre_mem_dqblk *m, - qid_t id, lustre_quota_version_t version) -{ - struct lustre_disk_dqblk_v2 *dqblk = (struct lustre_disk_dqblk_v2 *)d; - - LASSERT(version == LUSTRE_QUOTA_V2); - - dqblk->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit); - dqblk->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit); - dqblk->dqb_curinodes = cpu_to_le64(m->dqb_curinodes); - dqblk->dqb_itime = cpu_to_le64(m->dqb_itime); - dqblk->dqb_bhardlimit = cpu_to_le64(m->dqb_bhardlimit); - dqblk->dqb_bsoftlimit = cpu_to_le64(m->dqb_bsoftlimit); - dqblk->dqb_curspace = cpu_to_le64(m->dqb_curspace); - dqblk->dqb_btime = cpu_to_le64(m->dqb_btime); - dqblk->dqb_id = cpu_to_le32(id); - - return 0; -} - -dqbuf_t getdqbuf(void) -{ - dqbuf_t buf = kmalloc(LUSTRE_DQBLKSIZE, GFP_NOFS); - if (!buf) - CDEBUG(D_WARNING, - "VFS: Not enough memory for quota buffers.\n"); - return buf; -} - -void freedqbuf(dqbuf_t buf) -{ - kfree(buf); -} - -ssize_t read_blk(struct file *filp, struct inode *inode, int type, - uint blk, dqbuf_t buf) -{ - ssize_t ret; - - memset(buf, 0, LUSTRE_DQBLKSIZE); - ret = lustre_read_quota(filp, inode, type, (char *)buf, LUSTRE_DQBLKSIZE, - blk << LUSTRE_DQBLKSIZE_BITS); - - /* Reading past EOF just returns a block of zeros */ - if (ret == -EBADR) - ret = 0; - - return ret; -} - -ssize_t write_blk(struct file *filp, uint blk, dqbuf_t buf) -{ - ssize_t ret; - - ret = lustre_write_quota(filp, (char *)buf, LUSTRE_DQBLKSIZE, - blk << LUSTRE_DQBLKSIZE_BITS); - - return ret; -} - -void lustre_mark_info_dirty(struct lustre_mem_dqinfo *info) -{ - cfs_set_bit(DQF_INFO_DIRTY_B, &info->dqi_flags); -} - -/** - * Remove empty block from list and return it - */ -int get_free_dqblk(struct file *filp, struct lustre_mem_dqinfo *info) -{ - dqbuf_t buf = getdqbuf(); - struct lustre_disk_dqdbheader *dh = - (struct lustre_disk_dqdbheader *)buf; - int ret, blk; - - if (!buf) - return -ENOMEM; - if (info->dqi_free_blk) { - blk = info->dqi_free_blk; - if ((ret = read_blk(filp, NULL, 0, blk, buf)) < 0) - goto out_buf; - info->dqi_free_blk = le32_to_cpu(dh->dqdh_next_free); - } else { - memset(buf, 0, LUSTRE_DQBLKSIZE); - /* Assure block allocation... */ - if ((ret = write_blk(filp, info->dqi_blocks, buf)) < 0) - goto out_buf; - blk = info->dqi_blocks++; - } - lustre_mark_info_dirty(info); - ret = blk; -out_buf: - freedqbuf(buf); - return ret; -} - -/** - * Insert empty block to the list - */ -int put_free_dqblk(struct file *filp, struct lustre_mem_dqinfo *info, - dqbuf_t buf, uint blk) -{ - struct lustre_disk_dqdbheader *dh = - (struct lustre_disk_dqdbheader *)buf; - int err; - - dh->dqdh_next_free = cpu_to_le32(info->dqi_free_blk); - dh->dqdh_prev_free = cpu_to_le32(0); - dh->dqdh_entries = cpu_to_le16(0); - info->dqi_free_blk = blk; - lustre_mark_info_dirty(info); - if ((err = write_blk(filp, blk, buf)) < 0) - /* Some strange block. We had better leave it... */ - return err; - return 0; -} - -/** - * Remove given block from the list of blocks with free entries - */ -int remove_free_dqentry(struct file *filp, - struct lustre_mem_dqinfo *info, dqbuf_t buf, - uint blk) -{ - dqbuf_t tmpbuf = getdqbuf(); - struct lustre_disk_dqdbheader *dh = - (struct lustre_disk_dqdbheader *)buf; - uint nextblk = le32_to_cpu(dh->dqdh_next_free), prevblk = - le32_to_cpu(dh->dqdh_prev_free); - int err; - - if (!tmpbuf) - return -ENOMEM; - if (nextblk) { - if ((err = read_blk(filp, NULL, 0, nextblk, tmpbuf)) < 0) - goto out_buf; - ((struct lustre_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = - dh->dqdh_prev_free; - if ((err = write_blk(filp, nextblk, tmpbuf)) < 0) - goto out_buf; - } - if (prevblk) { - if ((err = read_blk(filp, NULL, 0, prevblk, tmpbuf)) < 0) - goto out_buf; - ((struct lustre_disk_dqdbheader *)tmpbuf)->dqdh_next_free = - dh->dqdh_next_free; - if ((err = write_blk(filp, prevblk, tmpbuf)) < 0) - goto out_buf; - } else { - info->dqi_free_entry = nextblk; - lustre_mark_info_dirty(info); - } - freedqbuf(tmpbuf); - dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); - if (write_blk(filp, blk, buf) < 0) - /* No matter whether write succeeds block is out of list */ - CDEBUG(D_ERROR, - "VFS: Can't write block (%u) with free entries.\n", blk); - return 0; -out_buf: - freedqbuf(tmpbuf); - return err; -} - -/** - * Insert given block to the beginning of list with free entries - */ -int insert_free_dqentry(struct file *filp, - struct lustre_mem_dqinfo *info, dqbuf_t buf, - uint blk) -{ - dqbuf_t tmpbuf = getdqbuf(); - struct lustre_disk_dqdbheader *dh = - (struct lustre_disk_dqdbheader *)buf; - int err; - - if (!tmpbuf) - return -ENOMEM; - dh->dqdh_next_free = cpu_to_le32(info->dqi_free_entry); - dh->dqdh_prev_free = cpu_to_le32(0); - if ((err = write_blk(filp, blk, buf)) < 0) - goto out_buf; - if (info->dqi_free_entry) { - if ((err = read_blk(filp, NULL, 0, info->dqi_free_entry, tmpbuf)) < 0) - goto out_buf; - ((struct lustre_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = - cpu_to_le32(blk); - if ((err = write_blk(filp, info->dqi_free_entry, tmpbuf)) < 0) - goto out_buf; - } - freedqbuf(tmpbuf); - info->dqi_free_entry = blk; - lustre_mark_info_dirty(info); - return 0; -out_buf: - freedqbuf(tmpbuf); - return err; -} - - - -/** - * Find space for dquot - */ -static uint find_free_dqentry(struct lustre_dquot *dquot, int *err, - lustre_quota_version_t version) -{ - struct lustre_quota_info *lqi = dquot->dq_info; - struct file *filp = lqi->qi_files[dquot->dq_type]; - struct lustre_mem_dqinfo *info = &lqi->qi_info[dquot->dq_type]; - uint blk, i; - struct lustre_disk_dqdbheader *dh; - void *ddquot; - int dqblk_sz = lustre_disk_dqblk_sz[version]; - int dqstrinblk = lustre_dqstrinblk[version]; - dqbuf_t buf; - - *err = 0; - if (!(buf = getdqbuf())) { - *err = -ENOMEM; - return 0; - } - dh = (struct lustre_disk_dqdbheader *)buf; - ddquot = GETENTRIES(buf, version); - if (info->dqi_free_entry) { - blk = info->dqi_free_entry; - if ((*err = read_blk(filp, NULL, 0, blk, buf)) < 0) - goto out_buf; - } else { - blk = get_free_dqblk(filp, info); - if ((int)blk < 0) { - *err = blk; - freedqbuf(buf); - return 0; - } - memset(buf, 0, LUSTRE_DQBLKSIZE); - info->dqi_free_entry = blk; /* This is enough as block is - already zeroed and entry list - is empty... */ - lustre_mark_info_dirty(info); - } - - /* Will block be full */ - if (le16_to_cpu(dh->dqdh_entries) + 1 >= dqstrinblk) - if ((*err = remove_free_dqentry(filp, info, buf, blk)) < 0) { - CDEBUG(D_ERROR, - "VFS: find_free_dqentry(): Can't remove block " - "(%u) from entry free list.\n", blk); - goto out_buf; - } - dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries) + 1); - /* Find free structure in block */ - for (i = 0; i < dqstrinblk && - memcmp((char *)&emptydquot[version], - (char *)ddquot + i * dqblk_sz, dqblk_sz); - i++); - - if (i == dqstrinblk) { - CDEBUG(D_ERROR, - "VFS: find_free_dqentry(): Data block full but it " - "shouldn't.\n"); - *err = -EIO; - goto out_buf; - } - - if ((*err = write_blk(filp, blk, buf)) < 0) { - CDEBUG(D_ERROR, - "VFS: find_free_dqentry(): Can't write quota data " - "block %u.\n", blk); - goto out_buf; - } - dquot->dq_off = - (blk << LUSTRE_DQBLKSIZE_BITS) + - sizeof(struct lustre_disk_dqdbheader) + - i * dqblk_sz; - freedqbuf(buf); - return blk; -out_buf: - freedqbuf(buf); - return 0; -} - -/** - * Insert reference to structure into the trie - */ -static int do_insert_tree(struct lustre_dquot *dquot, uint * treeblk, int depth, - lustre_quota_version_t version) -{ - struct lustre_quota_info *lqi = dquot->dq_info; - struct file *filp = lqi->qi_files[dquot->dq_type]; - struct lustre_mem_dqinfo *info = &lqi->qi_info[dquot->dq_type]; - dqbuf_t buf; - int ret = 0, newson = 0, newact = 0; - u32 *ref; - uint newblk; - - if (!(buf = getdqbuf())) - return -ENOMEM; - if (!*treeblk) { - ret = get_free_dqblk(filp, info); - if (ret < 0) - goto out_buf; - *treeblk = ret; - memset(buf, 0, LUSTRE_DQBLKSIZE); - newact = 1; - } else { - if ((ret = read_blk(filp, NULL, 0, *treeblk, buf)) < 0) { - CERROR("VFS: Can't read tree quota block %u.\n", - *treeblk); - goto out_buf; - } - } - ref = (u32 *) buf; - newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]); - if (!newblk) - newson = 1; - if (depth == LUSTRE_DQTREEDEPTH - 1) { - - if (newblk) { - CDEBUG(D_ERROR, - "VFS: Inserting already present quota entry " - "(block %u).\n", - ref[GETIDINDEX(dquot->dq_id, depth)]); - ret = -EIO; - goto out_buf; - } - - newblk = find_free_dqentry(dquot, &ret, version); - } else - ret = do_insert_tree(dquot, &newblk, depth + 1, version); - if (newson && ret >= 0) { - ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(newblk); - ret = write_blk(filp, *treeblk, buf); - } else if (newact && ret < 0) - put_free_dqblk(filp, info, buf, *treeblk); -out_buf: - freedqbuf(buf); - return ret; -} - -/** - * Wrapper for inserting quota structure into tree - */ -static inline int dq_insert_tree(struct lustre_dquot *dquot, - lustre_quota_version_t version) -{ - int tmp = LUSTRE_DQTREEOFF; - return do_insert_tree(dquot, &tmp, 0, version); -} - -/** - * We don't have to be afraid of deadlocks as we never have quotas on - * quota files... - */ -static int lustre_write_dquot(struct lustre_dquot *dquot, - lustre_quota_version_t version) -{ - int type = dquot->dq_type; - struct file *filp; - loff_t offset; - ssize_t ret; - int dqblk_sz = lustre_disk_dqblk_sz[version]; - struct lustre_disk_dqblk_v2 ddquot; - - ret = mem2diskdqb(&ddquot, &dquot->dq_dqb, dquot->dq_id, version); - if (ret < 0) - return ret; - - if (!dquot->dq_off) - if ((ret = dq_insert_tree(dquot, version)) < 0) { - CDEBUG(D_ERROR, - "VFS: Error %Zd occurred while creating " - "quota.\n", ret); - return ret; - } - filp = dquot->dq_info->qi_files[type]; - offset = dquot->dq_off; - /* Argh... We may need to write structure full of zeroes but that would - * be treated as an empty place by the rest of the code. Format change - * would be definitely cleaner but the problems probably are not worth - * it */ - if (!memcmp((char *)&emptydquot[version], (char *)&ddquot, dqblk_sz)) - ddquot.dqb_itime = cpu_to_le64(1); - - ret = lustre_write_quota(filp, (char *)&ddquot, dqblk_sz, offset); - if (ret != dqblk_sz) { - CDEBUG(D_WARNING, "VFS: dquota write failed on dev %s\n", - filp->f_dentry->d_sb->s_id); - if (ret >= 0) - ret = -ENOSPC; - } else - ret = 0; - - return ret; -} - -/** - * Free dquot entry in data block - */ -static int free_dqentry(struct lustre_dquot *dquot, uint blk, - lustre_quota_version_t version) -{ - struct file *filp = dquot->dq_info->qi_files[dquot->dq_type]; - struct lustre_mem_dqinfo *info = - &dquot->dq_info->qi_info[dquot->dq_type]; - struct lustre_disk_dqdbheader *dh; - dqbuf_t buf = getdqbuf(); - int dqstrinblk = lustre_dqstrinblk[version]; - int ret = 0; - - if (!buf) - return -ENOMEM; - if (dquot->dq_off >> LUSTRE_DQBLKSIZE_BITS != blk) { - CDEBUG(D_ERROR, - "VFS: Quota structure has offset to other block (%u) " - "than it should (%u).\n", - blk, (uint) (dquot->dq_off >> LUSTRE_DQBLKSIZE_BITS)); - goto out_buf; - } - if ((ret = read_blk(filp, NULL, 0, blk, buf)) < 0) { - CDEBUG(D_ERROR, "VFS: Can't read quota data block %u\n", blk); - goto out_buf; - } - dh = (struct lustre_disk_dqdbheader *)buf; - dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries) - 1); - if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */ - if ((ret = remove_free_dqentry(filp, info, buf, blk)) < 0 || - (ret = put_free_dqblk(filp, info, buf, blk)) < 0) { - CDEBUG(D_ERROR, - "VFS: Can't move quota data block (%u) to free " - "list.\n", blk); - goto out_buf; - } - } else { - memset(buf + (dquot->dq_off & ((1<dqdh_entries) == dqstrinblk - 1) { - /* Insert will write block itself */ - if ((ret = - insert_free_dqentry(filp, info, buf, blk)) < 0) { - CDEBUG(D_ERROR, - "VFS: Can't insert quota data block " - "(%u) to free entry list.\n", blk); - goto out_buf; - } - } else if ((ret = write_blk(filp, blk, buf)) < 0) { - CDEBUG(D_ERROR, - "VFS: Can't write quota data block %u\n", blk); - goto out_buf; - } - } - dquot->dq_off = 0; /* Quota is now unattached */ -out_buf: - freedqbuf(buf); - return ret; -} - -/** - * Remove reference to dquot from tree - */ -static int remove_tree(struct lustre_dquot *dquot, uint * blk, int depth, - lustre_quota_version_t version) -{ - struct file *filp = dquot->dq_info->qi_files[dquot->dq_type]; - struct lustre_mem_dqinfo *info = - &dquot->dq_info->qi_info[dquot->dq_type]; - dqbuf_t buf = getdqbuf(); - int ret = 0; - uint newblk; - u32 *ref = (u32 *) buf; - - if (!buf) - return -ENOMEM; - if ((ret = read_blk(filp, NULL, 0, *blk, buf)) < 0) { - CERROR("VFS: Can't read quota data block %u\n", *blk); - goto out_buf; - } - newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]); - if (depth == LUSTRE_DQTREEDEPTH - 1) { - ret = free_dqentry(dquot, newblk, version); - newblk = 0; - } else - ret = remove_tree(dquot, &newblk, depth + 1, version); - if (ret >= 0 && !newblk) { - int i; - ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(0); - for (i = 0; i < LUSTRE_DQBLKSIZE && !buf[i]; i++) - /* Block got empty? */ ; - /* don't put the root block into free blk list! */ - if (i == LUSTRE_DQBLKSIZE && *blk != LUSTRE_DQTREEOFF) { - put_free_dqblk(filp, info, buf, *blk); - *blk = 0; - } else if ((ret = write_blk(filp, *blk, buf)) < 0) - CDEBUG(D_ERROR, - "VFS: Can't write quota tree block %u.\n", *blk); - } -out_buf: - freedqbuf(buf); - return ret; -} - -/** - * Delete dquot from tree - */ -static int lustre_delete_dquot(struct lustre_dquot *dquot, - lustre_quota_version_t version) -{ - uint tmp = LUSTRE_DQTREEOFF; - - if (!dquot->dq_off) /* Even not allocated? */ - return 0; - return remove_tree(dquot, &tmp, 0, version); -} - -/** - * Find entry in block - */ -static loff_t find_block_dqentry(struct lustre_dquot *dquot, uint blk, - lustre_quota_version_t version) -{ - struct file *filp = dquot->dq_info->qi_files[dquot->dq_type]; - dqbuf_t buf = getdqbuf(); - loff_t ret = 0; - int i; - struct lustre_disk_dqblk_v2 *ddquot = - (struct lustre_disk_dqblk_v2 *)GETENTRIES(buf, version); - int dqblk_sz = lustre_disk_dqblk_sz[version]; - int dqstrinblk = lustre_dqstrinblk[version]; - - LASSERT(version == LUSTRE_QUOTA_V2); - - if (!buf) - return -ENOMEM; - if ((ret = read_blk(filp, NULL, 0, blk, buf)) < 0) { - CERROR("VFS: Can't read quota tree block %u.\n", blk); - goto out_buf; - } - if (dquot->dq_id) - for (i = 0; i < dqstrinblk && - le32_to_cpu(ddquot[i].dqb_id) != dquot->dq_id; - i++) ; - else { /* ID 0 as a bit more complicated searching... */ - for (i = 0; i < dqstrinblk; i++) - if (!le32_to_cpu(ddquot[i].dqb_id) - && memcmp((char *)&emptydquot[version], - (char *)&ddquot[i], dqblk_sz)) - break; - } - if (i == dqstrinblk) { - CDEBUG(D_ERROR, - "VFS: Quota for id %u referenced but not present.\n", - dquot->dq_id); - ret = -EIO; - goto out_buf; - } else - ret = - (blk << LUSTRE_DQBLKSIZE_BITS) + - sizeof(struct lustre_disk_dqdbheader) + - i * dqblk_sz; -out_buf: - freedqbuf(buf); - return ret; -} - -/** - * Find entry for given id in the tree - */ -static loff_t find_tree_dqentry(struct lustre_dquot *dquot, uint blk, int depth, - lustre_quota_version_t version) -{ - struct file *filp = dquot->dq_info->qi_files[dquot->dq_type]; - dqbuf_t buf = getdqbuf(); - loff_t ret = 0; - u32 *ref = (u32 *) buf; - - if (!buf) - return -ENOMEM; - if ((ret = read_blk(filp, NULL, 0, blk, buf)) < 0) { - CERROR("VFS: Can't read quota tree block %u.\n", blk); - goto out_buf; - } - ret = 0; - blk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]); - if (!blk) /* No reference? */ - goto out_buf; - if (depth < LUSTRE_DQTREEDEPTH - 1) - ret = find_tree_dqentry(dquot, blk, depth + 1, version); - else - ret = find_block_dqentry(dquot, blk, version); -out_buf: - freedqbuf(buf); - return ret; -} - -/** - * Find entry for given id in the tree - wrapper function - */ -static inline loff_t find_dqentry(struct lustre_dquot *dquot, - lustre_quota_version_t version) -{ - return find_tree_dqentry(dquot, LUSTRE_DQTREEOFF, 0, version); -} - -int lustre_read_dquot(struct lustre_dquot *dquot) -{ - int type = dquot->dq_type; - struct file *filp; - loff_t offset; - int ret = 0, dqblk_sz; - lustre_quota_version_t version; - - /* Invalidated quota? */ - if (!dquot->dq_info || !(filp = dquot->dq_info->qi_files[type])) { - CDEBUG(D_ERROR, "VFS: Quota invalidated while reading!\n"); - return -ESRCH; - } - - version = dquot->dq_info->qi_version; - LASSERT(version == LUSTRE_QUOTA_V2); - dqblk_sz = lustre_disk_dqblk_sz[version]; - - offset = find_dqentry(dquot, version); - if (offset <= 0) { /* Entry not present? */ - if (offset < 0) - CDEBUG(D_ERROR, - "VFS: Can't read quota structure for id %u.\n", - dquot->dq_id); - dquot->dq_off = 0; - cfs_set_bit(DQ_FAKE_B, &dquot->dq_flags); - memset(&dquot->dq_dqb, 0, sizeof(struct lustre_mem_dqblk)); - ret = offset; - } else { - struct lustre_disk_dqblk_v2 ddquot; - - dquot->dq_off = offset; - if ((ret = lustre_read_quota(filp, NULL, type, (char *)&ddquot, - dqblk_sz, offset)) != dqblk_sz) { - if (ret >= 0) - ret = -EIO; - CDEBUG(D_ERROR, - "VFS: Error while reading quota structure for id " - "%u.\n", dquot->dq_id); - memset((char *)&ddquot, 0, dqblk_sz); - } else { - ret = 0; - /* We need to escape back all-zero structure */ - if (!memcmp((char *)&fakedquot[version], - (char *)&ddquot, dqblk_sz)) - ddquot.dqb_itime = cpu_to_le64(0); - } - disk2memdqb(&dquot->dq_dqb, &ddquot, version); - } - - return ret; -} -EXPORT_SYMBOL(lustre_read_dquot); - -/** - * Commit changes of dquot to disk - it might also mean deleting - * it when quota became fake. - */ -int lustre_commit_dquot(struct lustre_dquot *dquot) -{ - int rc = 0; - lustre_quota_version_t version = dquot->dq_info->qi_version; - void *handle; - struct inode *inode = dquot->dq_info->qi_files[dquot->dq_type]->f_dentry->d_inode; - int delete = 0; - - /* always clear the flag so we don't loop on an IO error... */ - cfs_clear_bit(DQ_MOD_B, &dquot->dq_flags); - - /* The block/inode usage in admin quotafile isn't the real usage - * over all cluster, so keep the fake dquot entry on disk is - * meaningless, just remove it */ - if (cfs_test_bit(DQ_FAKE_B, &dquot->dq_flags)) - delete = 1; - handle = lustre_quota_journal_start(inode, delete); - if (unlikely(IS_ERR(handle))) { - rc = PTR_ERR(handle); - CERROR("fail to lustre_quota_journal_start: rc = %d\n", rc); - return rc; - } - - if (delete) - rc = lustre_delete_dquot(dquot, version); - else - rc = lustre_write_dquot(dquot, version); - lustre_quota_journal_stop(handle); - - if (rc < 0) - return rc; - - if (lustre_info_dirty(&dquot->dq_info->qi_info[dquot->dq_type])) - rc = lustre_write_quota_info(dquot->dq_info, dquot->dq_type); - - return rc; -} -EXPORT_SYMBOL(lustre_commit_dquot); - -int lustre_init_quota_header(struct lustre_quota_info *lqi, int type, - int fakemagics) -{ - static const uint quota_magics[] = LUSTRE_INITQMAGICS; - static const uint fake_magics[] = LUSTRE_BADQMAGICS; - const uint* quota_versions = lustre_initqversions[lqi->qi_version]; - struct lustre_disk_dqheader dqhead; - ssize_t size; - struct file *fp = lqi->qi_files[type]; - int rc = 0; - - /* write quotafile header */ - dqhead.dqh_magic = cpu_to_le32(fakemagics ? - fake_magics[type] : quota_magics[type]); - dqhead.dqh_version = cpu_to_le32(quota_versions[type]); - size = lustre_write_quota(fp, (char *)&dqhead, - sizeof(struct lustre_disk_dqheader), 0); - - if (size != sizeof(struct lustre_disk_dqheader)) { - CDEBUG(D_ERROR, "error writing quoafile header (rc:%d)\n", rc); - rc = size; - } - - return rc; -} - -/** - * We need to export this function to initialize quotafile, because we haven't - * user level check utility - */ -int lustre_init_quota_info_generic(struct lustre_quota_info *lqi, int type, - int fakemagics) -{ - struct lustre_mem_dqinfo *dqinfo = &lqi->qi_info[type]; - int rc; - - rc = lustre_init_quota_header(lqi, type, fakemagics); - if (rc) - return rc; - - /* write init quota info */ - memset(dqinfo, 0, sizeof(*dqinfo)); - dqinfo->dqi_bgrace = MAX_DQ_TIME; - dqinfo->dqi_igrace = MAX_IQ_TIME; - dqinfo->dqi_blocks = LUSTRE_DQTREEOFF + 1; - - return lustre_write_quota_info(lqi, type); -} - -int lustre_init_quota_info(struct lustre_quota_info *lqi, int type) -{ - return lustre_init_quota_info_generic(lqi, type, 0); -} -EXPORT_SYMBOL(lustre_init_quota_info); - -static int walk_block_dqentry(struct file *filp, struct inode *inode, int type, - uint blk, cfs_list_t *list) -{ - dqbuf_t buf = getdqbuf(); - loff_t ret = 0; - struct lustre_disk_dqdbheader *dqhead = - (struct lustre_disk_dqdbheader *)buf; - struct dqblk *blk_item; - struct dqblk *pos; - cfs_list_t *tmp; - - if (!buf) - return -ENOMEM; - if ((ret = read_blk(filp, inode, type, blk, buf)) < 0) { - CERROR("VFS: Can't read quota tree block %u.\n", blk); - goto out_buf; - } - ret = 0; - - if (!le32_to_cpu(dqhead->dqdh_entries)) - goto out_buf; - - if (cfs_list_empty(list)) { - tmp = list; - goto done; - } - - cfs_list_for_each_entry(pos, list, link) { - if (blk == pos->blk) /* we got this blk already */ - goto out_buf; - if (blk > pos->blk) - continue; - break; - } - tmp = &pos->link; -done: - blk_item = kmalloc(sizeof(*blk_item), GFP_NOFS); - if (!blk_item) { - ret = -ENOMEM; - goto out_buf; - } - blk_item->blk = blk; - CFS_INIT_LIST_HEAD(&blk_item->link); - - cfs_list_add_tail(&blk_item->link, tmp); - -out_buf: - freedqbuf(buf); - return ret; -} - -int walk_tree_dqentry(struct file *filp, struct inode *inode, int type, - uint blk, int depth, cfs_list_t *list) -{ - dqbuf_t buf = getdqbuf(); - loff_t ret = 0; - int index; - u32 *ref = (u32 *) buf; - - if (!buf) - return -ENOMEM; - if ((ret = read_blk(filp, inode, type, blk, buf)) < 0) { - CERROR("VFS: Can't read quota tree block %u.\n", blk); - goto out_buf; - } - ret = 0; - - for (index = 0; index <= 0xff && !ret; index++) { - blk = le32_to_cpu(ref[index]); - if (!blk) /* No reference */ - continue; - - if (depth < LUSTRE_DQTREEDEPTH - 1) - ret = walk_tree_dqentry(filp, inode, type, blk, - depth + 1, list); - else - ret = walk_block_dqentry(filp, inode, type, blk, list); - } -out_buf: - freedqbuf(buf); - return ret; -} - -/** - * Walk through the quota file (v2 format) to get all ids with quota limit - */ -int lustre_get_qids(struct file *fp, struct inode *inode, int type, - cfs_list_t *list) -{ - cfs_list_t blk_list; - struct dqblk *blk_item, *tmp; - dqbuf_t buf = NULL; - struct lustre_disk_dqblk_v2 *ddquot; - int rc; - lustre_quota_version_t version; - - ENTRY; - - LASSERT(ergo(fp == NULL, inode != NULL)); - - if (check_quota_file(fp, inode, type, LUSTRE_QUOTA_V2) == 0) - version = LUSTRE_QUOTA_V2; - else { - CDEBUG(D_ERROR, "unknown quota file format!\n"); - RETURN(-EINVAL); - } - - if (!cfs_list_empty(list)) { - CDEBUG(D_ERROR, "not empty list\n"); - RETURN(-EINVAL); - } - - CFS_INIT_LIST_HEAD(&blk_list); - rc = walk_tree_dqentry(fp, inode, type, LUSTRE_DQTREEOFF, 0, &blk_list); - if (rc) { - CDEBUG(D_ERROR, "walk through quota file failed!(%d)\n", rc); - GOTO(out_free, rc); - } - if (cfs_list_empty(&blk_list)) - RETURN(0); - - buf = getdqbuf(); - if (!buf) - RETURN(-ENOMEM); - ddquot = (struct lustre_disk_dqblk_v2 *)GETENTRIES(buf, version); - - cfs_list_for_each_entry(blk_item, &blk_list, link) { - loff_t ret = 0; - int i, dqblk_sz = lustre_disk_dqblk_sz[version]; - - memset(buf, 0, LUSTRE_DQBLKSIZE); - if ((ret = read_blk(fp, inode, type, blk_item->blk, buf)) < 0) { - CERROR("VFS: Can't read quota tree block %u.\n", - blk_item->blk); - GOTO(out_free, rc = ret); - } - - for (i = 0; i < lustre_dqstrinblk[version]; i++) { - struct dquot_id *dqid; - /* skip empty entry */ - if (!memcmp((char *)&emptydquot[version], - (char *)&ddquot[i], dqblk_sz)) - continue; - - OBD_ALLOC_GFP(dqid, sizeof(*dqid), CFS_ALLOC_NOFS); - if (!dqid) - GOTO(out_free, rc = -ENOMEM); - - dqid->di_id = le32_to_cpu(ddquot[i].dqb_id); - dqid->di_flag = le64_to_cpu(ddquot[i].dqb_ihardlimit) ? - QI_SET : 0; - dqid->di_flag |= le64_to_cpu(ddquot[i].dqb_bhardlimit) ? - QB_SET : 0; - - CFS_INIT_LIST_HEAD(&dqid->di_link); - cfs_list_add(&dqid->di_link, list); - } - } - -out_free: - cfs_list_for_each_entry_safe(blk_item, tmp, &blk_list, link) { - cfs_list_del_init(&blk_item->link); - kfree(blk_item); - } - if (buf) - freedqbuf(buf); - - RETURN(rc); -} -EXPORT_SYMBOL(lustre_get_qids); diff --git a/lustre/lvfs/lustre_quota_fmt.h b/lustre/lvfs/lustre_quota_fmt.h deleted file mode 100644 index cca4fb9..0000000 --- a/lustre/lvfs/lustre_quota_fmt.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * lustre/lvfs/lustre_quota_fmt.h - * - * Lustre administrative quota format - * from include/linux/quotaio_v2.h - */ -#ifndef _LUSTRE_QUOTA_FMT_H -#define _LUSTRE_QUOTA_FMT_H - -#include -#include - -/* - * Definitions of magics and versions of current quota files - * Same with quota v2's magic - */ -#define LUSTRE_INITQMAGICS {\ - 0xd9c01f11, /** USRQUOTA */\ - 0xd9c01927 /** GRPQUOTA */\ -} - -/* Invalid magics that mark quota file as inconsistent */ -#define LUSTRE_BADQMAGICS {\ - 0xbadbadba, /** USRQUOTA */\ - 0xbadbadba /** GRPQUOTA */\ -} - -/* for the verson 2 of lustre_disk_dqblk*/ -#define LUSTRE_INITQVERSIONS_V2 {\ - 1, /* USRQUOTA */\ - 1 /* GRPQUOTA */\ -} - -/* - * The following structure defines the format of the disk quota file - * (as it appears on disk) - the file is a radix tree whose leaves point - * to blocks of these structures. for the version 2. - */ -struct lustre_disk_dqblk_v2 { - __u32 dqb_id; /**< id this quota applies to */ - __u32 padding; - __u64 dqb_ihardlimit; /**< absolute limit on allocated inodes */ - __u64 dqb_isoftlimit; /**< preferred inode limit */ - __u64 dqb_curinodes; /**< current # allocated inodes */ - __u64 dqb_bhardlimit; /**< absolute limit on disk space (in QUOTABLOCK_SIZE) */ - __u64 dqb_bsoftlimit; /**< preferred limit on disk space (in QUOTABLOCK_SIZE) */ - __u64 dqb_curspace; /**< current space occupied (in bytes) */ - obd_time dqb_btime; /**< time limit for excessive disk use */ - obd_time dqb_itime; /**< time limit for excessive inode use */ -}; - -/* Number of entries in one blocks(14 entries) */ -#define LUSTRE_DQSTRINBLK_V2 \ - ((LUSTRE_DQBLKSIZE - sizeof(struct lustre_disk_dqdbheader)) \ - / sizeof(struct lustre_disk_dqblk_v2)) -#define GETENTRIES_V2(buf) (((char *)buf)+sizeof(struct lustre_disk_dqdbheader)) - -#define GETENTRIES(buf,version) ((version == LUSTRE_QUOTA_V2) ? \ - GETENTRIES_V2(buf) : 0) - -/* - * Here are header structures as written on disk and their in-memory copies - */ -/* First generic header */ -struct lustre_disk_dqheader { - __u32 dqh_magic; /* Magic number identifying file */ - __u32 dqh_version; /* File version */ -}; - -/* Header with type and version specific information */ -struct lustre_disk_dqinfo { - __u32 dqi_bgrace; /* Time before block soft limit becomes hard limit */ - __u32 dqi_igrace; /* Time before inode soft limit becomes hard limit */ - __u32 dqi_flags; /* Flags for quotafile (DQF_*) */ - __u32 dqi_blocks; /* Number of blocks in file */ - __u32 dqi_free_blk; /* Number of first free block in the list */ - __u32 dqi_free_entry; /* Number of block with at least one free entry */ -}; - -/* - * Structure of header of block with quota structures. It is padded to 16 bytes so - * there will be space for exactly 21 quota-entries in a block - */ -struct lustre_disk_dqdbheader { - __u32 dqdh_next_free; /* Number of next block with free entry */ - __u32 dqdh_prev_free; /* Number of previous block with free entry */ - __u16 dqdh_entries; /* Number of valid entries in block */ - __u16 dqdh_pad1; - __u32 dqdh_pad2; -}; - -#ifdef LPROCFS -void lprocfs_quotfmt_test_init_vars(struct lprocfs_static_vars *lvars); -#else -static void lprocfs_quotfmt_test_init_vars(struct lprocfs_static_vars *lvars) {} -#endif - -#define LUSTRE_DQINFOOFF sizeof(struct lustre_disk_dqheader) /* Offset of info header in file */ -#define LUSTRE_DQBLKSIZE_BITS 10 -#define LUSTRE_DQBLKSIZE (1 << LUSTRE_DQBLKSIZE_BITS) /* Size of block with quota structures */ -#define LUSTRE_DQTREEOFF 1 /* Offset of tree in file in blocks */ -#define LUSTRE_DQTREEDEPTH 4 /* Depth of quota tree */ - -typedef char *dqbuf_t; - -#define GETIDINDEX(id, depth) (((id) >> ((LUSTRE_DQTREEDEPTH-(depth)-1)*8)) & 0xff) - -#define MAX_UL (0xffffffffUL) - -#define lustre_info_dirty(info) \ - cfs_test_bit(DQF_INFO_DIRTY_B, &(info)->dqi_flags) - -struct dqblk { - cfs_list_t link; - uint blk; -}; - -/* come from lustre_fmt_common.c */ -dqbuf_t getdqbuf(void); -void freedqbuf(dqbuf_t buf); -void disk2memdqb(struct lustre_mem_dqblk *m, void *d, - enum lustre_quota_version version); -void lustre_mark_info_dirty(struct lustre_mem_dqinfo *info); -int lustre_init_quota_header(struct lustre_quota_info *lqi, int type, - int fakemagics); -int lustre_init_quota_info_generic(struct lustre_quota_info *lqi, int type, - int fakemagics); -int lustre_read_quota_info(struct lustre_quota_info *lqi, int type); -int lustre_read_quota_file_info(struct file* f, struct lustre_mem_dqinfo* info); -int lustre_write_quota_info(struct lustre_quota_info *lqi, int type); -int get_free_dqblk(struct file *filp, struct lustre_mem_dqinfo *info); -int put_free_dqblk(struct file *filp, struct lustre_mem_dqinfo *info, - dqbuf_t buf, uint blk); -int remove_free_dqentry(struct file *filp, - struct lustre_mem_dqinfo *info, dqbuf_t buf, - uint blk); -int insert_free_dqentry(struct file *filp, - struct lustre_mem_dqinfo *info, dqbuf_t buf, - uint blk); -ssize_t quota_read(struct file *file, struct inode *inode, int type, - uint blk, dqbuf_t buf); -int walk_tree_dqentry(struct file *filp, struct inode *inode, int type, - uint blk, int depth, cfs_list_t *list); -int check_quota_file(struct file *f, struct inode *inode, int type, - lustre_quota_version_t version); -int lustre_check_quota_file(struct lustre_quota_info *lqi, int type); -int lustre_read_dquot(struct lustre_dquot *dquot); -int lustre_commit_dquot(struct lustre_dquot *dquot); -int lustre_init_quota_info(struct lustre_quota_info *lqi, int type); -int lustre_get_qids(struct file *fp, struct inode *inode, int type, - cfs_list_t *list); -ssize_t lustre_read_quota(struct file *f, struct inode *inode, int type, - char *buf, int count, loff_t pos); - -#define LUSTRE_ADMIN_QUOTAFILES_V2 {\ - "admin_quotafile_v2.usr", /* user admin quotafile */\ - "admin_quotafile_v2.grp" /* group admin quotafile */\ -} - -#define LUSTRE_OPQFILES_NAMES_V2 { "lquota_v2.user", "lquota_v2.group" } -#endif /* lustre_quota_fmt.h */ diff --git a/lustre/lvfs/quotafmt_test.c b/lustre/lvfs/quotafmt_test.c deleted file mode 100644 index 20efcca..0000000 --- a/lustre/lvfs/quotafmt_test.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * lustre/lvfs/quotafmt_test.c - * - * No redistribution or use is permitted outside of Sun Microsystems, Inc. - * - * Kernel module to test lustre administrative quotafile format APIs - * from the OBD setup function - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include "lustre_quota_fmt.h" - -char *test_quotafile[2] = { "usrquota_test", "grpquota_test" }; - -static int quotfmt_initialize(struct lustre_quota_info *lqi, - struct obd_device *tgt, - struct lvfs_run_ctxt *saved) -{ - struct lustre_disk_dqheader dqhead; - static const uint quota_magics[] = LUSTRE_INITQMAGICS; - static const uint quota_versions[] = LUSTRE_INITQVERSIONS_V2; - struct file *fp; - struct inode *parent_inode = tgt->obd_lvfs_ctxt.pwd->d_inode; - size_t size; - struct dentry *de; - int i, rc = 0; - ENTRY; - - push_ctxt(saved, &tgt->obd_lvfs_ctxt, NULL); - - for (i = 0; i < MAXQUOTAS; i++) { - loff_t offset = 0; - char *name = test_quotafile[i]; - int namelen = strlen(name); - - /* remove the stale test quotafile */ - mutex_lock_nested(&parent_inode->i_mutex, I_MUTEX_PARENT); - de = lookup_one_len(name, tgt->obd_lvfs_ctxt.pwd, namelen); - if (!IS_ERR(de) && de->d_inode) - ll_vfs_unlink(parent_inode, de, - tgt->obd_lvfs_ctxt.pwdmnt); - if (!IS_ERR(de)) - dput(de); - mutex_unlock(&parent_inode->i_mutex); - - /* create quota file */ - fp = filp_open(name, O_CREAT | O_EXCL, 0644); - if (IS_ERR(fp)) { - rc = PTR_ERR(fp); - CERROR("error creating test quotafile %s (rc = %d)\n", - name, rc); - break; - } - lqi->qi_files[i] = fp; - - /* write quotafile header */ - dqhead.dqh_magic = cpu_to_le32(quota_magics[i]); - dqhead.dqh_version = cpu_to_le32(quota_versions[i]); - size = fp->f_op->write(fp, (char *)&dqhead, - sizeof(struct lustre_disk_dqheader), - &offset); - if (size != sizeof(struct lustre_disk_dqheader)) { - CERROR("error writing quotafile header %s (rc = %d)\n", - name, rc); - rc = size; - break; - } - } - - RETURN(rc); -} - -static int quotfmt_finalize(struct lustre_quota_info *lqi, - struct obd_device *tgt, struct lvfs_run_ctxt *saved) -{ - struct dentry *de; - struct inode *parent_inode = tgt->obd_lvfs_ctxt.pwd->d_inode; - int i, rc = 0; - ENTRY; - - for (i = 0; i < MAXQUOTAS; i++) { - char *name = test_quotafile[i]; - int namelen = strlen(name); - - if (lqi->qi_files[i] == NULL) - continue; - - /* close quota file */ - filp_close(lqi->qi_files[i], 0); - - /* unlink quota file */ - mutex_lock_nested(&parent_inode->i_mutex, I_MUTEX_PARENT); - - de = lookup_one_len(name, tgt->obd_lvfs_ctxt.pwd, namelen); - if (IS_ERR(de) || de->d_inode == NULL) { - rc = IS_ERR(de) ? PTR_ERR(de) : -ENOENT; - CERROR("error lookup quotafile %s (rc = %d)\n", - name, rc); - goto dput; - } - - rc = ll_vfs_unlink(parent_inode, de, tgt->obd_lvfs_ctxt.pwdmnt); - if (rc) - CERROR("error unlink quotafile %s (rc = %d)\n", - name, rc); -dput: - if (!IS_ERR(de)) - dput(de); - mutex_unlock(&parent_inode->i_mutex); - } - - pop_ctxt(saved, &tgt->obd_lvfs_ctxt, NULL); - RETURN(rc); -} - -static int quotfmt_test_1(struct lustre_quota_info *lqi) -{ - int i; - ENTRY; - - for (i = 0; i < MAXQUOTAS; i++) { - if (lustre_check_quota_file(lqi, i)) - RETURN(-EINVAL); - } - RETURN(0); -} - -static void print_quota_info(struct lustre_quota_info *lqi) -{ -#if 0 - struct lustre_mem_dqinfo *dqinfo; - int i; - - for (i = 0; i < MAXQUOTAS; i++) { - dqinfo = &lqi->qi_info[i]; - CDEBUG(D_INFO, "%s quota info:\n", i == USRQUOTA ? "user " : "group"); - CDEBUG(D_INFO, "dqi_bgrace(%u) dqi_igrace(%u) dqi_flags(%lu) dqi_blocks(%u) " - "dqi_free_blk(%u) dqi_free_entry(%u)\n", - dqinfo->dqi_bgrace, dqinfo->dqi_igrace, dqinfo->dqi_flags, - dqinfo->dqi_blocks, dqinfo->dqi_free_blk, - dqinfo->dqi_free_entry); - } -#endif -} - -static int quotfmt_test_2(struct lustre_quota_info *lqi) -{ - int i, rc = 0; - ENTRY; - - for (i = 0; i < MAXQUOTAS; i++) { - struct lustre_mem_dqinfo dqinfo; - - rc = lustre_init_quota_info(lqi, i); - if (rc) { - CERROR("init quotainfo(%d) failed! (rc:%d)\n", i, rc); - break; - } - memcpy(&dqinfo, &lqi->qi_info[i], sizeof(dqinfo)); - - rc = lustre_read_quota_info(lqi, i); - if (rc) { - CERROR("read quotainfo(%d) failed! (rc:%d)\n", i, rc); - break; - } - - if (memcmp(&dqinfo, &lqi->qi_info[i], sizeof(dqinfo))) { - rc = -EINVAL; - break; - } - } - RETURN(rc); -} - -static struct lustre_dquot *get_rand_dquot(struct lustre_quota_info *lqi) -{ - struct lustre_dquot *dquot; - unsigned int rand; - - OBD_ALLOC(dquot, sizeof(*dquot)); - if (dquot == NULL) - return NULL; - - cfs_get_random_bytes(&rand, sizeof(rand)); - if (!rand) - rand = 1000; - - dquot->dq_info = lqi; - dquot->dq_id = rand % 1000 + 1; - dquot->dq_type = rand % MAXQUOTAS; - - dquot->dq_dqb.dqb_bhardlimit = rand; - dquot->dq_dqb.dqb_bsoftlimit = rand / 2; - dquot->dq_dqb.dqb_curspace = rand / 3; - dquot->dq_dqb.dqb_ihardlimit = rand; - dquot->dq_dqb.dqb_isoftlimit = rand / 2; - dquot->dq_dqb.dqb_curinodes = rand / 3; - dquot->dq_dqb.dqb_btime = jiffies; - dquot->dq_dqb.dqb_itime = jiffies; - - return dquot; -} - -static void put_rand_dquot(struct lustre_dquot *dquot) -{ - OBD_FREE(dquot, sizeof(*dquot)); -} - -static int write_check_dquot(struct lustre_quota_info *lqi) -{ - struct lustre_dquot *dquot; - struct lustre_mem_dqblk dqblk; - int rc = 0; - ENTRY; - - dquot = get_rand_dquot(lqi); - if (dquot == NULL) - RETURN(-ENOMEM); - - /* for already exists entry, we set the dq_off by read_dquot */ - rc = lustre_read_dquot(dquot); - if (rc) { - CERROR("read dquot failed! (rc:%d)\n", rc); - GOTO(out, rc); - } - - cfs_clear_bit(DQ_FAKE_B, &dquot->dq_flags); - /* for already exists entry, we rewrite it */ - rc = lustre_commit_dquot(dquot); - if (rc) { - CERROR("commit dquot failed! (rc:%d)\n", rc); - GOTO(out, rc); - } - memcpy(&dqblk, &dquot->dq_dqb, sizeof(dqblk)); - memset(&dquot->dq_dqb, 0, sizeof(dqblk)); - - rc = lustre_read_dquot(dquot); - if (rc) { - CERROR("read dquot failed! (rc:%d)\n", rc); - GOTO(out, rc); - } - - if (memcmp(&dqblk, &dquot->dq_dqb, sizeof(dqblk))) { - rc = -EINVAL; - GOTO(out, rc); - } - out: - put_rand_dquot(dquot); - RETURN(rc); -} - -static int quotfmt_test_3(struct lustre_quota_info *lqi) -{ - struct lustre_dquot *dquot; - int i = 0, rc = 0; - ENTRY; - - dquot = get_rand_dquot(lqi); - if (dquot == NULL) - RETURN(-ENOMEM); - repeat: - cfs_clear_bit(DQ_FAKE_B, &dquot->dq_flags); - /* write a new dquot */ - rc = lustre_commit_dquot(dquot); - if (rc) { - CERROR("commit dquot failed! (rc:%d)\n", rc); - GOTO(out, rc); - } - dquot->dq_off = 0; - memset(&dquot->dq_dqb, 0, sizeof(dquot->dq_dqb)); - - /* check if this dquot is on disk now */ - rc = lustre_read_dquot(dquot); - if (rc) { - CERROR("read dquot failed! (rc:%d)\n", rc); - GOTO(out, rc); - } - if (!dquot->dq_off || cfs_test_bit(DQ_FAKE_B, &dquot->dq_flags)) { - CERROR("the dquot isn't committed\n"); - GOTO(out, rc = -EINVAL); - } - - /* remove this dquot */ - cfs_set_bit(DQ_FAKE_B, &dquot->dq_flags); - dquot->dq_dqb.dqb_curspace = 0; - dquot->dq_dqb.dqb_curinodes = 0; - rc = lustre_commit_dquot(dquot); - if (rc) { - CERROR("remove dquot failed! (rc:%d)\n", rc); - GOTO(out, rc); - } - - /* check if the dquot is really removed */ - cfs_clear_bit(DQ_FAKE_B, &dquot->dq_flags); - dquot->dq_off = 0; - rc = lustre_read_dquot(dquot); - if (rc) { - CERROR("read dquot failed! (rc:%d)\n", rc); - GOTO(out, rc); - } - if (!cfs_test_bit(DQ_FAKE_B, &dquot->dq_flags) || dquot->dq_off) { - CERROR("the dquot isn't removed!\n"); - GOTO(out, rc = -EINVAL); - } - - /* check if this dquot can be write again */ - if (++i < 2) - goto repeat; - - print_quota_info(lqi); - - out: - put_rand_dquot(dquot); - RETURN(rc); -} - -static int quotfmt_test_4(struct lustre_quota_info *lqi) -{ - int i, rc = 0; - ENTRY; - - for (i = 0; i < 30000; i++) { - rc = write_check_dquot(lqi); - if (rc) { - CERROR("write/check dquot failed at %d! (rc:%d)\n", - i, rc); - break; - } - } - print_quota_info(lqi); - RETURN(rc); -} - -static int quotfmt_run_tests(struct obd_device *obd, struct obd_device *tgt) -{ - struct lvfs_run_ctxt saved; - struct lustre_quota_info *lqi = NULL; - int rc = 0; - ENTRY; - - OBD_ALLOC(lqi, sizeof(*lqi)); - if (lqi == NULL) { - CERROR("not enough memory\n"); - RETURN(-ENOMEM); - } - - CWARN("=== Initialize quotafile test\n"); - rc = quotfmt_initialize(lqi, tgt, &saved); - if (rc) - GOTO(out, rc); - - CWARN("=== test 1: check quota header\n"); - rc = quotfmt_test_1(lqi); - if (rc) { - CERROR("check quota header failed! (rc:%d)\n", rc); - GOTO(out, rc); - } - - CWARN("=== test 2: write/read quota info\n"); - rc = quotfmt_test_2(lqi); - if (rc) { - CERROR("write/read quota info failed! (rc:%d)\n", rc); - GOTO(out, rc); - } - - CWARN("=== test 3: write/remove dquot\n"); - rc = quotfmt_test_3(lqi); - if (rc) { - CERROR("write/remove dquot failed! (rc:%d)\n", rc); - GOTO(out, rc); - } - - CWARN("=== test 4: write/read 30000 dquot\n"); - rc = quotfmt_test_4(lqi); - if (rc) { - CERROR("write/read 30000 dquot failed\n"); - GOTO(out, rc); - } - -out: - CWARN("=== Finalize quotafile test\n"); - rc = quotfmt_finalize(lqi, tgt, &saved); - OBD_FREE(lqi, sizeof(*lqi)); - RETURN(rc); -} - -static int quotfmt_test_cleanup(struct obd_device *obd) -{ - ENTRY; - lprocfs_obd_cleanup(obd); - RETURN(0); -} - -static int quotfmt_test_setup(struct obd_device *obd, struct lustre_cfg *lcfg) -{ - struct lprocfs_static_vars lvars; - struct obd_device *tgt; - int rc; - ENTRY; - - if (lcfg->lcfg_bufcount < 1) { - CERROR("requires a mds OBD name\n"); - RETURN(-EINVAL); - } - - tgt = class_name2obd(lustre_cfg_string(lcfg, 1)); - if (!tgt || !tgt->obd_attached || !tgt->obd_set_up) { - CERROR("target device not attached or not set up (%s)\n", - lustre_cfg_string(lcfg, 1)); - RETURN(-EINVAL); - } - - rc = quotfmt_run_tests(obd, tgt); - if (rc) - quotfmt_test_cleanup(obd); - - lprocfs_quotfmt_test_init_vars(&lvars); - lprocfs_obd_setup(obd, lvars.obd_vars); - - RETURN(rc); -} - -static struct obd_ops quotfmt_obd_ops = { - .o_owner = THIS_MODULE, - .o_setup = quotfmt_test_setup, - .o_cleanup = quotfmt_test_cleanup, -}; - -#ifdef LPROCFS -static struct lprocfs_vars lprocfs_quotfmt_test_obd_vars[] = { {0} }; -static struct lprocfs_vars lprocfs_quotfmt_test_module_vars[] = { {0} }; - -void lprocfs_quotfmt_test_init_vars(struct lprocfs_static_vars *lvars) -{ - lvars->module_vars = lprocfs_quotfmt_test_module_vars; - lvars->obd_vars = lprocfs_quotfmt_test_obd_vars; -} -#endif -static int __init quotfmt_test_init(void) -{ - struct lprocfs_static_vars lvars; - - lprocfs_quotfmt_test_init_vars(&lvars); - return class_register_type("fmt_obd_ops, NULL, lvars.module_vars, - "quotfmt_test", NULL); -} - -static void __exit quotfmt_test_exit(void) -{ - class_unregister_type("quotfmt_test"); -} - -MODULE_AUTHOR("Sun Microsystems, Inc. "); -MODULE_DESCRIPTION("administrative quotafile test module"); -MODULE_LICENSE("GPL"); - -module_init(quotfmt_test_init); -module_exit(quotfmt_test_exit); diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 426717b..185f348 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -1027,25 +1027,6 @@ static int osd_init_capa_ctxt(const struct lu_env *env, struct dt_device *d, } /** - * Concurrency: serialization provided by callers. - */ -static void osd_init_quota_ctxt(const struct lu_env *env, struct dt_device *d, - struct dt_quota_ctxt *ctxt, void *data) -{ - struct obd_device *obd = (void *)ctxt; - struct vfsmount *mnt = (struct vfsmount *)data; - ENTRY; - - obd->u.obt.obt_sb = mnt->mnt_root->d_inode->i_sb; - OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt); - obd->obd_lvfs_ctxt.pwdmnt = mnt; - obd->obd_lvfs_ctxt.pwd = mnt->mnt_root; - obd->obd_lvfs_ctxt.fs = get_ds(); - - EXIT; -} - -/** * Note: we do not count into QUOTA here. * If we mount with --data_journal we may need more. */ @@ -1113,7 +1094,6 @@ static const struct dt_device_operations osd_dt_ops = { .dt_ro = osd_ro, .dt_commit_async = osd_commit_async, .dt_init_capa_ctxt = osd_init_capa_ctxt, - .dt_init_quota_ctxt= osd_init_quota_ctxt, }; static void osd_object_read_lock(const struct lu_env *env, -- 1.8.3.1