X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fquota%2Fquota_interface.c;h=e035ceb57ae3acae261780952e7157bf11af8f7b;hb=86a06098ea05b37f5bb5e7ac59f3d6f1972abbe4;hp=87651190a060956cd52c928e9166346f5d812239;hpb=113303973ec9f8484eb2355a1a6ef3c4c7fd6a56;p=fs%2Flustre-release.git diff --git a/lustre/quota/quota_interface.c b/lustre/quota/quota_interface.c index 8765119..e035ceb 100644 --- a/lustre/quota/quota_interface.c +++ b/lustre/quota/quota_interface.c @@ -1,15 +1,39 @@ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * - * lustre/quota/quota_interface.c + * GPL HEADER START * - * Copyright (c) 2001-2005 Cluster File Systems, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * This file is part of Lustre, http://www.lustre.org. + * 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. * - * No redistribution or use is permitted outside of Cluster File Systems, Inc. + * 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 2008 Sun Microsystems, Inc. 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. */ + #ifndef EXPORT_SYMTAB # define EXPORT_SYMTAB #endif @@ -22,14 +46,10 @@ # include # include # include -# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) -# include -# include -# include -# include -# else -# include -# endif +# include +# include +# include +# include #else /* __KERNEL__ */ # include #endif @@ -46,7 +66,6 @@ #ifdef __KERNEL__ - /* quota proc file handling functions */ #ifdef LPROCFS int lprocfs_rd_bunit(char *page, char **start, off_t off, int count, @@ -79,6 +98,7 @@ int lprocfs_wr_bunit(struct file *file, const char *buffer, LASSERT(obd != NULL); rc = lprocfs_write_helper(buffer, count, &val); + if (rc) return rc; @@ -158,11 +178,11 @@ int lprocfs_wr_itune(struct file *file, const char *buffer, struct obd_device *obd = (struct obd_device *)data; int val, rc; LASSERT(obd != NULL); - + rc = lprocfs_write_helper(buffer, count, &val); if (rc) return rc; - + if (val <= MIN_QLIMIT || val >= obd->u.obt.obt_qctxt.lqc_iunit_sz) return -EINVAL; @@ -197,7 +217,7 @@ int lprocfs_rd_type(char *page, char **start, off_t off, int count, } EXPORT_SYMBOL(lprocfs_rd_type); -static int auto_quota_on(struct obd_device *obd, int type, +static int auto_quota_on(struct obd_device *obd, int type, struct super_block *sb, int is_master) { struct obd_quotactl *oqctl; @@ -238,7 +258,7 @@ local_quota: CDEBUG(rc == -ENOENT ? D_QUOTA : D_ERROR, "auto-enable local quota failed. rc=%d\n", rc); if (is_master) - mds_quota_off(obd, oqctl); + mds_quota_off(obd, oqctl); } else { obd->u.obt.obt_qctxt.lqc_status = 1; } @@ -249,6 +269,7 @@ out_pop: RETURN(rc); } + int lprocfs_wr_type(struct file *file, const char *buffer, unsigned long count, void *data) { @@ -295,6 +316,7 @@ static int filter_quota_setup(struct obd_device *obd) CERROR("initialize quota context failed! (rc:%d)\n", rc); RETURN(rc); } + RETURN(rc); } @@ -331,9 +353,9 @@ static int filter_quota_enforce(struct obd_device *obd, unsigned int ignore) RETURN(0); if (ignore) - cap_raise(current->cap_effective, CAP_SYS_RESOURCE); + cfs_cap_raise(CFS_CAP_SYS_RESOURCE); else - cap_lower(current->cap_effective, CAP_SYS_RESOURCE); + cfs_cap_lower(CFS_CAP_SYS_RESOURCE); RETURN(0); } @@ -373,16 +395,16 @@ static int filter_quota_getflag(struct obd_device *obd, struct obdo *oa) oa->o_valid |= (cnt == USRQUOTA) ? OBD_MD_FLUSRQUOTA : OBD_MD_FLGRPQUOTA; if (oqctl->qc_dqblk.dqb_bhardlimit && - (toqb(oqctl->qc_dqblk.dqb_curspace) > + (toqb(oqctl->qc_dqblk.dqb_curspace) > oqctl->qc_dqblk.dqb_bhardlimit)) - oa->o_flags |= (cnt == USRQUOTA) ? + oa->o_flags |= (cnt == USRQUOTA) ? OBD_FL_NO_USRQUOTA : OBD_FL_NO_GRPQUOTA; } OBD_FREE_PTR(oqctl); RETURN(rc); } -static int filter_quota_acquire(struct obd_device *obd, unsigned int uid, +static int filter_quota_acquire(struct obd_device *obd, unsigned int uid, unsigned int gid) { struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; @@ -404,6 +426,38 @@ static int mds_quota_exit(void) return 0; } +/* check whether the left quota of certain uid and uid can satisfy a write rpc + * when need to acquire quota, return QUOTA_RET_ACQUOTA */ +static int filter_quota_check(struct obd_device *obd, unsigned int uid, + unsigned int gid, int npage) +{ + struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; + int i; + __u32 id[MAXQUOTAS] = { uid, gid }; + struct qunit_data qdata[MAXQUOTAS]; + int rc; + ENTRY; + + CLASSERT(MAXQUOTAS < 4); + if (!sb_any_quota_enabled(qctxt->lqc_sb)) + RETURN(0); + + for (i = 0; i < MAXQUOTAS; i++) { + qdata[i].qd_id = id[i]; + qdata[i].qd_flags = i; + qdata[i].qd_flags |= QUOTA_IS_BLOCK; + qdata[i].qd_count = 0; + + qctxt_wait_pending_dqacq(qctxt, id[i], i, 1); + rc = compute_remquota(obd, qctxt, &qdata[i]); + if (rc == QUOTA_RET_OK && + qdata[i].qd_count < npage * CFS_PAGE_SIZE) + RETURN(QUOTA_RET_ACQUOTA); + } + + RETURN(rc); +} + static int mds_quota_setup(struct obd_device *obd) { struct obd_device_target *obt = &obd->u.obt; @@ -419,6 +473,7 @@ static int mds_quota_setup(struct obd_device *obd) CERROR("initialize quota context failed! (rc:%d)\n", rc); RETURN(rc); } + RETURN(rc); } @@ -473,7 +528,7 @@ static inline int hashfn(struct client_obd *cli, unsigned long id, int type) /* caller must hold qinfo_list_lock */ static inline void insert_qinfo_hash(struct osc_quota_info *oqi) { - struct list_head *head = qinfo_hash + + struct list_head *head = qinfo_hash + hashfn(oqi->oqi_cli, oqi->oqi_id, oqi->oqi_type); LASSERT_SPIN_LOCKED(&qinfo_list_lock); @@ -513,7 +568,7 @@ static struct osc_quota_info *alloc_qinfo(struct client_obd *cli, if(!oqi) RETURN(NULL); - INIT_LIST_HEAD(&oqi->oqi_hash); + CFS_INIT_LIST_HEAD(&oqi->oqi_hash); oqi->oqi_cli = cli; oqi->oqi_id = id; oqi->oqi_type = type; @@ -526,7 +581,7 @@ static void free_qinfo(struct osc_quota_info *oqi) OBD_SLAB_FREE(oqi, qinfo_cachep, sizeof(*oqi)); } -int osc_quota_chkdq(struct client_obd *cli, +int osc_quota_chkdq(struct client_obd *cli, unsigned int uid, unsigned int gid) { unsigned int id; @@ -549,7 +604,7 @@ int osc_quota_chkdq(struct client_obd *cli, RETURN(rc); } -int osc_quota_setdq(struct client_obd *cli, +int osc_quota_setdq(struct client_obd *cli, unsigned int uid, unsigned int gid, obd_flag valid, obd_flag flags) { @@ -562,12 +617,12 @@ int osc_quota_setdq(struct client_obd *cli, for (cnt = 0; cnt < MAXQUOTAS; cnt++) { struct osc_quota_info *oqi, *old; - if (!(valid & ((cnt == USRQUOTA) ? + if (!(valid & ((cnt == USRQUOTA) ? OBD_MD_FLUSRQUOTA : OBD_MD_FLGRPQUOTA))) continue; id = (cnt == USRQUOTA) ? uid : gid; - noquota = (cnt == USRQUOTA) ? + noquota = (cnt == USRQUOTA) ? (flags & OBD_FL_NO_USRQUOTA) : (flags & OBD_FL_NO_GRPQUOTA); oqi = alloc_qinfo(cli, id, cnt); @@ -624,13 +679,13 @@ int osc_quota_init(void) LASSERT(qinfo_cachep == NULL); qinfo_cachep = cfs_mem_cache_create("osc_quota_info", - sizeof(struct osc_quota_info), - 0, 0); + sizeof(struct osc_quota_info), + 0, 0); if (!qinfo_cachep) RETURN(-ENOMEM); for (i = 0; i < NR_DQHASH; i++) - INIT_LIST_HEAD(qinfo_hash + i); + CFS_INIT_LIST_HEAD(qinfo_hash + i); RETURN(0); } @@ -680,6 +735,7 @@ quota_interface_t filter_quota_interface = { .quota_getflag = filter_quota_getflag, .quota_acquire = filter_quota_acquire, .quota_adjust = filter_quota_adjust, + .quota_chkquota = filter_quota_check, }; #endif /* __KERNEL__ */ @@ -730,7 +786,7 @@ static void /*__exit*/ exit_lustre_quota(void) qunit_cache_cleanup(); } -MODULE_AUTHOR("Cluster File Systems, Inc. "); +MODULE_AUTHOR("Sun Microsystems, Inc. "); MODULE_DESCRIPTION("Lustre Quota"); MODULE_LICENSE("GPL");