/* -*- 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
# 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
+# include <linux/smp_lock.h>
+# include <linux/buffer_head.h>
+# include <linux/workqueue.h>
+# include <linux/mount.h>
#else /* __KERNEL__ */
# include <liblustre.h>
#endif
#ifdef __KERNEL__
-
/* quota proc file handling functions */
#ifdef LPROCFS
int lprocfs_rd_bunit(char *page, char **start, off_t off, int count,
LASSERT(obd != NULL);
rc = lprocfs_write_helper(buffer, count, &val);
+
if (rc)
return rc;
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;
}
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;
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;
}
RETURN(rc);
}
+
int lprocfs_wr_type(struct file *file, const char *buffer,
unsigned long count, void *data)
{
CERROR("initialize quota context failed! (rc:%d)\n", rc);
RETURN(rc);
}
+
RETURN(rc);
}
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);
}
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;
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;
CERROR("initialize quota context failed! (rc:%d)\n", rc);
RETURN(rc);
}
+
RETURN(rc);
}
/* 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);
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;
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;
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)
{
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);
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);
}
.quota_getflag = filter_quota_getflag,
.quota_acquire = filter_quota_acquire,
.quota_adjust = filter_quota_adjust,
+ .quota_chkquota = filter_quota_check,
};
#endif /* __KERNEL__ */
qunit_cache_cleanup();
}
-MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
+MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
MODULE_DESCRIPTION("Lustre Quota");
MODULE_LICENSE("GPL");