1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Use is subject to license terms.
32 * Copyright (c) 2011, 2012, Whamcloud, Inc.
35 * This file is part of Lustre, http://www.lustre.org/
36 * Lustre is a trademark of Sun Microsystems, Inc.
41 # define EXPORT_SYMTAB
43 #define DEBUG_SUBSYSTEM S_LQUOTA
46 # include <linux/version.h>
47 # include <linux/module.h>
48 # include <linux/init.h>
49 # include <linux/fs.h>
50 # include <linux/jbd.h>
51 # include <linux/ext3_fs.h>
52 # include <linux/smp_lock.h>
53 # include <linux/buffer_head.h>
54 # include <linux/workqueue.h>
55 # include <linux/mount.h>
56 #else /* __KERNEL__ */
57 # include <liblustre.h>
60 #include <obd_class.h>
61 #include <lustre_mds.h>
62 #include <lustre_dlm.h>
63 #include <lustre_cfg.h>
65 #include <lustre_fsfilt.h>
66 #include <lustre_quota.h>
67 #include "quota_internal.h"
69 #ifdef HAVE_QUOTA_SUPPORT
71 static int target_quotacheck_callback(struct obd_export *exp,
72 struct obd_quotactl *oqctl)
74 struct ptlrpc_request *req;
75 struct obd_quotactl *body;
79 req = ptlrpc_request_alloc_pack(exp->exp_imp_reverse, &RQF_QC_CALLBACK,
80 LUSTRE_OBD_VERSION, OBD_QC_CALLBACK);
84 body = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL);
87 ptlrpc_request_set_replen(req);
89 rc = ptlrpc_queue_wait(req);
90 ptlrpc_req_finished(req);
95 static int target_quotacheck_thread(void *data)
97 struct quotacheck_thread_args *qta = data;
98 struct obd_export *exp;
99 struct obd_device *obd;
100 struct obd_quotactl *oqctl;
101 struct lvfs_run_ctxt saved;
104 cfs_daemonize_ctxt("quotacheck");
108 oqctl = &qta->qta_oqctl;
110 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
112 rc = fsfilt_quotacheck(obd, qta->qta_sb, oqctl);
114 CERROR("%s: fsfilt_quotacheck: %d\n", obd->obd_name, rc);
116 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
118 rc = target_quotacheck_callback(exp, oqctl);
119 class_export_put(exp);
120 cfs_up(qta->qta_sem);
125 int target_quota_check(struct obd_device *obd, struct obd_export *exp,
126 struct obd_quotactl *oqctl)
128 struct obd_device_target *obt = &obd->u.obt;
129 struct quotacheck_thread_args *qta;
137 cfs_down(&obt->obt_quotachecking);
141 qta->qta_oqctl = *oqctl;
142 qta->qta_oqctl.qc_id = obt->obt_qfmt; /* override qfmt version */
143 qta->qta_sb = obt->obt_sb;
144 qta->qta_sem = &obt->obt_quotachecking;
146 /* quotaoff firstly */
147 oqctl->qc_cmd = Q_QUOTAOFF;
148 if (!strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME)) {
149 rc = do_mds_quota_off(obd, oqctl);
150 if (rc && rc != -EALREADY) {
151 CERROR("off quota on MDS failed: %d\n", rc);
156 rc = init_admin_quotafiles(obd, &qta->qta_oqctl);
158 CERROR("init_admin_quotafiles failed: %d\n", rc);
162 struct lvfs_run_ctxt saved;
163 struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt;
165 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
166 rc = fsfilt_quotactl(obd, obt->obt_sb, oqctl);
167 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
169 qctxt->lqc_flags &= ~UGQUOTA2LQC(oqctl->qc_type);
170 } else if (!quota_is_off(qctxt, oqctl)) {
171 CERROR("off quota on OSS failed: %d\n", rc);
176 /* we get ref for exp because target_quotacheck_callback() will use this
177 * export later b=18126 */
178 class_export_get(exp);
179 rc = cfs_create_thread(target_quotacheck_thread, qta,
182 /* target_quotacheck_thread will drop the ref on exp and release
183 * obt_quotachecking */
184 CDEBUG(D_INFO, "%s: target_quotacheck_thread: %d\n",
188 CERROR("%s: error starting quotacheck_thread: %d\n",
190 class_export_put(exp);
195 cfs_up(&obt->obt_quotachecking);
200 #endif /* __KERNEL__ */
201 #endif /* HAVE_QUOTA_SUPPORT */