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 + -
显示快捷键?