fsfilt_ext3.c
来自「lustre 1.6.5 source code」· C语言 代码 · 共 1,853 行 · 第 1/5 页
C
1,853 行
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) { if (!qcop->quota_on) GOTO(out, rc = -ENOSYS); rc = qcop->quota_on(sb, i, oqc->qc_id, (char *)op_quotafile[i]); } else if (oqc->qc_cmd == Q_QUOTAOFF) { if (!qcop->quota_off) GOTO(out, rc = -ENOSYS); rc = qcop->quota_off(sb, i); } 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; default: CERROR("unsupported quotactl command: %d", 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 %d " "failed: %d\n", oqc->qc_cmd, oqc->qc_id, oqc->qc_type, rc); RETURN(rc);}struct chk_dqblk{ struct hlist_node dqb_hash; /* quotacheck hash */ struct list_head 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 */ __u64 dqb_btime; /* block grace time */ __u64 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(struct hlist_head *head, qid_t id, int type){ struct hlist_node *node; struct chk_dqblk *cdqb; hlist_for_each(node, head) { cdqb = 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) { INIT_HLIST_NODE(&cdqb->dqb_hash); 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, struct hlist_head *hash, struct list_head *list, qid_t id, int type, int first_check){ struct hlist_head *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; } } hlist_add_head(&cdqb->dqb_hash, head); list_add_tail(&cdqb->dqb_list, list); return cdqb;}static inline int quota_onoff(struct super_block *sb, int cmd, int type){ struct obd_quotactl *oqctl; int rc; OBD_ALLOC_PTR(oqctl); if (!oqctl) RETURN(-ENOMEM); oqctl->qc_cmd = cmd; oqctl->qc_id = QFMT_LDISKFS; 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);}static inline struct ext3_group_desc *get_group_desc(struct super_block *sb, int group){ unsigned long desc_block, desc; struct ext3_group_desc *gdp; desc_block = group / EXT3_DESC_PER_BLOCK(sb); desc = group % EXT3_DESC_PER_BLOCK(sb); gdp = (struct ext3_group_desc *) EXT3_SB(sb)->s_group_desc[desc_block]->b_data; return gdp + desc;}static inline struct buffer_head *read_inode_bitmap(struct super_block *sb, unsigned long group){ struct ext3_group_desc *desc; struct buffer_head *bh; desc = get_group_desc(sb, group); bh = sb_bread(sb, le32_to_cpu(desc->bg_inode_bitmap)); return bh;}static inline struct inode *ext3_iget_inuse(struct super_block *sb, struct buffer_head *bitmap_bh, int index, unsigned long ino){ struct inode *inode = NULL; if (ext3_test_bit(index, bitmap_bh->b_data)) inode = iget(sb, ino); return inode;}struct qchk_ctxt { struct hlist_head qckt_hash[NR_DQHASH]; /* quotacheck hash */ struct list_head 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;}static int v2_write_dqheader(struct file *f, int type){ static const __u32 quota_magics[] = V2_INITQMAGICS; static const __u32 quota_versions[] = V2_INITQVERSIONS; 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);}/* write dqinfo struct in a new quota file */static int v2_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 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; if (!Q_TYPESET(oqc, i)) continue; file = filp_open(op_quotafile[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", op_quotafile[i], rc); GOTO(out, rc); } if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?