quota_interface.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 948 行 · 第 1/3 页

C
948
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * lustre/quota/quota_interface.c * * Copyright (c) 2001-2005 Cluster File Systems, Inc. * * This file is part of Lustre, http://www.lustre.org. * * No redistribution or use is permitted outside of Cluster File Systems, Inc. * */#ifndef EXPORT_SYMTAB# define EXPORT_SYMTAB#endif#define DEBUG_SUBSYSTEM S_MDS#ifdef __KERNEL__# include <linux/version.h># include <linux/module.h># include <linux/init.h># include <linux/fs.h># include <linux/jbd.h># include <linux/ext3_fs.h># if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))#  include <linux/smp_lock.h>#  include <linux/buffer_head.h>#  include <linux/workqueue.h>#  include <linux/mount.h># else#  include <linux/locks.h># endif#else /* __KERNEL__ */# include <liblustre.h>#endif#include <obd_class.h>#include <lustre_mds.h>#include <lustre_dlm.h>#include <lustre_cfg.h>#include <obd_ost.h>#include <lustre_fsfilt.h>#include <lustre_quota.h>#include <lprocfs_status.h>#include "quota_internal.h"#ifdef __KERNEL__/* quota proc file handling functions */#ifdef LPROCFS#define USER_QUOTA      1#define GROUP_QUOTA     2#define MAX_STYPE_SIZE  5int lprocfs_quota_rd_type(char *page, char **start, off_t off, int count,                          int *eof, void *data){        struct obd_device *obd = (struct obd_device *)data;        char stype[MAX_STYPE_SIZE + 1] = "";        int type = obd->u.obt.obt_qctxt.lqc_atype;        LASSERT(obd != NULL);        if (type == 0) {                strcpy(stype, "off");        } else {                if (type & USER_QUOTA)                        strcat(stype, "u");                if (type & GROUP_QUOTA)                        strcat(stype, "g");        }        /* append with quota version on MDS */        if (!strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME)) {                int rc;                lustre_quota_version_t version;                rc = mds_quota_get_version(obd, &version);                if (rc)                        return rc;                switch (version) {                        case LUSTRE_QUOTA_V1:                                strcat(stype, "1");                                break;                        case LUSTRE_QUOTA_V2:                                strcat(stype, "2");                                break;                        default:                                return -ENOSYS;                }        }        return snprintf(page, count, "%s\n", stype);}EXPORT_SYMBOL(lprocfs_quota_rd_type);static int auto_quota_on(struct obd_device *obd, int type,                         struct super_block *sb, int is_master){        struct obd_quotactl *oqctl;        struct lvfs_run_ctxt saved;        int rc;        ENTRY;        LASSERT(type == USRQUOTA || type == GRPQUOTA || type == UGQUOTA);        /* quota already turned on */        if (obd->u.obt.obt_qctxt.lqc_status)                RETURN(0);        OBD_ALLOC_PTR(oqctl);        if (!oqctl)                RETURN(-ENOMEM);        oqctl->qc_type = type;        oqctl->qc_cmd = Q_QUOTAON;        oqctl->qc_id = QFMT_LDISKFS;        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);        if (!is_master)                goto local_quota;        /* turn on cluster wide quota */        rc = mds_admin_quota_on(obd, oqctl);        if (rc) {                CDEBUG(rc == -ENOENT ? D_QUOTA : D_ERROR,                       "auto-enable admin quota failed. rc=%d\n", rc);                GOTO(out_pop, rc);        }local_quota:        /* turn on local quota */        rc = fsfilt_quotactl(obd, sb, oqctl);        if (rc) {                CDEBUG(rc == -ENOENT ? D_QUOTA : D_ERROR,                       "auto-enable local quota failed. rc=%d\n", rc);                if (is_master)                        mds_quota_off(obd, oqctl);        } else {                obd->u.obt.obt_qctxt.lqc_status = 1;        }out_pop:        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);        OBD_FREE_PTR(oqctl);        RETURN(rc);}int lprocfs_quota_wr_type(struct file *file, const char *buffer,                          unsigned long count, void *data){        struct obd_device *obd = (struct obd_device *)data;        struct obd_device_target *obt = &obd->u.obt;        int type = 0;        unsigned long i;        char stype[MAX_STYPE_SIZE + 1] = "";        LASSERT(obd != NULL);        if (count > MAX_STYPE_SIZE)                return -EINVAL;        if (copy_from_user(stype, buffer, count))                return -EFAULT;        for (i = 0 ; i < count ; i++) {                int rc;                switch (stype[i]) {                case 'u' :                        type |= USER_QUOTA;                        break;                case 'g' :                        type |= GROUP_QUOTA;                        break;                /* quota version specifiers */                case '1' :                        if (strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME))                                break;                        rc = mds_quota_set_version(obd, LUSTRE_QUOTA_V1);                        if (rc) {                                CDEBUG(D_QUOTA, "failed to set quota v1! %d\n", rc);                                return rc;                        }                        break;                case '2' :                        if (strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME))                                break;                        rc = mds_quota_set_version(obd, LUSTRE_QUOTA_V2);                        if (rc) {                                CDEBUG(D_QUOTA, "could not set quota v2! %d\n", rc);                                return rc;                        }                        break;                default  : /* just skip stray symbols like \n */                        break;                }        }        obt->obt_qctxt.lqc_atype = type;        if (type == 0)                return count;        if (!strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME))                auto_quota_on(obd, type - 1, obt->obt_sb, 1);        else if (!strcmp(obd->obd_type->typ_name, LUSTRE_OST_NAME))                auto_quota_on(obd, type - 1, obt->obt_sb, 0);        else                return -EFAULT;        return count;}EXPORT_SYMBOL(lprocfs_quota_wr_type);#endif /* LPROCFS */static int filter_quota_setup(struct obd_device *obd){        int rc = 0;        struct obd_device_target *obt = &obd->u.obt;        ENTRY;        atomic_set(&obt->obt_quotachecking, 1);        rc = qctxt_init(&obt->obt_qctxt, obt->obt_sb, NULL);        if (rc) {                CERROR("initialize quota context failed! (rc:%d)\n", rc);                RETURN(rc);        }        RETURN(rc);}static int filter_quota_cleanup(struct obd_device *obd){        qctxt_cleanup(&obd->u.obt.obt_qctxt, 0);        return 0;}static int filter_quota_setinfo(struct obd_export *exp, struct obd_device *obd){        struct obd_import *imp;        /* setup the quota context import */        spin_lock(&obd->u.obt.obt_qctxt.lqc_lock);        obd->u.obt.obt_qctxt.lqc_import = exp->exp_imp_reverse;        spin_unlock(&obd->u.obt.obt_qctxt.lqc_lock);        /* make imp's connect flags equal relative exp's connect flags         * adding it to avoid the scan export list         */        imp = exp->exp_imp_reverse;        if (imp)                imp->imp_connect_data.ocd_connect_flags |=                        (exp->exp_connect_flags &                         (OBD_CONNECT_QUOTA64 | OBD_CONNECT_CHANGE_QS));        /* start quota slave recovery thread. (release high limits) */        qslave_start_recovery(obd, &obd->u.obt.obt_qctxt);        return 0;}static int filter_quota_clearinfo(struct obd_export *exp, struct obd_device *obd){        struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;        /* lquota may be not set up before destroying export, b=14896 */        if (!obd->obd_set_up)                return 0;        /* when exp->exp_imp_reverse is destroyed, the corresponding lqc_import         * should be invalid b=12374 */        if (qctxt->lqc_import == exp->exp_imp_reverse) {                spin_lock(&qctxt->lqc_lock);                qctxt->lqc_import = NULL;                spin_unlock(&qctxt->lqc_lock);        }        return 0;}static int filter_quota_enforce(struct obd_device *obd, unsigned int ignore){        ENTRY;        if (!sb_any_quota_enabled(obd->u.obt.obt_sb))                RETURN(0);        if (ignore)                cap_raise(current->cap_effective, CAP_SYS_RESOURCE);        else                cap_lower(current->cap_effective, CAP_SYS_RESOURCE);        RETURN(0);}static int filter_quota_getflag(struct obd_device *obd, struct obdo *oa){        struct obd_device_target *obt = &obd->u.obt;        int err, cnt, rc = 0;        struct obd_quotactl *oqctl;        ENTRY;        if (!sb_any_quota_enabled(obt->obt_sb))                RETURN(0);        oa->o_flags &= ~(OBD_FL_NO_USRQUOTA | OBD_FL_NO_GRPQUOTA);        OBD_ALLOC_PTR(oqctl);        if (!oqctl) {                CERROR("Not enough memory!");                RETURN(-ENOMEM);        }        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?