OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [xfs/] [quota/] [xfs_qm.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
3
 *
4
 * This program is free software; you can redistribute it and/or modify it
5
 * under the terms of version 2 of the GNU General Public License as
6
 * published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it would be useful, but
9
 * WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * Further, this software is distributed without any warranty that it is
13
 * free of the rightful claim of any third person regarding infringement
14
 * or the like.  Any license provided herein, whether implied or
15
 * otherwise, applies only to this software file.  Patent licenses, if
16
 * any, provided herein do not apply to combinations of this program with
17
 * other software, or any other product whatsoever.
18
 *
19
 * You should have received a copy of the GNU General Public License along
20
 * with this program; if not, write the Free Software Foundation, Inc., 59
21
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22
 *
23
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24
 * Mountain View, CA  94043, or:
25
 *
26
 * http://www.sgi.com
27
 *
28
 * For further information regarding this notice, see:
29
 *
30
 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31
 */
32
 
33
#include "xfs.h"
34
#include "xfs_fs.h"
35
#include "xfs_inum.h"
36
#include "xfs_log.h"
37
#include "xfs_clnt.h"
38
#include "xfs_trans.h"
39
#include "xfs_sb.h"
40
#include "xfs_ag.h"
41
#include "xfs_dir.h"
42
#include "xfs_dir2.h"
43
#include "xfs_alloc.h"
44
#include "xfs_dmapi.h"
45
#include "xfs_quota.h"
46
#include "xfs_mount.h"
47
#include "xfs_alloc_btree.h"
48
#include "xfs_bmap_btree.h"
49
#include "xfs_ialloc_btree.h"
50
#include "xfs_btree.h"
51
#include "xfs_ialloc.h"
52
#include "xfs_attr_sf.h"
53
#include "xfs_dir_sf.h"
54
#include "xfs_dir2_sf.h"
55
#include "xfs_dinode.h"
56
#include "xfs_inode.h"
57
#include "xfs_bmap.h"
58
#include "xfs_bit.h"
59
#include "xfs_rtalloc.h"
60
#include "xfs_error.h"
61
#include "xfs_itable.h"
62
#include "xfs_rw.h"
63
#include "xfs_acl.h"
64
#include "xfs_cap.h"
65
#include "xfs_mac.h"
66
#include "xfs_attr.h"
67
#include "xfs_buf_item.h"
68
#include "xfs_trans_space.h"
69
#include "xfs_utils.h"
70
 
71
#include "xfs_qm.h"
72
 
73
/*
74
 * The global quota manager. There is only one of these for the entire
75
 * system, _not_ one per file system. XQM keeps track of the overall
76
 * quota functionality, including maintaining the freelist and hash
77
 * tables of dquots.
78
 */
79
mutex_t xfs_Gqm_lock;
80
struct xfs_qm   *xfs_Gqm;
81
 
82
kmem_zone_t     *qm_dqzone;
83
kmem_zone_t     *qm_dqtrxzone;
84
kmem_shaker_t   xfs_qm_shaker;
85
 
86
STATIC void     xfs_qm_list_init(xfs_dqlist_t *, char *, int);
87
STATIC void     xfs_qm_list_destroy(xfs_dqlist_t *);
88
STATIC int      xfs_qm_quotacheck(xfs_mount_t *);
89
 
90
STATIC int      xfs_qm_init_quotainos(xfs_mount_t *);
91
STATIC int      xfs_qm_shake(int, unsigned int);
92
 
93
#ifdef DEBUG
94
extern mutex_t  qcheck_lock;
95
#endif
96
 
97
#ifdef QUOTADEBUG
98
#define XQM_LIST_PRINT(l, NXT, title) \
99
{ \
100
        xfs_dquot_t     *dqp; int i = 0; \
101
        cmn_err(CE_DEBUG, "%s (#%d)", title, (int) (l)->qh_nelems); \
102
        for (dqp = (l)->qh_next; dqp != NULL; dqp = dqp->NXT) { \
103
                cmn_err(CE_DEBUG, "   %d.  \"%d (%s)\"   " \
104
                                  "bcnt = %d, icnt = %d, refs = %d", \
105
                        ++i, (int) INT_GET(dqp->q_core.d_id, ARCH_CONVERT), \
106
                        DQFLAGTO_TYPESTR(dqp),       \
107
                        (int) INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT), \
108
                        (int) INT_GET(dqp->q_core.d_icount, ARCH_CONVERT), \
109
                        (int) dqp->q_nrefs);  } \
110
}
111
#else
112
#define XQM_LIST_PRINT(l, NXT, title) do { } while (0)
113
#endif
114
 
115
/*
116
 * Initialize the XQM structure.
117
 * Note that there is not one quota manager per file system.
118
 */
119
STATIC struct xfs_qm *
120
xfs_Gqm_init(void)
121
{
122
        xfs_qm_t                *xqm;
123
        int                     hsize, i;
124
 
125
        xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP);
126
        ASSERT(xqm);
127
 
128
        /*
129
         * Initialize the dquot hash tables.
130
         */
131
        hsize = (DQUOT_HASH_HEURISTIC < XFS_QM_NCSIZE_THRESHOLD) ?
132
                XFS_QM_HASHSIZE_LOW : XFS_QM_HASHSIZE_HIGH;
133
        xqm->qm_dqhashmask = hsize - 1;
134
 
135
        xqm->qm_usr_dqhtable = (xfs_dqhash_t *)kmem_zalloc(hsize *
136
                                                      sizeof(xfs_dqhash_t),
137
                                                      KM_SLEEP);
138
        xqm->qm_grp_dqhtable = (xfs_dqhash_t *)kmem_zalloc(hsize *
139
                                                      sizeof(xfs_dqhash_t),
140
                                                      KM_SLEEP);
141
        ASSERT(xqm->qm_usr_dqhtable != NULL);
142
        ASSERT(xqm->qm_grp_dqhtable != NULL);
143
 
144
        for (i = 0; i < hsize; i++) {
145
                xfs_qm_list_init(&(xqm->qm_usr_dqhtable[i]), "uxdqh", i);
146
                xfs_qm_list_init(&(xqm->qm_grp_dqhtable[i]), "gxdqh", i);
147
        }
148
 
149
        /*
150
         * Freelist of all dquots of all file systems
151
         */
152
        xfs_qm_freelist_init(&(xqm->qm_dqfreelist));
153
 
154
        /*
155
         * dquot zone. we register our own low-memory callback.
156
         */
157
        if (!qm_dqzone) {
158
                xqm->qm_dqzone = kmem_zone_init(sizeof(xfs_dquot_t),
159
                                                "xfs_dquots");
160
                qm_dqzone = xqm->qm_dqzone;
161
        } else
162
                xqm->qm_dqzone = qm_dqzone;
163
 
164
        xfs_qm_shaker = kmem_shake_register(xfs_qm_shake);
165
 
166
        /*
167
         * The t_dqinfo portion of transactions.
168
         */
169
        if (!qm_dqtrxzone) {
170
                xqm->qm_dqtrxzone = kmem_zone_init(sizeof(xfs_dquot_acct_t),
171
                                                   "xfs_dqtrx");
172
                qm_dqtrxzone = xqm->qm_dqtrxzone;
173
        } else
174
                xqm->qm_dqtrxzone = qm_dqtrxzone;
175
 
176
        atomic_set(&xqm->qm_totaldquots, 0);
177
        xqm->qm_dqfree_ratio = XFS_QM_DQFREE_RATIO;
178
        xqm->qm_nrefs = 0;
179
#ifdef DEBUG
180
        mutex_init(&qcheck_lock, MUTEX_DEFAULT, "qchk");
181
#endif
182
        return xqm;
183
}
184
 
185
/*
186
 * Destroy the global quota manager when its reference count goes to zero.
187
 */
188
void
189
xfs_qm_destroy(
190
        struct xfs_qm   *xqm)
191
{
192
        int             hsize, i;
193
 
194
        ASSERT(xqm != NULL);
195
        ASSERT(xqm->qm_nrefs == 0);
196
        kmem_shake_deregister(xfs_qm_shaker);
197
        hsize = xqm->qm_dqhashmask + 1;
198
        for (i = 0; i < hsize; i++) {
199
                xfs_qm_list_destroy(&(xqm->qm_usr_dqhtable[i]));
200
                xfs_qm_list_destroy(&(xqm->qm_grp_dqhtable[i]));
201
        }
202
        kmem_free(xqm->qm_usr_dqhtable, hsize * sizeof(xfs_dqhash_t));
203
        kmem_free(xqm->qm_grp_dqhtable, hsize * sizeof(xfs_dqhash_t));
204
        xqm->qm_usr_dqhtable = NULL;
205
        xqm->qm_grp_dqhtable = NULL;
206
        xqm->qm_dqhashmask = 0;
207
        xfs_qm_freelist_destroy(&(xqm->qm_dqfreelist));
208
#ifdef DEBUG
209
        mutex_destroy(&qcheck_lock);
210
#endif
211
        kmem_free(xqm, sizeof(xfs_qm_t));
212
}
213
 
214
/*
215
 * Called at mount time to let XQM know that another file system is
216
 * starting quotas. This isn't crucial information as the individual mount
217
 * structures are pretty independent, but it helps the XQM keep a
218
 * global view of what's going on.
219
 */
220
/* ARGSUSED */
221
STATIC int
222
xfs_qm_hold_quotafs_ref(
223
        struct xfs_mount *mp)
224
{
225
        /*
226
         * Need to lock the xfs_Gqm structure for things like this. For example,
227
         * the structure could disappear between the entry to this routine and
228
         * a HOLD operation if not locked.
229
         */
230
        XFS_QM_LOCK(xfs_Gqm);
231
 
232
        if (xfs_Gqm == NULL) {
233
                if ((xfs_Gqm = xfs_Gqm_init()) == NULL) {
234
                        return (XFS_ERROR(EINVAL));
235
                }
236
        }
237
        /*
238
         * We can keep a list of all filesystems with quotas mounted for
239
         * debugging and statistical purposes, but ...
240
         * Just take a reference and get out.
241
         */
242
        XFS_QM_HOLD(xfs_Gqm);
243
        XFS_QM_UNLOCK(xfs_Gqm);
244
 
245
        return 0;
246
}
247
 
248
 
249
/*
250
 * Release the reference that a filesystem took at mount time,
251
 * so that we know when we need to destroy the entire quota manager.
252
 */
253
/* ARGSUSED */
254
STATIC void
255
xfs_qm_rele_quotafs_ref(
256
        struct xfs_mount *mp)
257
{
258
        xfs_dquot_t     *dqp, *nextdqp;
259
 
260
        ASSERT(xfs_Gqm);
261
        ASSERT(xfs_Gqm->qm_nrefs > 0);
262
 
263
        /*
264
         * Go thru the freelist and destroy all inactive dquots.
265
         */
266
        xfs_qm_freelist_lock(xfs_Gqm);
267
 
268
        for (dqp = xfs_Gqm->qm_dqfreelist.qh_next;
269
             dqp != (xfs_dquot_t *)&(xfs_Gqm->qm_dqfreelist); ) {
270
                xfs_dqlock(dqp);
271
                nextdqp = dqp->dq_flnext;
272
                if (dqp->dq_flags & XFS_DQ_INACTIVE) {
273
                        ASSERT(dqp->q_mount == NULL);
274
                        ASSERT(! XFS_DQ_IS_DIRTY(dqp));
275
                        ASSERT(dqp->HL_PREVP == NULL);
276
                        ASSERT(dqp->MPL_PREVP == NULL);
277
                        XQM_FREELIST_REMOVE(dqp);
278
                        xfs_dqunlock(dqp);
279
                        xfs_qm_dqdestroy(dqp);
280
                } else {
281
                        xfs_dqunlock(dqp);
282
                }
283
                dqp = nextdqp;
284
        }
285
        xfs_qm_freelist_unlock(xfs_Gqm);
286
 
287
        /*
288
         * Destroy the entire XQM. If somebody mounts with quotaon, this'll
289
         * be restarted.
290
         */
291
        XFS_QM_LOCK(xfs_Gqm);
292
        XFS_QM_RELE(xfs_Gqm);
293
        if (xfs_Gqm->qm_nrefs == 0) {
294
                xfs_qm_destroy(xfs_Gqm);
295
                xfs_Gqm = NULL;
296
        }
297
        XFS_QM_UNLOCK(xfs_Gqm);
298
}
299
 
300
/*
301
 * This is called at mount time from xfs_mountfs to initialize the quotainfo
302
 * structure and start the global quotamanager (xfs_Gqm) if it hasn't done
303
 * so already.  Note that the superblock has not been read in yet.
304
 */
305
void
306
xfs_qm_mount_quotainit(
307
        xfs_mount_t     *mp,
308
        uint            flags)
309
{
310
        /*
311
         * User or group quotas has to be on.
312
         */
313
        ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA));
314
 
315
        /*
316
         * Initialize the flags in the mount structure. From this point
317
         * onwards we look at m_qflags to figure out if quotas's ON/OFF, etc.
318
         * Note that we enforce nothing if accounting is off.
319
         * ie.  XFSMNT_*QUOTA must be ON for XFSMNT_*QUOTAENF.
320
         * It isn't necessary to take the quotaoff lock to do this; this is
321
         * called from mount.
322
         */
323
        if (flags & XFSMNT_UQUOTA) {
324
                mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
325
                if (flags & XFSMNT_UQUOTAENF)
326
                        mp->m_qflags |= XFS_UQUOTA_ENFD;
327
        }
328
        if (flags & XFSMNT_GQUOTA) {
329
                mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
330
                if (flags & XFSMNT_GQUOTAENF)
331
                        mp->m_qflags |= XFS_GQUOTA_ENFD;
332
        }
333
}
334
 
335
/*
336
 * Just destroy the quotainfo structure.
337
 */
338
void
339
xfs_qm_unmount_quotadestroy(
340
        xfs_mount_t     *mp)
341
{
342
        if (mp->m_quotainfo)
343
                xfs_qm_destroy_quotainfo(mp);
344
}
345
 
346
 
347
/*
348
 * This is called from xfs_mountfs to start quotas and initialize all
349
 * necessary data structures like quotainfo.  This is also responsible for
350
 * running a quotacheck as necessary.  We are guaranteed that the superblock
351
 * is consistently read in at this point.
352
 */
353
int
354
xfs_qm_mount_quotas(
355
        xfs_mount_t     *mp)
356
{
357
        unsigned long   s;
358
        int             error = 0;
359
        uint            sbf;
360
 
361
        /*
362
         * If a file system had quotas running earlier, but decided to
363
         * mount without -o quota/uquota/gquota options, revoke the
364
         * quotachecked license, and bail out.
365
         */
366
        if (! XFS_IS_QUOTA_ON(mp) &&
367
            (mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) {
368
                mp->m_qflags = 0;
369
                goto write_changes;
370
        }
371
 
372
        /*
373
         * If quotas on realtime volumes is not supported, we disable
374
         * quotas immediately.
375
         */
376
        if (mp->m_sb.sb_rextents) {
377
                cmn_err(CE_NOTE,
378
                        "Cannot turn on quotas for realtime filesystem %s",
379
                        mp->m_fsname);
380
                mp->m_qflags = 0;
381
                goto write_changes;
382
        }
383
 
384
#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
385
        cmn_err(CE_NOTE, "Attempting to turn on disk quotas.");
386
#endif
387
 
388
        ASSERT(XFS_IS_QUOTA_RUNNING(mp));
389
        /*
390
         * Allocate the quotainfo structure inside the mount struct, and
391
         * create quotainode(s), and change/rev superblock if necessary.
392
         */
393
        if ((error = xfs_qm_init_quotainfo(mp))) {
394
                /*
395
                 * We must turn off quotas.
396
                 */
397
                ASSERT(mp->m_quotainfo == NULL);
398
                mp->m_qflags = 0;
399
                goto write_changes;
400
        }
401
        /*
402
         * If any of the quotas are not consistent, do a quotacheck.
403
         */
404
        if (XFS_QM_NEED_QUOTACHECK(mp)) {
405
#ifdef DEBUG
406
                cmn_err(CE_NOTE, "Doing a quotacheck. Please wait.");
407
#endif
408
                if ((error = xfs_qm_quotacheck(mp))) {
409
                        cmn_err(CE_WARN, "Quotacheck unsuccessful (Error %d): "
410
                                "Disabling quotas.",
411
                                error);
412
                        /*
413
                         * We must turn off quotas.
414
                         */
415
                        ASSERT(mp->m_quotainfo != NULL);
416
                        ASSERT(xfs_Gqm != NULL);
417
                        xfs_qm_destroy_quotainfo(mp);
418
                        mp->m_qflags = 0;
419
                        goto write_changes;
420
                }
421
#ifdef DEBUG
422
                cmn_err(CE_NOTE, "Done quotacheck.");
423
#endif
424
        }
425
 write_changes:
426
        /*
427
         * We actually don't have to acquire the SB_LOCK at all.
428
         * This can only be called from mount, and that's single threaded. XXX
429
         */
430
        s = XFS_SB_LOCK(mp);
431
        sbf = mp->m_sb.sb_qflags;
432
        mp->m_sb.sb_qflags = mp->m_qflags & XFS_MOUNT_QUOTA_ALL;
433
        XFS_SB_UNLOCK(mp, s);
434
 
435
        if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) {
436
                if (xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS)) {
437
                        /*
438
                         * We could only have been turning quotas off.
439
                         * We aren't in very good shape actually because
440
                         * the incore structures are convinced that quotas are
441
                         * off, but the on disk superblock doesn't know that !
442
                         */
443
                        ASSERT(!(XFS_IS_QUOTA_RUNNING(mp)));
444
                        xfs_fs_cmn_err(CE_ALERT, mp,
445
                                "XFS mount_quotas: Superblock update failed!");
446
                }
447
        }
448
 
449
        if (error) {
450
                xfs_fs_cmn_err(CE_WARN, mp,
451
                        "Failed to initialize disk quotas.");
452
        }
453
        return XFS_ERROR(error);
454
}
455
 
456
/*
457
 * Called from the vfsops layer.
458
 */
459
int
460
xfs_qm_unmount_quotas(
461
        xfs_mount_t     *mp)
462
{
463
        xfs_inode_t     *uqp, *gqp;
464
        int             error = 0;
465
 
466
        /*
467
         * Release the dquots that root inode, et al might be holding,
468
         * before we flush quotas and blow away the quotainfo structure.
469
         */
470
        ASSERT(mp->m_rootip);
471
        xfs_qm_dqdetach(mp->m_rootip);
472
        if (mp->m_rbmip)
473
                xfs_qm_dqdetach(mp->m_rbmip);
474
        if (mp->m_rsumip)
475
                xfs_qm_dqdetach(mp->m_rsumip);
476
 
477
        /*
478
         * Flush out the quota inodes.
479
         */
480
        uqp = gqp = NULL;
481
        if (mp->m_quotainfo) {
482
                if ((uqp = mp->m_quotainfo->qi_uquotaip) != NULL) {
483
                        xfs_ilock(uqp, XFS_ILOCK_EXCL);
484
                        xfs_iflock(uqp);
485
                        error = xfs_iflush(uqp, XFS_IFLUSH_SYNC);
486
                        xfs_iunlock(uqp, XFS_ILOCK_EXCL);
487
                        if (unlikely(error == EFSCORRUPTED)) {
488
                                XFS_ERROR_REPORT("xfs_qm_unmount_quotas(1)",
489
                                                 XFS_ERRLEVEL_LOW, mp);
490
                                goto out;
491
                        }
492
                }
493
                if ((gqp = mp->m_quotainfo->qi_gquotaip) != NULL) {
494
                        xfs_ilock(gqp, XFS_ILOCK_EXCL);
495
                        xfs_iflock(gqp);
496
                        error = xfs_iflush(gqp, XFS_IFLUSH_SYNC);
497
                        xfs_iunlock(gqp, XFS_ILOCK_EXCL);
498
                        if (unlikely(error == EFSCORRUPTED)) {
499
                                XFS_ERROR_REPORT("xfs_qm_unmount_quotas(2)",
500
                                                 XFS_ERRLEVEL_LOW, mp);
501
                                goto out;
502
                        }
503
                }
504
        }
505
        if (uqp) {
506
                 XFS_PURGE_INODE(uqp);
507
                 mp->m_quotainfo->qi_uquotaip = NULL;
508
        }
509
        if (gqp) {
510
                XFS_PURGE_INODE(gqp);
511
                mp->m_quotainfo->qi_gquotaip = NULL;
512
        }
513
out:
514
        return XFS_ERROR(error);
515
}
516
 
517
/*
518
 * Flush all dquots of the given file system to disk. The dquots are
519
 * _not_ purged from memory here, just their data written to disk.
520
 */
521
int
522
xfs_qm_dqflush_all(
523
        xfs_mount_t     *mp,
524
        int             flags)
525
{
526
        int             recl;
527
        xfs_dquot_t     *dqp;
528
        int             niters;
529
        int             error;
530
 
531
        if (mp->m_quotainfo == NULL)
532
                return (0);
533
        niters = 0;
534
again:
535
        xfs_qm_mplist_lock(mp);
536
        FOREACH_DQUOT_IN_MP(dqp, mp) {
537
                xfs_dqlock(dqp);
538
                if (! XFS_DQ_IS_DIRTY(dqp)) {
539
                        xfs_dqunlock(dqp);
540
                        continue;
541
                }
542
                xfs_dqtrace_entry(dqp, "FLUSHALL: DQDIRTY");
543
                /* XXX a sentinel would be better */
544
                recl = XFS_QI_MPLRECLAIMS(mp);
545
                if (! xfs_qm_dqflock_nowait(dqp)) {
546
                        /*
547
                         * If we can't grab the flush lock then check
548
                         * to see if the dquot has been flushed delayed
549
                         * write.  If so, grab its buffer and send it
550
                         * out immediately.  We'll be able to acquire
551
                         * the flush lock when the I/O completes.
552
                         */
553
                        xfs_qm_dqflock_pushbuf_wait(dqp);
554
                }
555
                /*
556
                 * Let go of the mplist lock. We don't want to hold it
557
                 * across a disk write.
558
                 */
559
                xfs_qm_mplist_unlock(mp);
560
                error = xfs_qm_dqflush(dqp, flags);
561
                xfs_dqunlock(dqp);
562
                if (error)
563
                        return (error);
564
 
565
                xfs_qm_mplist_lock(mp);
566
                if (recl != XFS_QI_MPLRECLAIMS(mp)) {
567
                        xfs_qm_mplist_unlock(mp);
568
                        /* XXX restart limit */
569
                        goto again;
570
                }
571
        }
572
 
573
        xfs_qm_mplist_unlock(mp);
574
        /* return ! busy */
575
        return (0);
576
}
577
/*
578
 * Release the group dquot pointers the user dquots may be
579
 * carrying around as a hint. mplist is locked on entry and exit.
580
 */
581
STATIC void
582
xfs_qm_detach_gdquots(
583
        xfs_mount_t     *mp)
584
{
585
        xfs_dquot_t     *dqp, *gdqp;
586
        int             nrecl;
587
 
588
 again:
589
        ASSERT(XFS_QM_IS_MPLIST_LOCKED(mp));
590
        dqp = XFS_QI_MPLNEXT(mp);
591
        while (dqp) {
592
                xfs_dqlock(dqp);
593
                if ((gdqp = dqp->q_gdquot)) {
594
                        xfs_dqlock(gdqp);
595
                        dqp->q_gdquot = NULL;
596
                }
597
                xfs_dqunlock(dqp);
598
 
599
                if (gdqp) {
600
                        /*
601
                         * Can't hold the mplist lock across a dqput.
602
                         * XXXmust convert to marker based iterations here.
603
                         */
604
                        nrecl = XFS_QI_MPLRECLAIMS(mp);
605
                        xfs_qm_mplist_unlock(mp);
606
                        xfs_qm_dqput(gdqp);
607
 
608
                        xfs_qm_mplist_lock(mp);
609
                        if (nrecl != XFS_QI_MPLRECLAIMS(mp))
610
                                goto again;
611
                }
612
                dqp = dqp->MPL_NEXT;
613
        }
614
}
615
 
616
/*
617
 * Go through all the incore dquots of this file system and take them
618
 * off the mplist and hashlist, if the dquot type matches the dqtype
619
 * parameter. This is used when turning off quota accounting for
620
 * users and/or groups, as well as when the filesystem is unmounting.
621
 */
622
STATIC int
623
xfs_qm_dqpurge_int(
624
        xfs_mount_t     *mp,
625
        uint            flags) /* QUOTAOFF/UMOUNTING/UQUOTA/GQUOTA */
626
{
627
        xfs_dquot_t     *dqp;
628
        uint            dqtype;
629
        int             nrecl;
630
        xfs_dquot_t     *nextdqp;
631
        int             nmisses;
632
 
633
        if (mp->m_quotainfo == NULL)
634
                return (0);
635
 
636
        dqtype = (flags & XFS_QMOPT_UQUOTA) ? XFS_DQ_USER : 0;
637
        dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0;
638
 
639
        xfs_qm_mplist_lock(mp);
640
 
641
        /*
642
         * In the first pass through all incore dquots of this filesystem,
643
         * we release the group dquot pointers the user dquots may be
644
         * carrying around as a hint. We need to do this irrespective of
645
         * what's being turned off.
646
         */
647
        xfs_qm_detach_gdquots(mp);
648
 
649
      again:
650
        nmisses = 0;
651
        ASSERT(XFS_QM_IS_MPLIST_LOCKED(mp));
652
        /*
653
         * Try to get rid of all of the unwanted dquots. The idea is to
654
         * get them off mplist and hashlist, but leave them on freelist.
655
         */
656
        dqp = XFS_QI_MPLNEXT(mp);
657
        while (dqp) {
658
                /*
659
                 * It's OK to look at the type without taking dqlock here.
660
                 * We're holding the mplist lock here, and that's needed for
661
                 * a dqreclaim.
662
                 */
663
                if ((dqp->dq_flags & dqtype) == 0) {
664
                        dqp = dqp->MPL_NEXT;
665
                        continue;
666
                }
667
 
668
                if (! xfs_qm_dqhashlock_nowait(dqp)) {
669
                        nrecl = XFS_QI_MPLRECLAIMS(mp);
670
                        xfs_qm_mplist_unlock(mp);
671
                        XFS_DQ_HASH_LOCK(dqp->q_hash);
672
                        xfs_qm_mplist_lock(mp);
673
 
674
                        /*
675
                         * XXXTheoretically, we can get into a very long
676
                         * ping pong game here.
677
                         * No one can be adding dquots to the mplist at
678
                         * this point, but somebody might be taking things off.
679
                         */
680
                        if (nrecl != XFS_QI_MPLRECLAIMS(mp)) {
681
                                XFS_DQ_HASH_UNLOCK(dqp->q_hash);
682
                                goto again;
683
                        }
684
                }
685
 
686
                /*
687
                 * Take the dquot off the mplist and hashlist. It may remain on
688
                 * freelist in INACTIVE state.
689
                 */
690
                nextdqp = dqp->MPL_NEXT;
691
                nmisses += xfs_qm_dqpurge(dqp, flags);
692
                dqp = nextdqp;
693
        }
694
        xfs_qm_mplist_unlock(mp);
695
        return nmisses;
696
}
697
 
698
int
699
xfs_qm_dqpurge_all(
700
        xfs_mount_t     *mp,
701
        uint            flags)
702
{
703
        int             ndquots;
704
 
705
        /*
706
         * Purge the dquot cache.
707
         * None of the dquots should really be busy at this point.
708
         */
709
        if (mp->m_quotainfo) {
710
                while ((ndquots = xfs_qm_dqpurge_int(mp, flags))) {
711
                        delay(ndquots * 10);
712
                }
713
        }
714
        return 0;
715
}
716
 
717
STATIC int
718
xfs_qm_dqattach_one(
719
        xfs_inode_t     *ip,
720
        xfs_dqid_t      id,
721
        uint            type,
722
        uint            doalloc,
723
        uint            dolock,
724
        xfs_dquot_t     *udqhint, /* hint */
725
        xfs_dquot_t     **IO_idqpp)
726
{
727
        xfs_dquot_t     *dqp;
728
        int             error;
729
 
730
        ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
731
        error = 0;
732
        /*
733
         * See if we already have it in the inode itself. IO_idqpp is
734
         * &i_udquot or &i_gdquot. This made the code look weird, but
735
         * made the logic a lot simpler.
736
         */
737
        if ((dqp = *IO_idqpp)) {
738
                if (dolock)
739
                        xfs_dqlock(dqp);
740
                xfs_dqtrace_entry(dqp, "DQATTACH: found in ip");
741
                goto done;
742
        }
743
 
744
        /*
745
         * udqhint is the i_udquot field in inode, and is non-NULL only
746
         * when the type arg is XFS_DQ_GROUP. Its purpose is to save a
747
         * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside
748
         * the user dquot.
749
         */
750
        ASSERT(!udqhint || type == XFS_DQ_GROUP);
751
        if (udqhint && !dolock)
752
                xfs_dqlock(udqhint);
753
 
754
        /*
755
         * No need to take dqlock to look at the id.
756
         * The ID can't change until it gets reclaimed, and it won't
757
         * be reclaimed as long as we have a ref from inode and we hold
758
         * the ilock.
759
         */
760
        if (udqhint &&
761
            (dqp = udqhint->q_gdquot) &&
762
            (INT_GET(dqp->q_core.d_id, ARCH_CONVERT) == id)) {
763
                ASSERT(XFS_DQ_IS_LOCKED(udqhint));
764
                xfs_dqlock(dqp);
765
                XFS_DQHOLD(dqp);
766
                ASSERT(*IO_idqpp == NULL);
767
                *IO_idqpp = dqp;
768
                if (!dolock) {
769
                        xfs_dqunlock(dqp);
770
                        xfs_dqunlock(udqhint);
771
                }
772
                goto done;
773
        }
774
        /*
775
         * We can't hold a dquot lock when we call the dqget code.
776
         * We'll deadlock in no time, because of (not conforming to)
777
         * lock ordering - the inodelock comes before any dquot lock,
778
         * and we may drop and reacquire the ilock in xfs_qm_dqget().
779
         */
780
        if (udqhint)
781
                xfs_dqunlock(udqhint);
782
        /*
783
         * Find the dquot from somewhere. This bumps the
784
         * reference count of dquot and returns it locked.
785
         * This can return ENOENT if dquot didn't exist on
786
         * disk and we didn't ask it to allocate;
787
         * ESRCH if quotas got turned off suddenly.
788
         */
789
        if ((error = xfs_qm_dqget(ip->i_mount, ip, id, type,
790
                                 doalloc|XFS_QMOPT_DOWARN, &dqp))) {
791
                if (udqhint && dolock)
792
                        xfs_dqlock(udqhint);
793
                goto done;
794
        }
795
 
796
        xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget");
797
        /*
798
         * dqget may have dropped and re-acquired the ilock, but it guarantees
799
         * that the dquot returned is the one that should go in the inode.
800
         */
801
        *IO_idqpp = dqp;
802
        ASSERT(dqp);
803
        ASSERT(XFS_DQ_IS_LOCKED(dqp));
804
        if (! dolock) {
805
                xfs_dqunlock(dqp);
806
                goto done;
807
        }
808
        if (! udqhint)
809
                goto done;
810
 
811
        ASSERT(udqhint);
812
        ASSERT(dolock);
813
        ASSERT(XFS_DQ_IS_LOCKED(dqp));
814
        if (! xfs_qm_dqlock_nowait(udqhint)) {
815
                xfs_dqunlock(dqp);
816
                xfs_dqlock(udqhint);
817
                xfs_dqlock(dqp);
818
        }
819
      done:
820
#ifdef QUOTADEBUG
821
        if (udqhint) {
822
                if (dolock)
823
                        ASSERT(XFS_DQ_IS_LOCKED(udqhint));
824
        }
825
        if (! error) {
826
                if (dolock)
827
                        ASSERT(XFS_DQ_IS_LOCKED(dqp));
828
        }
829
#endif
830
        return (error);
831
}
832
 
833
 
834
/*
835
 * Given a udquot and gdquot, attach a ptr to the group dquot in the
836
 * udquot as a hint for future lookups. The idea sounds simple, but the
837
 * execution isn't, because the udquot might have a group dquot attached
838
 * already and getting rid of that gets us into lock ordering contraints.
839
 * The process is complicated more by the fact that the dquots may or may not
840
 * be locked on entry.
841
 */
842
STATIC void
843
xfs_qm_dqattach_grouphint(
844
        xfs_dquot_t     *udq,
845
        xfs_dquot_t     *gdq,
846
        uint            locked)
847
{
848
        xfs_dquot_t     *tmp;
849
 
850
#ifdef QUOTADEBUG
851
        if (locked) {
852
                ASSERT(XFS_DQ_IS_LOCKED(udq));
853
                ASSERT(XFS_DQ_IS_LOCKED(gdq));
854
        }
855
#endif
856
        if (! locked)
857
                xfs_dqlock(udq);
858
 
859
        if ((tmp = udq->q_gdquot)) {
860
                if (tmp == gdq) {
861
                        if (! locked)
862
                                xfs_dqunlock(udq);
863
                        return;
864
                }
865
 
866
                udq->q_gdquot = NULL;
867
                /*
868
                 * We can't keep any dqlocks when calling dqrele,
869
                 * because the freelist lock comes before dqlocks.
870
                 */
871
                xfs_dqunlock(udq);
872
                if (locked)
873
                        xfs_dqunlock(gdq);
874
                /*
875
                 * we took a hard reference once upon a time in dqget,
876
                 * so give it back when the udquot no longer points at it
877
                 * dqput() does the unlocking of the dquot.
878
                 */
879
                xfs_qm_dqrele(tmp);
880
 
881
                xfs_dqlock(udq);
882
                xfs_dqlock(gdq);
883
 
884
        } else {
885
                ASSERT(XFS_DQ_IS_LOCKED(udq));
886
                if (! locked) {
887
                        xfs_dqlock(gdq);
888
                }
889
        }
890
 
891
        ASSERT(XFS_DQ_IS_LOCKED(udq));
892
        ASSERT(XFS_DQ_IS_LOCKED(gdq));
893
        /*
894
         * Somebody could have attached a gdquot here,
895
         * when we dropped the uqlock. If so, just do nothing.
896
         */
897
        if (udq->q_gdquot == NULL) {
898
                XFS_DQHOLD(gdq);
899
                udq->q_gdquot = gdq;
900
        }
901
        if (! locked) {
902
                xfs_dqunlock(gdq);
903
                xfs_dqunlock(udq);
904
        }
905
}
906
 
907
 
908
/*
909
 * Given a locked inode, attach dquot(s) to it, taking UQUOTAON / GQUOTAON
910
 * in to account.
911
 * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed.
912
 * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty
913
 * much made this code a complete mess, but it has been pretty useful.
914
 * If XFS_QMOPT_ILOCKED, then inode sent is already locked EXCL.
915
 * Inode may get unlocked and relocked in here, and the caller must deal with
916
 * the consequences.
917
 */
918
int
919
xfs_qm_dqattach(
920
        xfs_inode_t     *ip,
921
        uint            flags)
922
{
923
        xfs_mount_t     *mp = ip->i_mount;
924
        uint            nquotas = 0;
925
        int             error = 0;
926
 
927
        if ((! XFS_IS_QUOTA_ON(mp)) ||
928
            (! XFS_NOT_DQATTACHED(mp, ip)) ||
929
            (ip->i_ino == mp->m_sb.sb_uquotino) ||
930
            (ip->i_ino == mp->m_sb.sb_gquotino))
931
                return (0);
932
 
933
        ASSERT((flags & XFS_QMOPT_ILOCKED) == 0 ||
934
               XFS_ISLOCKED_INODE_EXCL(ip));
935
 
936
        if (! (flags & XFS_QMOPT_ILOCKED))
937
                xfs_ilock(ip, XFS_ILOCK_EXCL);
938
 
939
        if (XFS_IS_UQUOTA_ON(mp)) {
940
                error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
941
                                                flags & XFS_QMOPT_DQALLOC,
942
                                                flags & XFS_QMOPT_DQLOCK,
943
                                                NULL, &ip->i_udquot);
944
                if (error)
945
                        goto done;
946
                nquotas++;
947
        }
948
        ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
949
        if (XFS_IS_GQUOTA_ON(mp)) {
950
                error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
951
                                                flags & XFS_QMOPT_DQALLOC,
952
                                                flags & XFS_QMOPT_DQLOCK,
953
                                                ip->i_udquot, &ip->i_gdquot);
954
                /*
955
                 * Don't worry about the udquot that we may have
956
                 * attached above. It'll get detached, if not already.
957
                 */
958
                if (error)
959
                        goto done;
960
                nquotas++;
961
        }
962
 
963
        /*
964
         * Attach this group quota to the user quota as a hint.
965
         * This WON'T, in general, result in a thrash.
966
         */
967
        if (nquotas == 2) {
968
                ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
969
                ASSERT(ip->i_udquot);
970
                ASSERT(ip->i_gdquot);
971
 
972
                /*
973
                 * We may or may not have the i_udquot locked at this point,
974
                 * but this check is OK since we don't depend on the i_gdquot to
975
                 * be accurate 100% all the time. It is just a hint, and this
976
                 * will succeed in general.
977
                 */
978
                if (ip->i_udquot->q_gdquot == ip->i_gdquot)
979
                        goto done;
980
                /*
981
                 * Attach i_gdquot to the gdquot hint inside the i_udquot.
982
                 */
983
                xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot,
984
                                         flags & XFS_QMOPT_DQLOCK);
985
        }
986
 
987
      done:
988
 
989
#ifdef QUOTADEBUG
990
        if (! error) {
991
                if (ip->i_udquot) {
992
                        if (flags & XFS_QMOPT_DQLOCK)
993
                                ASSERT(XFS_DQ_IS_LOCKED(ip->i_udquot));
994
                }
995
                if (ip->i_gdquot) {
996
                        if (flags & XFS_QMOPT_DQLOCK)
997
                                ASSERT(XFS_DQ_IS_LOCKED(ip->i_gdquot));
998
                }
999
                if (XFS_IS_UQUOTA_ON(mp))
1000
                        ASSERT(ip->i_udquot);
1001
                if (XFS_IS_GQUOTA_ON(mp))
1002
                        ASSERT(ip->i_gdquot);
1003
        }
1004
#endif
1005
 
1006
        if (! (flags & XFS_QMOPT_ILOCKED))
1007
                xfs_iunlock(ip, XFS_ILOCK_EXCL);
1008
 
1009
#ifdef QUOTADEBUG
1010
        else
1011
                ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
1012
#endif
1013
        return (error);
1014
}
1015
 
1016
/*
1017
 * Release dquots (and their references) if any.
1018
 * The inode should be locked EXCL except when this's called by
1019
 * xfs_ireclaim.
1020
 */
1021
void
1022
xfs_qm_dqdetach(
1023
        xfs_inode_t     *ip)
1024
{
1025
        if (!(ip->i_udquot || ip->i_gdquot))
1026
                return;
1027
 
1028
        ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino);
1029
        ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino);
1030
        if (ip->i_udquot)
1031
                xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip);
1032
        if (ip->i_udquot) {
1033
                xfs_qm_dqrele(ip->i_udquot);
1034
                ip->i_udquot = NULL;
1035
        }
1036
        if (ip->i_gdquot) {
1037
                xfs_qm_dqrele(ip->i_gdquot);
1038
                ip->i_gdquot = NULL;
1039
        }
1040
}
1041
 
1042
/*
1043
 * This is called by VFS_SYNC and flags arg determines the caller,
1044
 * and its motives, as done in xfs_sync.
1045
 *
1046
 * vfs_sync: SYNC_FSDATA|SYNC_ATTR|SYNC_BDFLUSH 0x31
1047
 * syscall sync: SYNC_FSDATA|SYNC_ATTR|SYNC_DELWRI 0x25
1048
 * umountroot : SYNC_WAIT | SYNC_CLOSE | SYNC_ATTR | SYNC_FSDATA
1049
 */
1050
 
1051
int
1052
xfs_qm_sync(
1053
        xfs_mount_t     *mp,
1054
        short           flags)
1055
{
1056
        int             recl, restarts;
1057
        xfs_dquot_t     *dqp;
1058
        uint            flush_flags;
1059
        boolean_t       nowait;
1060
        int             error;
1061
 
1062
        restarts = 0;
1063
        /*
1064
         * We won't block unless we are asked to.
1065
         */
1066
        nowait = (boolean_t)(flags & SYNC_BDFLUSH || (flags & SYNC_WAIT) == 0);
1067
 
1068
  again:
1069
        xfs_qm_mplist_lock(mp);
1070
        /*
1071
         * dqpurge_all() also takes the mplist lock and iterate thru all dquots
1072
         * in quotaoff. However, if the QUOTA_ACTIVE bits are not cleared
1073
         * when we have the mplist lock, we know that dquots will be consistent
1074
         * as long as we have it locked.
1075
         */
1076
        if (! XFS_IS_QUOTA_ON(mp)) {
1077
                xfs_qm_mplist_unlock(mp);
1078
                return (0);
1079
        }
1080
        FOREACH_DQUOT_IN_MP(dqp, mp) {
1081
                /*
1082
                 * If this is vfs_sync calling, then skip the dquots that
1083
                 * don't 'seem' to be dirty. ie. don't acquire dqlock.
1084
                 * This is very similar to what xfs_sync does with inodes.
1085
                 */
1086
                if (flags & SYNC_BDFLUSH) {
1087
                        if (! XFS_DQ_IS_DIRTY(dqp))
1088
                                continue;
1089
                }
1090
 
1091
                if (nowait) {
1092
                        /*
1093
                         * Try to acquire the dquot lock. We are NOT out of
1094
                         * lock order, but we just don't want to wait for this
1095
                         * lock, unless somebody wanted us to.
1096
                         */
1097
                        if (! xfs_qm_dqlock_nowait(dqp))
1098
                                continue;
1099
                } else {
1100
                        xfs_dqlock(dqp);
1101
                }
1102
 
1103
                /*
1104
                 * Now, find out for sure if this dquot is dirty or not.
1105
                 */
1106
                if (! XFS_DQ_IS_DIRTY(dqp)) {
1107
                        xfs_dqunlock(dqp);
1108
                        continue;
1109
                }
1110
 
1111
                /* XXX a sentinel would be better */
1112
                recl = XFS_QI_MPLRECLAIMS(mp);
1113
                if (! xfs_qm_dqflock_nowait(dqp)) {
1114
                        if (nowait) {
1115
                                xfs_dqunlock(dqp);
1116
                                continue;
1117
                        }
1118
                        /*
1119
                         * If we can't grab the flush lock then if the caller
1120
                         * really wanted us to give this our best shot,
1121
                         * see if we can give a push to the buffer before we wait
1122
                         * on the flush lock. At this point, we know that
1123
                         * eventhough the dquot is being flushed,
1124
                         * it has (new) dirty data.
1125
                         */
1126
                        xfs_qm_dqflock_pushbuf_wait(dqp);
1127
                }
1128
                /*
1129
                 * Let go of the mplist lock. We don't want to hold it
1130
                 * across a disk write
1131
                 */
1132
                flush_flags = (nowait) ? XFS_QMOPT_DELWRI : XFS_QMOPT_SYNC;
1133
                xfs_qm_mplist_unlock(mp);
1134
                xfs_dqtrace_entry(dqp, "XQM_SYNC: DQFLUSH");
1135
                error = xfs_qm_dqflush(dqp, flush_flags);
1136
                xfs_dqunlock(dqp);
1137
                if (error && XFS_FORCED_SHUTDOWN(mp))
1138
                        return(0);       /* Need to prevent umount failure */
1139
                else if (error)
1140
                        return (error);
1141
 
1142
                xfs_qm_mplist_lock(mp);
1143
                if (recl != XFS_QI_MPLRECLAIMS(mp)) {
1144
                        if (++restarts >= XFS_QM_SYNC_MAX_RESTARTS)
1145
                                break;
1146
 
1147
                        xfs_qm_mplist_unlock(mp);
1148
                        goto again;
1149
                }
1150
        }
1151
 
1152
        xfs_qm_mplist_unlock(mp);
1153
        return (0);
1154
}
1155
 
1156
 
1157
/*
1158
 * This initializes all the quota information that's kept in the
1159
 * mount structure
1160
 */
1161
int
1162
xfs_qm_init_quotainfo(
1163
        xfs_mount_t     *mp)
1164
{
1165
        xfs_quotainfo_t *qinf;
1166
        int             error;
1167
        xfs_dquot_t     *dqp;
1168
 
1169
        ASSERT(XFS_IS_QUOTA_RUNNING(mp));
1170
 
1171
        /*
1172
         * Tell XQM that we exist as soon as possible.
1173
         */
1174
        if ((error = xfs_qm_hold_quotafs_ref(mp))) {
1175
                return (error);
1176
        }
1177
 
1178
        qinf = mp->m_quotainfo = kmem_zalloc(sizeof(xfs_quotainfo_t), KM_SLEEP);
1179
 
1180
        /*
1181
         * See if quotainodes are setup, and if not, allocate them,
1182
         * and change the superblock accordingly.
1183
         */
1184
        if ((error = xfs_qm_init_quotainos(mp))) {
1185
                kmem_free(qinf, sizeof(xfs_quotainfo_t));
1186
                mp->m_quotainfo = NULL;
1187
                return (error);
1188
        }
1189
 
1190
        spinlock_init(&qinf->qi_pinlock, "xfs_qinf_pin");
1191
        xfs_qm_list_init(&qinf->qi_dqlist, "mpdqlist", 0);
1192
        qinf->qi_dqreclaims = 0;
1193
 
1194
        /* mutex used to serialize quotaoffs */
1195
        mutex_init(&qinf->qi_quotaofflock, MUTEX_DEFAULT, "qoff");
1196
 
1197
        /* Precalc some constants */
1198
        qinf->qi_dqchunklen = XFS_FSB_TO_BB(mp, XFS_DQUOT_CLUSTER_SIZE_FSB);
1199
        ASSERT(qinf->qi_dqchunklen);
1200
        qinf->qi_dqperchunk = BBTOB(qinf->qi_dqchunklen);
1201
        do_div(qinf->qi_dqperchunk, sizeof(xfs_dqblk_t));
1202
 
1203
        mp->m_qflags |= (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_CHKD);
1204
 
1205
        /*
1206
         * We try to get the limits from the superuser's limits fields.
1207
         * This is quite hacky, but it is standard quota practice.
1208
         * We look at the USR dquot with id == 0 first, but if user quotas
1209
         * are not enabled we goto the GRP dquot with id == 0.
1210
         * We don't really care to keep separate default limits for user
1211
         * and group quotas, at least not at this point.
1212
         */
1213
        error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)0,
1214
                             (XFS_IS_UQUOTA_RUNNING(mp)) ?
1215
                             XFS_DQ_USER : XFS_DQ_GROUP,
1216
                             XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN,
1217
                             &dqp);
1218
        if (! error) {
1219
                /*
1220
                 * The warnings and timers set the grace period given to
1221
                 * a user or group before he or she can not perform any
1222
                 * more writing. If it is zero, a default is used.
1223
                 */
1224
                qinf->qi_btimelimit = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT) ?
1225
                        INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT) : XFS_QM_BTIMELIMIT;
1226
                qinf->qi_itimelimit = INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT) ?
1227
                        INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT) : XFS_QM_ITIMELIMIT;
1228
                qinf->qi_rtbtimelimit = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT) ?
1229
                        INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT) : XFS_QM_RTBTIMELIMIT;
1230
                qinf->qi_bwarnlimit = INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) ?
1231
                        INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) : XFS_QM_BWARNLIMIT;
1232
                qinf->qi_iwarnlimit = INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) ?
1233
                        INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) : XFS_QM_IWARNLIMIT;
1234
 
1235
                /*
1236
                 * We sent the XFS_QMOPT_DQSUSER flag to dqget because
1237
                 * we don't want this dquot cached. We haven't done a
1238
                 * quotacheck yet, and quotacheck doesn't like incore dquots.
1239
                 */
1240
                xfs_qm_dqdestroy(dqp);
1241
        } else {
1242
                qinf->qi_btimelimit = XFS_QM_BTIMELIMIT;
1243
                qinf->qi_itimelimit = XFS_QM_ITIMELIMIT;
1244
                qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT;
1245
                qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT;
1246
                qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT;
1247
        }
1248
 
1249
        return (0);
1250
}
1251
 
1252
 
1253
/*
1254
 * Gets called when unmounting a filesystem or when all quotas get
1255
 * turned off.
1256
 * This purges the quota inodes, destroys locks and frees itself.
1257
 */
1258
void
1259
xfs_qm_destroy_quotainfo(
1260
        xfs_mount_t     *mp)
1261
{
1262
        xfs_quotainfo_t *qi;
1263
 
1264
        qi = mp->m_quotainfo;
1265
        ASSERT(qi != NULL);
1266
        ASSERT(xfs_Gqm != NULL);
1267
 
1268
        /*
1269
         * Release the reference that XQM kept, so that we know
1270
         * when the XQM structure should be freed. We cannot assume
1271
         * that xfs_Gqm is non-null after this point.
1272
         */
1273
        xfs_qm_rele_quotafs_ref(mp);
1274
 
1275
        spinlock_destroy(&qi->qi_pinlock);
1276
        xfs_qm_list_destroy(&qi->qi_dqlist);
1277
 
1278
        if (qi->qi_uquotaip) {
1279
                XFS_PURGE_INODE(qi->qi_uquotaip);
1280
                qi->qi_uquotaip = NULL; /* paranoia */
1281
        }
1282
        if (qi->qi_gquotaip) {
1283
                XFS_PURGE_INODE(qi->qi_gquotaip);
1284
                qi->qi_gquotaip = NULL;
1285
        }
1286
        mutex_destroy(&qi->qi_quotaofflock);
1287
        kmem_free(qi, sizeof(xfs_quotainfo_t));
1288
        mp->m_quotainfo = NULL;
1289
}
1290
 
1291
 
1292
 
1293
/* ------------------- PRIVATE STATIC FUNCTIONS ----------------------- */
1294
 
1295
/* ARGSUSED */
1296
STATIC void
1297
xfs_qm_list_init(
1298
        xfs_dqlist_t    *list,
1299
        char            *str,
1300
        int             n)
1301
{
1302
        mutex_init(&list->qh_lock, MUTEX_DEFAULT, str);
1303
        list->qh_next = NULL;
1304
        list->qh_version = 0;
1305
        list->qh_nelems = 0;
1306
}
1307
 
1308
STATIC void
1309
xfs_qm_list_destroy(
1310
        xfs_dqlist_t    *list)
1311
{
1312
        mutex_destroy(&(list->qh_lock));
1313
}
1314
 
1315
 
1316
/*
1317
 * Stripped down version of dqattach. This doesn't attach, or even look at the
1318
 * dquots attached to the inode. The rationale is that there won't be any
1319
 * attached at the time this is called from quotacheck.
1320
 */
1321
STATIC int
1322
xfs_qm_dqget_noattach(
1323
        xfs_inode_t     *ip,
1324
        xfs_dquot_t     **O_udqpp,
1325
        xfs_dquot_t     **O_gdqpp)
1326
{
1327
        int             error;
1328
        xfs_mount_t     *mp;
1329
        xfs_dquot_t     *udqp, *gdqp;
1330
 
1331
        ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
1332
        mp = ip->i_mount;
1333
        udqp = NULL;
1334
        gdqp = NULL;
1335
 
1336
        if (XFS_IS_UQUOTA_ON(mp)) {
1337
                ASSERT(ip->i_udquot == NULL);
1338
                /*
1339
                 * We want the dquot allocated if it doesn't exist.
1340
                 */
1341
                if ((error = xfs_qm_dqget(mp, ip, ip->i_d.di_uid, XFS_DQ_USER,
1342
                                         XFS_QMOPT_DQALLOC | XFS_QMOPT_DOWARN,
1343
                                         &udqp))) {
1344
                        /*
1345
                         * Shouldn't be able to turn off quotas here.
1346
                         */
1347
                        ASSERT(error != ESRCH);
1348
                        ASSERT(error != ENOENT);
1349
                        return (error);
1350
                }
1351
                ASSERT(udqp);
1352
        }
1353
 
1354
        if (XFS_IS_GQUOTA_ON(mp)) {
1355
                ASSERT(ip->i_gdquot == NULL);
1356
                if (udqp)
1357
                        xfs_dqunlock(udqp);
1358
                if ((error = xfs_qm_dqget(mp, ip, ip->i_d.di_gid, XFS_DQ_GROUP,
1359
                                         XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
1360
                                         &gdqp))) {
1361
                        if (udqp)
1362
                                xfs_qm_dqrele(udqp);
1363
                        ASSERT(error != ESRCH);
1364
                        ASSERT(error != ENOENT);
1365
                        return (error);
1366
                }
1367
                ASSERT(gdqp);
1368
 
1369
                /* Reacquire the locks in the right order */
1370
                if (udqp) {
1371
                        if (! xfs_qm_dqlock_nowait(udqp)) {
1372
                                xfs_dqunlock(gdqp);
1373
                                xfs_dqlock(udqp);
1374
                                xfs_dqlock(gdqp);
1375
                        }
1376
                }
1377
        }
1378
 
1379
        *O_udqpp = udqp;
1380
        *O_gdqpp = gdqp;
1381
 
1382
#ifdef QUOTADEBUG
1383
        if (udqp) ASSERT(XFS_DQ_IS_LOCKED(udqp));
1384
        if (gdqp) ASSERT(XFS_DQ_IS_LOCKED(gdqp));
1385
#endif
1386
        return (0);
1387
}
1388
 
1389
/*
1390
 * Create an inode and return with a reference already taken, but unlocked
1391
 * This is how we create quota inodes
1392
 */
1393
STATIC int
1394
xfs_qm_qino_alloc(
1395
        xfs_mount_t     *mp,
1396
        xfs_inode_t     **ip,
1397
        __int64_t       sbfields,
1398
        uint            flags)
1399
{
1400
        xfs_trans_t     *tp;
1401
        int             error;
1402
        unsigned long s;
1403
        cred_t          zerocr;
1404
        int             committed;
1405
 
1406
        tp = xfs_trans_alloc(mp,XFS_TRANS_QM_QINOCREATE);
1407
        if ((error = xfs_trans_reserve(tp,
1408
                                      XFS_QM_QINOCREATE_SPACE_RES(mp),
1409
                                      XFS_CREATE_LOG_RES(mp), 0,
1410
                                      XFS_TRANS_PERM_LOG_RES,
1411
                                      XFS_CREATE_LOG_COUNT))) {
1412
                xfs_trans_cancel(tp, 0);
1413
                return (error);
1414
        }
1415
        memset(&zerocr, 0, sizeof(zerocr));
1416
 
1417
        if ((error = xfs_dir_ialloc(&tp, mp->m_rootip, S_IFREG, 1, 0,
1418
                                   &zerocr, 0, 1, ip, &committed))) {
1419
                xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES |
1420
                                 XFS_TRANS_ABORT);
1421
                return (error);
1422
        }
1423
 
1424
        /*
1425
         * Keep an extra reference to this quota inode. This inode is
1426
         * locked exclusively and joined to the transaction already.
1427
         */
1428
        ASSERT(XFS_ISLOCKED_INODE_EXCL(*ip));
1429
        VN_HOLD(XFS_ITOV((*ip)));
1430
 
1431
        /*
1432
         * Make the changes in the superblock, and log those too.
1433
         * sbfields arg may contain fields other than *QUOTINO;
1434
         * VERSIONNUM for example.
1435
         */
1436
        s = XFS_SB_LOCK(mp);
1437
        if (flags & XFS_QMOPT_SBVERSION) {
1438
#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
1439
                unsigned oldv = mp->m_sb.sb_versionnum;
1440
#endif
1441
                ASSERT(!XFS_SB_VERSION_HASQUOTA(&mp->m_sb));
1442
                ASSERT((sbfields & (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
1443
                                   XFS_SB_GQUOTINO | XFS_SB_QFLAGS)) ==
1444
                       (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
1445
                        XFS_SB_GQUOTINO | XFS_SB_QFLAGS));
1446
 
1447
                XFS_SB_VERSION_ADDQUOTA(&mp->m_sb);
1448
                mp->m_sb.sb_uquotino = NULLFSINO;
1449
                mp->m_sb.sb_gquotino = NULLFSINO;
1450
 
1451
                /* qflags will get updated _after_ quotacheck */
1452
                mp->m_sb.sb_qflags = 0;
1453
#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
1454
                cmn_err(CE_NOTE,
1455
                        "Old superblock version %x, converting to %x.",
1456
                        oldv, mp->m_sb.sb_versionnum);
1457
#endif
1458
        }
1459
        if (flags & XFS_QMOPT_UQUOTA)
1460
                mp->m_sb.sb_uquotino = (*ip)->i_ino;
1461
        else
1462
                mp->m_sb.sb_gquotino = (*ip)->i_ino;
1463
        XFS_SB_UNLOCK(mp, s);
1464
        xfs_mod_sb(tp, sbfields);
1465
 
1466
        if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES,
1467
                                     NULL))) {
1468
                xfs_fs_cmn_err(CE_ALERT, mp, "XFS qino_alloc failed!");
1469
                return (error);
1470
        }
1471
        return (0);
1472
}
1473
 
1474
 
1475
STATIC int
1476
xfs_qm_reset_dqcounts(
1477
        xfs_mount_t     *mp,
1478
        xfs_buf_t       *bp,
1479
        xfs_dqid_t      id,
1480
        uint            type)
1481
{
1482
        xfs_disk_dquot_t        *ddq;
1483
        int                     j;
1484
 
1485
        xfs_buftrace("RESET DQUOTS", bp);
1486
        /*
1487
         * Reset all counters and timers. They'll be
1488
         * started afresh by xfs_qm_quotacheck.
1489
         */
1490
#ifdef DEBUG
1491
        j = XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB);
1492
        do_div(j, sizeof(xfs_dqblk_t));
1493
        ASSERT(XFS_QM_DQPERBLK(mp) == j);
1494
#endif
1495
        ddq = (xfs_disk_dquot_t *)XFS_BUF_PTR(bp);
1496
        for (j = 0; j < XFS_QM_DQPERBLK(mp); j++) {
1497
                /*
1498
                 * Do a sanity check, and if needed, repair the dqblk. Don't
1499
                 * output any warnings because it's perfectly possible to
1500
                 * find unitialized dquot blks. See comment in xfs_qm_dqcheck.
1501
                 */
1502
                (void) xfs_qm_dqcheck(ddq, id+j, type, XFS_QMOPT_DQREPAIR,
1503
                                      "xfs_quotacheck");
1504
                INT_SET(ddq->d_bcount, ARCH_CONVERT, 0ULL);
1505
                INT_SET(ddq->d_icount, ARCH_CONVERT, 0ULL);
1506
                INT_SET(ddq->d_rtbcount, ARCH_CONVERT, 0ULL);
1507
                INT_SET(ddq->d_btimer, ARCH_CONVERT, (time_t)0);
1508
                INT_SET(ddq->d_itimer, ARCH_CONVERT, (time_t)0);
1509
                INT_SET(ddq->d_bwarns, ARCH_CONVERT, 0UL);
1510
                INT_SET(ddq->d_iwarns, ARCH_CONVERT, 0UL);
1511
                ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1);
1512
        }
1513
 
1514
        return (0);
1515
}
1516
 
1517
STATIC int
1518
xfs_qm_dqiter_bufs(
1519
        xfs_mount_t     *mp,
1520
        xfs_dqid_t      firstid,
1521
        xfs_fsblock_t   bno,
1522
        xfs_filblks_t   blkcnt,
1523
        uint            flags)
1524
{
1525
        xfs_buf_t       *bp;
1526
        int             error;
1527
        int             notcommitted;
1528
        int             incr;
1529
 
1530
        ASSERT(blkcnt > 0);
1531
        notcommitted = 0;
1532
        incr = (blkcnt > XFS_QM_MAX_DQCLUSTER_LOGSZ) ?
1533
                XFS_QM_MAX_DQCLUSTER_LOGSZ : blkcnt;
1534
        error = 0;
1535
 
1536
        /*
1537
         * Blkcnt arg can be a very big number, and might even be
1538
         * larger than the log itself. So, we have to break it up into
1539
         * manageable-sized transactions.
1540
         * Note that we don't start a permanent transaction here; we might
1541
         * not be able to get a log reservation for the whole thing up front,
1542
         * and we don't really care to either, because we just discard
1543
         * everything if we were to crash in the middle of this loop.
1544
         */
1545
        while (blkcnt--) {
1546
                error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
1547
                              XFS_FSB_TO_DADDR(mp, bno),
1548
                              (int)XFS_QI_DQCHUNKLEN(mp), 0, &bp);
1549
                if (error)
1550
                        break;
1551
 
1552
                (void) xfs_qm_reset_dqcounts(mp, bp, firstid,
1553
                                             flags & XFS_QMOPT_UQUOTA ?
1554
                                             XFS_DQ_USER : XFS_DQ_GROUP);
1555
                xfs_bdwrite(mp, bp);
1556
                /*
1557
                 * goto the next block.
1558
                 */
1559
                bno++;
1560
                firstid += XFS_QM_DQPERBLK(mp);
1561
        }
1562
        return (error);
1563
}
1564
 
1565
/*
1566
 * Iterate over all allocated USR/GRP dquots in the system, calling a
1567
 * caller supplied function for every chunk of dquots that we find.
1568
 */
1569
STATIC int
1570
xfs_qm_dqiterate(
1571
        xfs_mount_t     *mp,
1572
        xfs_inode_t     *qip,
1573
        uint            flags)
1574
{
1575
        xfs_bmbt_irec_t         *map;
1576
        int                     i, nmaps;       /* number of map entries */
1577
        int                     error;          /* return value */
1578
        xfs_fileoff_t           lblkno;
1579
        xfs_filblks_t           maxlblkcnt;
1580
        xfs_dqid_t              firstid;
1581
        xfs_fsblock_t           rablkno;
1582
        xfs_filblks_t           rablkcnt;
1583
 
1584
        error = 0;
1585
        /*
1586
         * This looks racey, but we can't keep an inode lock across a
1587
         * trans_reserve. But, this gets called during quotacheck, and that
1588
         * happens only at mount time which is single threaded.
1589
         */
1590
        if (qip->i_d.di_nblocks == 0)
1591
                return (0);
1592
 
1593
        map = kmem_alloc(XFS_DQITER_MAP_SIZE * sizeof(*map), KM_SLEEP);
1594
 
1595
        lblkno = 0;
1596
        maxlblkcnt = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
1597
        do {
1598
                nmaps = XFS_DQITER_MAP_SIZE;
1599
                /*
1600
                 * We aren't changing the inode itself. Just changing
1601
                 * some of its data. No new blocks are added here, and
1602
                 * the inode is never added to the transaction.
1603
                 */
1604
                xfs_ilock(qip, XFS_ILOCK_SHARED);
1605
                error = xfs_bmapi(NULL, qip, lblkno,
1606
                                  maxlblkcnt - lblkno,
1607
                                  XFS_BMAPI_METADATA,
1608
                                  NULL,
1609
                                  0, map, &nmaps, NULL);
1610
                xfs_iunlock(qip, XFS_ILOCK_SHARED);
1611
                if (error)
1612
                        break;
1613
 
1614
                ASSERT(nmaps <= XFS_DQITER_MAP_SIZE);
1615
                for (i = 0; i < nmaps; i++) {
1616
                        ASSERT(map[i].br_startblock != DELAYSTARTBLOCK);
1617
                        ASSERT(map[i].br_blockcount);
1618
 
1619
 
1620
                        lblkno += map[i].br_blockcount;
1621
 
1622
                        if (map[i].br_startblock == HOLESTARTBLOCK)
1623
                                continue;
1624
 
1625
                        firstid = (xfs_dqid_t) map[i].br_startoff *
1626
                                XFS_QM_DQPERBLK(mp);
1627
                        /*
1628
                         * Do a read-ahead on the next extent.
1629
                         */
1630
                        if ((i+1 < nmaps) &&
1631
                            (map[i+1].br_startblock != HOLESTARTBLOCK)) {
1632
                                rablkcnt =  map[i+1].br_blockcount;
1633
                                rablkno = map[i+1].br_startblock;
1634
                                while (rablkcnt--) {
1635
                                        xfs_baread(mp->m_ddev_targp,
1636
                                               XFS_FSB_TO_DADDR(mp, rablkno),
1637
                                               (int)XFS_QI_DQCHUNKLEN(mp));
1638
                                        rablkno++;
1639
                                }
1640
                        }
1641
                        /*
1642
                         * Iterate thru all the blks in the extent and
1643
                         * reset the counters of all the dquots inside them.
1644
                         */
1645
                        if ((error = xfs_qm_dqiter_bufs(mp,
1646
                                                       firstid,
1647
                                                       map[i].br_startblock,
1648
                                                       map[i].br_blockcount,
1649
                                                       flags))) {
1650
                                break;
1651
                        }
1652
                }
1653
 
1654
                if (error)
1655
                        break;
1656
        } while (nmaps > 0);
1657
 
1658
        kmem_free(map, XFS_DQITER_MAP_SIZE * sizeof(*map));
1659
 
1660
        return (error);
1661
}
1662
 
1663
/*
1664
 * Called by dqusage_adjust in doing a quotacheck.
1665
 * Given the inode, and a dquot (either USR or GRP, doesn't matter),
1666
 * this updates its incore copy as well as the buffer copy. This is
1667
 * so that once the quotacheck is done, we can just log all the buffers,
1668
 * as opposed to logging numerous updates to individual dquots.
1669
 */
1670
STATIC void
1671
xfs_qm_quotacheck_dqadjust(
1672
        xfs_dquot_t             *dqp,
1673
        xfs_qcnt_t              nblks,
1674
        xfs_qcnt_t              rtblks)
1675
{
1676
        ASSERT(XFS_DQ_IS_LOCKED(dqp));
1677
        xfs_dqtrace_entry(dqp, "QCHECK DQADJUST");
1678
        /*
1679
         * Adjust the inode count and the block count to reflect this inode's
1680
         * resource usage.
1681
         */
1682
        INT_MOD(dqp->q_core.d_icount, ARCH_CONVERT, +1);
1683
        dqp->q_res_icount++;
1684
        if (nblks) {
1685
                INT_MOD(dqp->q_core.d_bcount, ARCH_CONVERT, nblks);
1686
                dqp->q_res_bcount += nblks;
1687
        }
1688
        if (rtblks) {
1689
                INT_MOD(dqp->q_core.d_rtbcount, ARCH_CONVERT, rtblks);
1690
                dqp->q_res_rtbcount += rtblks;
1691
        }
1692
 
1693
        /*
1694
         * Adjust the timers since we just changed usages
1695
         */
1696
        if (! XFS_IS_SUSER_DQUOT(dqp))
1697
                xfs_qm_adjust_dqtimers(dqp->q_mount, &dqp->q_core);
1698
 
1699
        dqp->dq_flags |= XFS_DQ_DIRTY;
1700
}
1701
 
1702
STATIC int
1703
xfs_qm_get_rtblks(
1704
        xfs_inode_t     *ip,
1705
        xfs_qcnt_t      *O_rtblks)
1706
{
1707
        xfs_filblks_t   rtblks;                 /* total rt blks */
1708
        xfs_ifork_t     *ifp;                   /* inode fork pointer */
1709
        xfs_extnum_t    nextents;               /* number of extent entries */
1710
        xfs_bmbt_rec_t  *base;                  /* base of extent array */
1711
        xfs_bmbt_rec_t  *ep;                    /* pointer to an extent entry */
1712
        int             error;
1713
 
1714
        ASSERT(XFS_IS_REALTIME_INODE(ip));
1715
        ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
1716
        if (!(ifp->if_flags & XFS_IFEXTENTS)) {
1717
                if ((error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK)))
1718
                        return (error);
1719
        }
1720
        rtblks = 0;
1721
        nextents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
1722
        base = &ifp->if_u1.if_extents[0];
1723
        for (ep = base; ep < &base[nextents]; ep++)
1724
                rtblks += xfs_bmbt_get_blockcount(ep);
1725
        *O_rtblks = (xfs_qcnt_t)rtblks;
1726
        return (0);
1727
}
1728
 
1729
/*
1730
 * callback routine supplied to bulkstat(). Given an inumber, find its
1731
 * dquots and update them to account for resources taken by that inode.
1732
 */
1733
/* ARGSUSED */
1734
STATIC int
1735
xfs_qm_dqusage_adjust(
1736
        xfs_mount_t     *mp,            /* mount point for filesystem */
1737
        xfs_trans_t     *tp,            /* transaction pointer - NULL */
1738
        xfs_ino_t       ino,            /* inode number to get data for */
1739
        void            *buffer,        /* not used */
1740
        int             ubsize,         /* not used */
1741
        void            *private_data,  /* not used */
1742
        xfs_daddr_t     bno,            /* starting block of inode cluster */
1743
        int             *ubused,        /* not used */
1744
        void            *dip,           /* on-disk inode pointer (not used) */
1745
        int             *res)           /* result code value */
1746
{
1747
        xfs_inode_t     *ip;
1748
        xfs_dquot_t     *udqp, *gdqp;
1749
        xfs_qcnt_t      nblks, rtblks;
1750
        int             error;
1751
 
1752
        ASSERT(XFS_IS_QUOTA_RUNNING(mp));
1753
 
1754
        /*
1755
         * rootino must have its resources accounted for, not so with the quota
1756
         * inodes.
1757
         */
1758
        if (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino) {
1759
                *res = BULKSTAT_RV_NOTHING;
1760
                return XFS_ERROR(EINVAL);
1761
        }
1762
 
1763
        /*
1764
         * We don't _need_ to take the ilock EXCL. However, the xfs_qm_dqget
1765
         * interface expects the inode to be exclusively locked because that's
1766
         * the case in all other instances. It's OK that we do this because
1767
         * quotacheck is done only at mount time.
1768
         */
1769
        if ((error = xfs_iget(mp, tp, ino, XFS_ILOCK_EXCL, &ip, bno))) {
1770
                *res = BULKSTAT_RV_NOTHING;
1771
                return (error);
1772
        }
1773
 
1774
        if (ip->i_d.di_mode == 0) {
1775
                xfs_iput_new(ip, XFS_ILOCK_EXCL);
1776
                *res = BULKSTAT_RV_NOTHING;
1777
                return XFS_ERROR(ENOENT);
1778
        }
1779
 
1780
        /*
1781
         * Obtain the locked dquots. In case of an error (eg. allocation
1782
         * fails for ENOSPC), we return the negative of the error number
1783
         * to bulkstat, so that it can get propagated to quotacheck() and
1784
         * making us disable quotas for the file system.
1785
         */
1786
        if ((error = xfs_qm_dqget_noattach(ip, &udqp, &gdqp))) {
1787
                xfs_iput(ip, XFS_ILOCK_EXCL);
1788
                *res = BULKSTAT_RV_GIVEUP;
1789
                return (error);
1790
        }
1791
 
1792
        rtblks = 0;
1793
        if (! XFS_IS_REALTIME_INODE(ip)) {
1794
                nblks = (xfs_qcnt_t)ip->i_d.di_nblocks;
1795
        } else {
1796
                /*
1797
                 * Walk thru the extent list and count the realtime blocks.
1798
                 */
1799
                if ((error = xfs_qm_get_rtblks(ip, &rtblks))) {
1800
                        xfs_iput(ip, XFS_ILOCK_EXCL);
1801
                        if (udqp)
1802
                                xfs_qm_dqput(udqp);
1803
                        if (gdqp)
1804
                                xfs_qm_dqput(gdqp);
1805
                        *res = BULKSTAT_RV_GIVEUP;
1806
                        return (error);
1807
                }
1808
                nblks = (xfs_qcnt_t)ip->i_d.di_nblocks - rtblks;
1809
        }
1810
        ASSERT(ip->i_delayed_blks == 0);
1811
 
1812
        /*
1813
         * We can't release the inode while holding its dquot locks.
1814
         * The inode can go into inactive and might try to acquire the dquotlocks.
1815
         * So, just unlock here and do a vn_rele at the end.
1816
         */
1817
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
1818
 
1819
        /*
1820
         * Add the (disk blocks and inode) resources occupied by this
1821
         * inode to its dquots. We do this adjustment in the incore dquot,
1822
         * and also copy the changes to its buffer.
1823
         * We don't care about putting these changes in a transaction
1824
         * envelope because if we crash in the middle of a 'quotacheck'
1825
         * we have to start from the beginning anyway.
1826
         * Once we're done, we'll log all the dquot bufs.
1827
         *
1828
         * The *QUOTA_ON checks below may look pretty racey, but quotachecks
1829
         * and quotaoffs don't race. (Quotachecks happen at mount time only).
1830
         */
1831
        if (XFS_IS_UQUOTA_ON(mp)) {
1832
                ASSERT(udqp);
1833
                xfs_qm_quotacheck_dqadjust(udqp, nblks, rtblks);
1834
                xfs_qm_dqput(udqp);
1835
        }
1836
        if (XFS_IS_GQUOTA_ON(mp)) {
1837
                ASSERT(gdqp);
1838
                xfs_qm_quotacheck_dqadjust(gdqp, nblks, rtblks);
1839
                xfs_qm_dqput(gdqp);
1840
        }
1841
        /*
1842
         * Now release the inode. This will send it to 'inactive', and
1843
         * possibly even free blocks.
1844
         */
1845
        VN_RELE(XFS_ITOV(ip));
1846
 
1847
        /*
1848
         * Goto next inode.
1849
         */
1850
        *res = BULKSTAT_RV_DIDONE;
1851
        return (0);
1852
}
1853
 
1854
/*
1855
 * Walk thru all the filesystem inodes and construct a consistent view
1856
 * of the disk quota world.
1857
 */
1858
STATIC int
1859
xfs_qm_quotacheck(
1860
        xfs_mount_t     *mp)
1861
{
1862
        int             done, count, error;
1863
        xfs_ino_t       lastino;
1864
        size_t          structsz;
1865
        xfs_inode_t     *uip, *gip;
1866
        uint            flags;
1867
 
1868
        count = INT_MAX;
1869
        structsz = 1;
1870
        lastino = 0;
1871
        flags = 0;
1872
 
1873
        ASSERT(XFS_QI_UQIP(mp) || XFS_QI_GQIP(mp));
1874
        ASSERT(XFS_IS_QUOTA_RUNNING(mp));
1875
 
1876
        /*
1877
         * There should be no cached dquots. The (simplistic) quotacheck
1878
         * algorithm doesn't like that.
1879
         */
1880
        ASSERT(XFS_QI_MPLNDQUOTS(mp) == 0);
1881
 
1882
        cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname);
1883
 
1884
        /*
1885
         * First we go thru all the dquots on disk, USR and GRP, and reset
1886
         * their counters to zero. We need a clean slate.
1887
         * We don't log our changes till later.
1888
         */
1889
        if ((uip = XFS_QI_UQIP(mp))) {
1890
                if ((error = xfs_qm_dqiterate(mp, uip, XFS_QMOPT_UQUOTA)))
1891
                        goto error_return;
1892
                flags |= XFS_UQUOTA_CHKD;
1893
        }
1894
 
1895
        if ((gip = XFS_QI_GQIP(mp))) {
1896
                if ((error = xfs_qm_dqiterate(mp, gip, XFS_QMOPT_GQUOTA)))
1897
                        goto error_return;
1898
                flags |= XFS_GQUOTA_CHKD;
1899
        }
1900
 
1901
        do {
1902
                /*
1903
                 * Iterate thru all the inodes in the file system,
1904
                 * adjusting the corresponding dquot counters in core.
1905
                 */
1906
                if ((error = xfs_bulkstat(mp, NULL, &lastino, &count,
1907
                                     xfs_qm_dqusage_adjust, NULL,
1908
                                     structsz, NULL,
1909
                                     BULKSTAT_FG_IGET|BULKSTAT_FG_VFSLOCKED,
1910
                                     &done)))
1911
                        break;
1912
 
1913
        } while (! done);
1914
 
1915
        /*
1916
         * We can get this error if we couldn't do a dquot allocation inside
1917
         * xfs_qm_dqusage_adjust (via bulkstat). We don't care about the
1918
         * dirty dquots that might be cached, we just want to get rid of them
1919
         * and turn quotaoff. The dquots won't be attached to any of the inodes
1920
         * at this point (because we intentionally didn't in dqget_noattach).
1921
         */
1922
        if (error) {
1923
                xfs_qm_dqpurge_all(mp,
1924
                                   XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA|
1925
                                   XFS_QMOPT_QUOTAOFF);
1926
                goto error_return;
1927
        }
1928
        /*
1929
         * We've made all the changes that we need to make incore.
1930
         * Now flush_them down to disk buffers.
1931
         */
1932
        xfs_qm_dqflush_all(mp, XFS_QMOPT_DELWRI);
1933
 
1934
        /*
1935
         * We didn't log anything, because if we crashed, we'll have to
1936
         * start the quotacheck from scratch anyway. However, we must make
1937
         * sure that our dquot changes are secure before we put the
1938
         * quotacheck'd stamp on the superblock. So, here we do a synchronous
1939
         * flush.
1940
         */
1941
        XFS_bflush(mp->m_ddev_targp);
1942
 
1943
        /*
1944
         * If one type of quotas is off, then it will lose its
1945
         * quotachecked status, since we won't be doing accounting for
1946
         * that type anymore.
1947
         */
1948
        mp->m_qflags &= ~(XFS_GQUOTA_CHKD | XFS_UQUOTA_CHKD);
1949
        mp->m_qflags |= flags;
1950
 
1951
        XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++");
1952
 
1953
 error_return:
1954
        cmn_err(CE_NOTE, "XFS quotacheck %s: Done.", mp->m_fsname);
1955
        return (error);
1956
}
1957
 
1958
/*
1959
 * This is called after the superblock has been read in and we're ready to
1960
 * iget the quota inodes.
1961
 */
1962
STATIC int
1963
xfs_qm_init_quotainos(
1964
        xfs_mount_t     *mp)
1965
{
1966
        xfs_inode_t     *uip, *gip;
1967
        int             error;
1968
        __int64_t       sbflags;
1969
        uint            flags;
1970
 
1971
        ASSERT(mp->m_quotainfo);
1972
        uip = gip = NULL;
1973
        sbflags = 0;
1974
        flags = 0;
1975
 
1976
        /*
1977
         * Get the uquota and gquota inodes
1978
         */
1979
        if (XFS_SB_VERSION_HASQUOTA(&mp->m_sb)) {
1980
                if (XFS_IS_UQUOTA_ON(mp) &&
1981
                    mp->m_sb.sb_uquotino != NULLFSINO) {
1982
                        ASSERT(mp->m_sb.sb_uquotino > 0);
1983
                        if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
1984
                                             0, &uip, 0)))
1985
                                return XFS_ERROR(error);
1986
                }
1987
                if (XFS_IS_GQUOTA_ON(mp) &&
1988
                    mp->m_sb.sb_gquotino != NULLFSINO) {
1989
                        ASSERT(mp->m_sb.sb_gquotino > 0);
1990
                        if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
1991
                                             0, &gip, 0))) {
1992
                                if (uip)
1993
                                        VN_RELE(XFS_ITOV(uip));
1994
                                return XFS_ERROR(error);
1995
                        }
1996
                }
1997
        } else {
1998
                flags |= XFS_QMOPT_SBVERSION;
1999
                sbflags |= (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
2000
                            XFS_SB_GQUOTINO | XFS_SB_QFLAGS);
2001
        }
2002
 
2003
        /*
2004
         * Create the two inodes, if they don't exist already. The changes
2005
         * made above will get added to a transaction and logged in one of
2006
         * the qino_alloc calls below.  If the device is readonly,
2007
         * temporarily switch to read-write to do this.
2008
         */
2009
        if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) {
2010
                if ((error = xfs_qm_qino_alloc(mp, &uip,
2011
                                              sbflags | XFS_SB_UQUOTINO,
2012
                                              flags | XFS_QMOPT_UQUOTA)))
2013
                        return XFS_ERROR(error);
2014
 
2015
                flags &= ~XFS_QMOPT_SBVERSION;
2016
        }
2017
        if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) {
2018
                if ((error = xfs_qm_qino_alloc(mp, &gip,
2019
                                              sbflags | XFS_SB_GQUOTINO,
2020
                                              flags | XFS_QMOPT_GQUOTA))) {
2021
                        if (uip)
2022
                                VN_RELE(XFS_ITOV(uip));
2023
 
2024
                        return XFS_ERROR(error);
2025
                }
2026
        }
2027
 
2028
        XFS_QI_UQIP(mp) = uip;
2029
        XFS_QI_GQIP(mp) = gip;
2030
 
2031
        return (0);
2032
}
2033
 
2034
 
2035
/*
2036
 * Traverse the freelist of dquots and attempt to reclaim a maximum of
2037
 * 'howmany' dquots. This operation races with dqlookup(), and attempts to
2038
 * favor the lookup function ...
2039
 * XXXsup merge this with qm_reclaim_one().
2040
 */
2041
STATIC int
2042
xfs_qm_shake_freelist(
2043
        int howmany)
2044
{
2045
        int             nreclaimed;
2046
        xfs_dqhash_t    *hash;
2047
        xfs_dquot_t     *dqp, *nextdqp;
2048
        int             restarts;
2049
        int             nflushes;
2050
 
2051
        if (howmany <= 0)
2052
                return (0);
2053
 
2054
        nreclaimed = 0;
2055
        restarts = 0;
2056
        nflushes = 0;
2057
 
2058
#ifdef QUOTADEBUG
2059
        cmn_err(CE_DEBUG, "Shake free 0x%x", howmany);
2060
#endif
2061
        /* lock order is : hashchainlock, freelistlock, mplistlock */
2062
 tryagain:
2063
        xfs_qm_freelist_lock(xfs_Gqm);
2064
 
2065
        for (dqp = xfs_Gqm->qm_dqfreelist.qh_next;
2066
             ((dqp != (xfs_dquot_t *) &xfs_Gqm->qm_dqfreelist) &&
2067
              nreclaimed < howmany); ) {
2068
                xfs_dqlock(dqp);
2069
 
2070
                /*
2071
                 * We are racing with dqlookup here. Naturally we don't
2072
                 * want to reclaim a dquot that lookup wants.
2073
                 */
2074
                if (dqp->dq_flags & XFS_DQ_WANT) {
2075
                        xfs_dqunlock(dqp);
2076
                        xfs_qm_freelist_unlock(xfs_Gqm);
2077
                        if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
2078
                                return (nreclaimed);
2079
                        XQM_STATS_INC(xqmstats.xs_qm_dqwants);
2080
                        goto tryagain;
2081
                }
2082
 
2083
                /*
2084
                 * If the dquot is inactive, we are assured that it is
2085
                 * not on the mplist or the hashlist, and that makes our
2086
                 * life easier.
2087
                 */
2088
                if (dqp->dq_flags & XFS_DQ_INACTIVE) {
2089
                        ASSERT(dqp->q_mount == NULL);
2090
                        ASSERT(! XFS_DQ_IS_DIRTY(dqp));
2091
                        ASSERT(dqp->HL_PREVP == NULL);
2092
                        ASSERT(dqp->MPL_PREVP == NULL);
2093
                        XQM_STATS_INC(xqmstats.xs_qm_dqinact_reclaims);
2094
                        nextdqp = dqp->dq_flnext;
2095
                        goto off_freelist;
2096
                }
2097
 
2098
                ASSERT(dqp->MPL_PREVP);
2099
                /*
2100
                 * Try to grab the flush lock. If this dquot is in the process of
2101
                 * getting flushed to disk, we don't want to reclaim it.
2102
                 */
2103
                if (! xfs_qm_dqflock_nowait(dqp)) {
2104
                        xfs_dqunlock(dqp);
2105
                        dqp = dqp->dq_flnext;
2106
                        continue;
2107
                }
2108
 
2109
                /*
2110
                 * We have the flush lock so we know that this is not in the
2111
                 * process of being flushed. So, if this is dirty, flush it
2112
                 * DELWRI so that we don't get a freelist infested with
2113
                 * dirty dquots.
2114
                 */
2115
                if (XFS_DQ_IS_DIRTY(dqp)) {
2116
                        xfs_dqtrace_entry(dqp, "DQSHAKE: DQDIRTY");
2117
                        /*
2118
                         * We flush it delayed write, so don't bother
2119
                         * releasing the mplock.
2120
                         */
2121
                        (void) xfs_qm_dqflush(dqp, XFS_QMOPT_DELWRI);
2122
                        xfs_dqunlock(dqp); /* dqflush unlocks dqflock */
2123
                        dqp = dqp->dq_flnext;
2124
                        continue;
2125
                }
2126
                /*
2127
                 * We're trying to get the hashlock out of order. This races
2128
                 * with dqlookup; so, we giveup and goto the next dquot if
2129
                 * we couldn't get the hashlock. This way, we won't starve
2130
                 * a dqlookup process that holds the hashlock that is
2131
                 * waiting for the freelist lock.
2132
                 */
2133
                if (! xfs_qm_dqhashlock_nowait(dqp)) {
2134
                        xfs_dqfunlock(dqp);
2135
                        xfs_dqunlock(dqp);
2136
                        dqp = dqp->dq_flnext;
2137
                        continue;
2138
                }
2139
                /*
2140
                 * This races with dquot allocation code as well as dqflush_all
2141
                 * and reclaim code. So, if we failed to grab the mplist lock,
2142
                 * giveup everything and start over.
2143
                 */
2144
                hash = dqp->q_hash;
2145
                ASSERT(hash);
2146
                if (! xfs_qm_mplist_nowait(dqp->q_mount)) {
2147
                        /* XXX put a sentinel so that we can come back here */
2148
                        xfs_dqfunlock(dqp);
2149
                        xfs_dqunlock(dqp);
2150
                        XFS_DQ_HASH_UNLOCK(hash);
2151
                        xfs_qm_freelist_unlock(xfs_Gqm);
2152
                        if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
2153
                                return (nreclaimed);
2154
                        goto tryagain;
2155
                }
2156
                xfs_dqtrace_entry(dqp, "DQSHAKE: UNLINKING");
2157
#ifdef QUOTADEBUG
2158
                cmn_err(CE_DEBUG, "Shake 0x%p, ID 0x%x\n",
2159
                        dqp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
2160
#endif
2161
                ASSERT(dqp->q_nrefs == 0);
2162
                nextdqp = dqp->dq_flnext;
2163
                XQM_MPLIST_REMOVE(&(XFS_QI_MPL_LIST(dqp->q_mount)), dqp);
2164
                XQM_HASHLIST_REMOVE(hash, dqp);
2165
                xfs_dqfunlock(dqp);
2166
                xfs_qm_mplist_unlock(dqp->q_mount);
2167
                XFS_DQ_HASH_UNLOCK(hash);
2168
 
2169
 off_freelist:
2170
                XQM_FREELIST_REMOVE(dqp);
2171
                xfs_dqunlock(dqp);
2172
                nreclaimed++;
2173
                XQM_STATS_INC(xqmstats.xs_qm_dqshake_reclaims);
2174
                xfs_qm_dqdestroy(dqp);
2175
                dqp = nextdqp;
2176
        }
2177
        xfs_qm_freelist_unlock(xfs_Gqm);
2178
        return (nreclaimed);
2179
}
2180
 
2181
 
2182
/*
2183
 * The kmem_shake interface is invoked when memory is running low.
2184
 */
2185
/* ARGSUSED */
2186
STATIC int
2187
xfs_qm_shake(int nr_to_scan, unsigned int gfp_mask)
2188
{
2189
        int     ndqused, nfree, n;
2190
 
2191
        if (!kmem_shake_allow(gfp_mask))
2192
                return (0);
2193
        if (!xfs_Gqm)
2194
                return (0);
2195
 
2196
        nfree = xfs_Gqm->qm_dqfreelist.qh_nelems; /* free dquots */
2197
        /* incore dquots in all f/s's */
2198
        ndqused = atomic_read(&xfs_Gqm->qm_totaldquots) - nfree;
2199
 
2200
        ASSERT(ndqused >= 0);
2201
 
2202
        if (nfree <= ndqused && nfree < ndquot)
2203
                return (0);
2204
 
2205
        ndqused *= xfs_Gqm->qm_dqfree_ratio;    /* target # of free dquots */
2206
        n = nfree - ndqused - ndquot;           /* # over target */
2207
 
2208
        return xfs_qm_shake_freelist(MAX(nfree, n));
2209
}
2210
 
2211
 
2212
/*
2213
 * Just pop the least recently used dquot off the freelist and
2214
 * recycle it. The returned dquot is locked.
2215
 */
2216
STATIC xfs_dquot_t *
2217
xfs_qm_dqreclaim_one(void)
2218
{
2219
        xfs_dquot_t     *dqpout;
2220
        xfs_dquot_t     *dqp;
2221
        int             restarts;
2222
        int             nflushes;
2223
 
2224
        restarts = 0;
2225
        dqpout = NULL;
2226
        nflushes = 0;
2227
 
2228
        /* lockorder: hashchainlock, freelistlock, mplistlock, dqlock, dqflock */
2229
 startagain:
2230
        xfs_qm_freelist_lock(xfs_Gqm);
2231
 
2232
        FOREACH_DQUOT_IN_FREELIST(dqp, &(xfs_Gqm->qm_dqfreelist)) {
2233
                xfs_dqlock(dqp);
2234
 
2235
                /*
2236
                 * We are racing with dqlookup here. Naturally we don't
2237
                 * want to reclaim a dquot that lookup wants. We release the
2238
                 * freelist lock and start over, so that lookup will grab
2239
                 * both the dquot and the freelistlock.
2240
                 */
2241
                if (dqp->dq_flags & XFS_DQ_WANT) {
2242
                        ASSERT(! (dqp->dq_flags & XFS_DQ_INACTIVE));
2243
                        xfs_dqtrace_entry(dqp, "DQRECLAIM: DQWANT");
2244
                        xfs_dqunlock(dqp);
2245
                        xfs_qm_freelist_unlock(xfs_Gqm);
2246
                        if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
2247
                                return (NULL);
2248
                        XQM_STATS_INC(xqmstats.xs_qm_dqwants);
2249
                        goto startagain;
2250
                }
2251
 
2252
                /*
2253
                 * If the dquot is inactive, we are assured that it is
2254
                 * not on the mplist or the hashlist, and that makes our
2255
                 * life easier.
2256
                 */
2257
                if (dqp->dq_flags & XFS_DQ_INACTIVE) {
2258
                        ASSERT(dqp->q_mount == NULL);
2259
                        ASSERT(! XFS_DQ_IS_DIRTY(dqp));
2260
                        ASSERT(dqp->HL_PREVP == NULL);
2261
                        ASSERT(dqp->MPL_PREVP == NULL);
2262
                        XQM_FREELIST_REMOVE(dqp);
2263
                        xfs_dqunlock(dqp);
2264
                        dqpout = dqp;
2265
                        XQM_STATS_INC(xqmstats.xs_qm_dqinact_reclaims);
2266
                        break;
2267
                }
2268
 
2269
                ASSERT(dqp->q_hash);
2270
                ASSERT(dqp->MPL_PREVP);
2271
 
2272
                /*
2273
                 * Try to grab the flush lock. If this dquot is in the process of
2274
                 * getting flushed to disk, we don't want to reclaim it.
2275
                 */
2276
                if (! xfs_qm_dqflock_nowait(dqp)) {
2277
                        xfs_dqunlock(dqp);
2278
                        continue;
2279
                }
2280
 
2281
                /*
2282
                 * We have the flush lock so we know that this is not in the
2283
                 * process of being flushed. So, if this is dirty, flush it
2284
                 * DELWRI so that we don't get a freelist infested with
2285
                 * dirty dquots.
2286
                 */
2287
                if (XFS_DQ_IS_DIRTY(dqp)) {
2288
                        xfs_dqtrace_entry(dqp, "DQRECLAIM: DQDIRTY");
2289
                        /*
2290
                         * We flush it delayed write, so don't bother
2291
                         * releasing the freelist lock.
2292
                         */
2293
                        (void) xfs_qm_dqflush(dqp, XFS_QMOPT_DELWRI);
2294
                        xfs_dqunlock(dqp); /* dqflush unlocks dqflock */
2295
                        continue;
2296
                }
2297
 
2298
                if (! xfs_qm_mplist_nowait(dqp->q_mount)) {
2299
                        xfs_dqfunlock(dqp);
2300
                        xfs_dqunlock(dqp);
2301
                        continue;
2302
                }
2303
 
2304
                if (! xfs_qm_dqhashlock_nowait(dqp))
2305
                        goto mplistunlock;
2306
 
2307
                ASSERT(dqp->q_nrefs == 0);
2308
                xfs_dqtrace_entry(dqp, "DQRECLAIM: UNLINKING");
2309
                XQM_MPLIST_REMOVE(&(XFS_QI_MPL_LIST(dqp->q_mount)), dqp);
2310
                XQM_HASHLIST_REMOVE(dqp->q_hash, dqp);
2311
                XQM_FREELIST_REMOVE(dqp);
2312
                dqpout = dqp;
2313
                XFS_DQ_HASH_UNLOCK(dqp->q_hash);
2314
 mplistunlock:
2315
                xfs_qm_mplist_unlock(dqp->q_mount);
2316
                xfs_dqfunlock(dqp);
2317
                xfs_dqunlock(dqp);
2318
                if (dqpout)
2319
                        break;
2320
        }
2321
 
2322
        xfs_qm_freelist_unlock(xfs_Gqm);
2323
        return (dqpout);
2324
}
2325
 
2326
 
2327
/*------------------------------------------------------------------*/
2328
 
2329
/*
2330
 * Return a new incore dquot. Depending on the number of
2331
 * dquots in the system, we either allocate a new one on the kernel heap,
2332
 * or reclaim a free one.
2333
 * Return value is B_TRUE if we allocated a new dquot, B_FALSE if we managed
2334
 * to reclaim an existing one from the freelist.
2335
 */
2336
boolean_t
2337
xfs_qm_dqalloc_incore(
2338
        xfs_dquot_t **O_dqpp)
2339
{
2340
        xfs_dquot_t     *dqp;
2341
 
2342
        /*
2343
         * Check against high water mark to see if we want to pop
2344
         * a nincompoop dquot off the freelist.
2345
         */
2346
        if (atomic_read(&xfs_Gqm->qm_totaldquots) >= ndquot) {
2347
                /*
2348
                 * Try to recycle a dquot from the freelist.
2349
                 */
2350
                if ((dqp = xfs_qm_dqreclaim_one())) {
2351
                        XQM_STATS_INC(xqmstats.xs_qm_dqreclaims);
2352
                        /*
2353
                         * Just zero the core here. The rest will get
2354
                         * reinitialized by caller. XXX we shouldn't even
2355
                         * do this zero ...
2356
                         */
2357
                        memset(&dqp->q_core, 0, sizeof(dqp->q_core));
2358
                        *O_dqpp = dqp;
2359
                        return (B_FALSE);
2360
                }
2361
                XQM_STATS_INC(xqmstats.xs_qm_dqreclaim_misses);
2362
        }
2363
 
2364
        /*
2365
         * Allocate a brand new dquot on the kernel heap and return it
2366
         * to the caller to initialize.
2367
         */
2368
        ASSERT(xfs_Gqm->qm_dqzone != NULL);
2369
        *O_dqpp = kmem_zone_zalloc(xfs_Gqm->qm_dqzone, KM_SLEEP);
2370
        atomic_inc(&xfs_Gqm->qm_totaldquots);
2371
 
2372
        return (B_TRUE);
2373
}
2374
 
2375
 
2376
/*
2377
 * Start a transaction and write the incore superblock changes to
2378
 * disk. flags parameter indicates which fields have changed.
2379
 */
2380
int
2381
xfs_qm_write_sb_changes(
2382
        xfs_mount_t     *mp,
2383
        __int64_t       flags)
2384
{
2385
        xfs_trans_t     *tp;
2386
        int             error;
2387
 
2388
#ifdef QUOTADEBUG
2389
        cmn_err(CE_NOTE, "Writing superblock quota changes :%s", mp->m_fsname);
2390
#endif
2391
        tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
2392
        if ((error = xfs_trans_reserve(tp, 0,
2393
                                      mp->m_sb.sb_sectsize + 128, 0,
2394
                                      0,
2395
                                      XFS_DEFAULT_LOG_COUNT))) {
2396
                xfs_trans_cancel(tp, 0);
2397
                return (error);
2398
        }
2399
 
2400
        xfs_mod_sb(tp, flags);
2401
        (void) xfs_trans_commit(tp, 0, NULL);
2402
 
2403
        return (0);
2404
}
2405
 
2406
 
2407
/* --------------- utility functions for vnodeops ---------------- */
2408
 
2409
 
2410
/*
2411
 * Given an inode, a uid and gid (from cred_t) make sure that we have
2412
 * allocated relevant dquot(s) on disk, and that we won't exceed inode
2413
 * quotas by creating this file.
2414
 * This also attaches dquot(s) to the given inode after locking it,
2415
 * and returns the dquots corresponding to the uid and/or gid.
2416
 *
2417
 * in   : inode (unlocked)
2418
 * out  : udquot, gdquot with references taken and unlocked
2419
 */
2420
int
2421
xfs_qm_vop_dqalloc(
2422
        xfs_mount_t     *mp,
2423
        xfs_inode_t     *ip,
2424
        uid_t           uid,
2425
        gid_t           gid,
2426
        uint            flags,
2427
        xfs_dquot_t     **O_udqpp,
2428
        xfs_dquot_t     **O_gdqpp)
2429
{
2430
        int             error;
2431
        xfs_dquot_t     *uq, *gq;
2432
        uint            lockflags;
2433
 
2434
        if (!XFS_IS_QUOTA_ON(mp))
2435
                return 0;
2436
 
2437
        lockflags = XFS_ILOCK_EXCL;
2438
        xfs_ilock(ip, lockflags);
2439
 
2440
        if ((flags & XFS_QMOPT_INHERIT) &&
2441
            XFS_INHERIT_GID(ip, XFS_MTOVFS(mp)))
2442
                gid = ip->i_d.di_gid;
2443
 
2444
        /*
2445
         * Attach the dquot(s) to this inode, doing a dquot allocation
2446
         * if necessary. The dquot(s) will not be locked.
2447
         */
2448
        if (XFS_NOT_DQATTACHED(mp, ip)) {
2449
                if ((error = xfs_qm_dqattach(ip, XFS_QMOPT_DQALLOC |
2450
                                            XFS_QMOPT_ILOCKED))) {
2451
                        xfs_iunlock(ip, lockflags);
2452
                        return (error);
2453
                }
2454
        }
2455
 
2456
        uq = gq = NULL;
2457
        if ((flags & XFS_QMOPT_UQUOTA) &&
2458
            XFS_IS_UQUOTA_ON(mp)) {
2459
                if (ip->i_d.di_uid != uid) {
2460
                        /*
2461
                         * What we need is the dquot that has this uid, and
2462
                         * if we send the inode to dqget, the uid of the inode
2463
                         * takes priority over what's sent in the uid argument.
2464
                         * We must unlock inode here before calling dqget if
2465
                         * we're not sending the inode, because otherwise
2466
                         * we'll deadlock by doing trans_reserve while
2467
                         * holding ilock.
2468
                         */
2469
                        xfs_iunlock(ip, lockflags);
2470
                        if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t) uid,
2471
                                                 XFS_DQ_USER,
2472
                                                 XFS_QMOPT_DQALLOC |
2473
                                                 XFS_QMOPT_DOWARN,
2474
                                                 &uq))) {
2475
                                ASSERT(error != ENOENT);
2476
                                return (error);
2477
                        }
2478
                        /*
2479
                         * Get the ilock in the right order.
2480
                         */
2481
                        xfs_dqunlock(uq);
2482
                        lockflags = XFS_ILOCK_SHARED;
2483
                        xfs_ilock(ip, lockflags);
2484
                } else {
2485
                        /*
2486
                         * Take an extra reference, because we'll return
2487
                         * this to caller
2488
                         */
2489
                        ASSERT(ip->i_udquot);
2490
                        uq = ip->i_udquot;
2491
                        xfs_dqlock(uq);
2492
                        XFS_DQHOLD(uq);
2493
                        xfs_dqunlock(uq);
2494
                }
2495
        }
2496
        if ((flags & XFS_QMOPT_GQUOTA) &&
2497
            XFS_IS_GQUOTA_ON(mp)) {
2498
                if (ip->i_d.di_gid != gid) {
2499
                        xfs_iunlock(ip, lockflags);
2500
                        if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
2501
                                                 XFS_DQ_GROUP,
2502
                                                 XFS_QMOPT_DQALLOC |
2503
                                                 XFS_QMOPT_DOWARN,
2504
                                                 &gq))) {
2505
                                if (uq)
2506
                                        xfs_qm_dqrele(uq);
2507
                                ASSERT(error != ENOENT);
2508
                                return (error);
2509
                        }
2510
                        xfs_dqunlock(gq);
2511
                        lockflags = XFS_ILOCK_SHARED;
2512
                        xfs_ilock(ip, lockflags);
2513
                } else {
2514
                        ASSERT(ip->i_gdquot);
2515
                        gq = ip->i_gdquot;
2516
                        xfs_dqlock(gq);
2517
                        XFS_DQHOLD(gq);
2518
                        xfs_dqunlock(gq);
2519
                }
2520
        }
2521
        if (uq)
2522
                xfs_dqtrace_entry_ino(uq, "DQALLOC", ip);
2523
 
2524
        xfs_iunlock(ip, lockflags);
2525
        if (O_udqpp)
2526
                *O_udqpp = uq;
2527
        else if (uq)
2528
                xfs_qm_dqrele(uq);
2529
        if (O_gdqpp)
2530
                *O_gdqpp = gq;
2531
        else if (gq)
2532
                xfs_qm_dqrele(gq);
2533
        return (0);
2534
}
2535
 
2536
/*
2537
 * Actually transfer ownership, and do dquot modifications.
2538
 * These were already reserved.
2539
 */
2540
xfs_dquot_t *
2541
xfs_qm_vop_chown(
2542
        xfs_trans_t     *tp,
2543
        xfs_inode_t     *ip,
2544
        xfs_dquot_t     **IO_olddq,
2545
        xfs_dquot_t     *newdq)
2546
{
2547
        xfs_dquot_t     *prevdq;
2548
        ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
2549
        ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
2550
 
2551
        /* old dquot */
2552
        prevdq = *IO_olddq;
2553
        ASSERT(prevdq);
2554
        ASSERT(prevdq != newdq);
2555
 
2556
        xfs_trans_mod_dquot(tp, prevdq,
2557
                            XFS_TRANS_DQ_BCOUNT,
2558
                            -(ip->i_d.di_nblocks));
2559
        xfs_trans_mod_dquot(tp, prevdq,
2560
                            XFS_TRANS_DQ_ICOUNT,
2561
                            -1);
2562
 
2563
        /* the sparkling new dquot */
2564
        xfs_trans_mod_dquot(tp, newdq,
2565
                            XFS_TRANS_DQ_BCOUNT,
2566
                            ip->i_d.di_nblocks);
2567
        xfs_trans_mod_dquot(tp, newdq,
2568
                            XFS_TRANS_DQ_ICOUNT,
2569
                            1);
2570
 
2571
        /*
2572
         * Take an extra reference, because the inode
2573
         * is going to keep this dquot pointer even
2574
         * after the trans_commit.
2575
         */
2576
        xfs_dqlock(newdq);
2577
        XFS_DQHOLD(newdq);
2578
        xfs_dqunlock(newdq);
2579
        *IO_olddq = newdq;
2580
 
2581
        return (prevdq);
2582
}
2583
 
2584
/*
2585
 * Quota reservations for setattr(AT_UID|AT_GID).
2586
 */
2587
int
2588
xfs_qm_vop_chown_reserve(
2589
        xfs_trans_t     *tp,
2590
        xfs_inode_t     *ip,
2591
        xfs_dquot_t     *udqp,
2592
        xfs_dquot_t     *gdqp,
2593
        uint            flags)
2594
{
2595
        int             error;
2596
        xfs_mount_t     *mp;
2597
        uint            delblks;
2598
        xfs_dquot_t     *unresudq, *unresgdq, *delblksudq, *delblksgdq;
2599
 
2600
        ASSERT(XFS_ISLOCKED_INODE(ip));
2601
        mp = ip->i_mount;
2602
        ASSERT(XFS_IS_QUOTA_RUNNING(mp));
2603
 
2604
        delblks = ip->i_delayed_blks;
2605
        delblksudq = delblksgdq = unresudq = unresgdq = NULL;
2606
 
2607
        if (XFS_IS_UQUOTA_ON(mp) && udqp &&
2608
            ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) {
2609
                delblksudq = udqp;
2610
                /*
2611
                 * If there are delayed allocation blocks, then we have to
2612
                 * unreserve those from the old dquot, and add them to the
2613
                 * new dquot.
2614
                 */
2615
                if (delblks) {
2616
                        ASSERT(ip->i_udquot);
2617
                        unresudq = ip->i_udquot;
2618
                }
2619
        }
2620
        if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp &&
2621
            ip->i_d.di_gid != INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) {
2622
                delblksgdq = gdqp;
2623
                if (delblks) {
2624
                        ASSERT(ip->i_gdquot);
2625
                        unresgdq = ip->i_gdquot;
2626
                }
2627
        }
2628
 
2629
        if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
2630
                                delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
2631
                                flags | XFS_QMOPT_RES_REGBLKS)))
2632
                return (error);
2633
 
2634
        /*
2635
         * Do the delayed blks reservations/unreservations now. Since, these
2636
         * are done without the help of a transaction, if a reservation fails
2637
         * its previous reservations won't be automatically undone by trans
2638
         * code. So, we have to do it manually here.
2639
         */
2640
        if (delblks) {
2641
                /*
2642
                 * Do the reservations first. Unreservation can't fail.
2643
                 */
2644
                ASSERT(delblksudq || delblksgdq);
2645
                ASSERT(unresudq || unresgdq);
2646
                if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
2647
                                delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
2648
                                flags | XFS_QMOPT_RES_REGBLKS)))
2649
                        return (error);
2650
                xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
2651
                                unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
2652
                                XFS_QMOPT_RES_REGBLKS);
2653
        }
2654
 
2655
        return (0);
2656
}
2657
 
2658
int
2659
xfs_qm_vop_rename_dqattach(
2660
        xfs_inode_t     **i_tab)
2661
{
2662
        xfs_inode_t     *ip;
2663
        int             i;
2664
        int             error;
2665
 
2666
        ip = i_tab[0];
2667
 
2668
        if (! XFS_IS_QUOTA_ON(ip->i_mount))
2669
                return (0);
2670
 
2671
        if (XFS_NOT_DQATTACHED(ip->i_mount, ip)) {
2672
                error = xfs_qm_dqattach(ip, 0);
2673
                if (error)
2674
                        return (error);
2675
        }
2676
        for (i = 1; (i < 4 && i_tab[i]); i++) {
2677
                /*
2678
                 * Watch out for duplicate entries in the table.
2679
                 */
2680
                if ((ip = i_tab[i]) != i_tab[i-1]) {
2681
                        if (XFS_NOT_DQATTACHED(ip->i_mount, ip)) {
2682
                                error = xfs_qm_dqattach(ip, 0);
2683
                                if (error)
2684
                                        return (error);
2685
                        }
2686
                }
2687
        }
2688
        return (0);
2689
}
2690
 
2691
void
2692
xfs_qm_vop_dqattach_and_dqmod_newinode(
2693
        xfs_trans_t     *tp,
2694
        xfs_inode_t     *ip,
2695
        xfs_dquot_t     *udqp,
2696
        xfs_dquot_t     *gdqp)
2697
{
2698
        if (!XFS_IS_QUOTA_ON(tp->t_mountp))
2699
                return;
2700
 
2701
        ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
2702
        ASSERT(XFS_IS_QUOTA_RUNNING(tp->t_mountp));
2703
 
2704
        if (udqp) {
2705
                xfs_dqlock(udqp);
2706
                XFS_DQHOLD(udqp);
2707
                xfs_dqunlock(udqp);
2708
                ASSERT(ip->i_udquot == NULL);
2709
                ip->i_udquot = udqp;
2710
                ASSERT(ip->i_d.di_uid == INT_GET(udqp->q_core.d_id, ARCH_CONVERT));
2711
                xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1);
2712
        }
2713
        if (gdqp) {
2714
                xfs_dqlock(gdqp);
2715
                XFS_DQHOLD(gdqp);
2716
                xfs_dqunlock(gdqp);
2717
                ASSERT(ip->i_gdquot == NULL);
2718
                ip->i_gdquot = gdqp;
2719
                ASSERT(ip->i_d.di_gid == INT_GET(gdqp->q_core.d_id, ARCH_CONVERT));
2720
                xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
2721
        }
2722
}
2723
 
2724
/* ------------- list stuff -----------------*/
2725
void
2726
xfs_qm_freelist_init(xfs_frlist_t *ql)
2727
{
2728
        ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql;
2729
        mutex_init(&ql->qh_lock, MUTEX_DEFAULT, "dqf");
2730
        ql->qh_version = 0;
2731
        ql->qh_nelems = 0;
2732
}
2733
 
2734
void
2735
xfs_qm_freelist_destroy(xfs_frlist_t *ql)
2736
{
2737
        xfs_dquot_t     *dqp, *nextdqp;
2738
 
2739
        mutex_lock(&ql->qh_lock, PINOD);
2740
        for (dqp = ql->qh_next;
2741
             dqp != (xfs_dquot_t *)ql; ) {
2742
                xfs_dqlock(dqp);
2743
                nextdqp = dqp->dq_flnext;
2744
#ifdef QUOTADEBUG
2745
                cmn_err(CE_DEBUG, "FREELIST destroy 0x%p", dqp);
2746
#endif
2747
                XQM_FREELIST_REMOVE(dqp);
2748
                xfs_dqunlock(dqp);
2749
                xfs_qm_dqdestroy(dqp);
2750
                dqp = nextdqp;
2751
        }
2752
        /*
2753
         * Don't bother about unlocking.
2754
         */
2755
        mutex_destroy(&ql->qh_lock);
2756
 
2757
        ASSERT(ql->qh_nelems == 0);
2758
}
2759
 
2760
void
2761
xfs_qm_freelist_insert(xfs_frlist_t *ql, xfs_dquot_t *dq)
2762
{
2763
        dq->dq_flnext = ql->qh_next;
2764
        dq->dq_flprev = (xfs_dquot_t *)ql;
2765
        ql->qh_next = dq;
2766
        dq->dq_flnext->dq_flprev = dq;
2767
        xfs_Gqm->qm_dqfreelist.qh_nelems++;
2768
        xfs_Gqm->qm_dqfreelist.qh_version++;
2769
}
2770
 
2771
void
2772
xfs_qm_freelist_unlink(xfs_dquot_t *dq)
2773
{
2774
        xfs_dquot_t *next = dq->dq_flnext;
2775
        xfs_dquot_t *prev = dq->dq_flprev;
2776
 
2777
        next->dq_flprev = prev;
2778
        prev->dq_flnext = next;
2779
        dq->dq_flnext = dq->dq_flprev = dq;
2780
        xfs_Gqm->qm_dqfreelist.qh_nelems--;
2781
        xfs_Gqm->qm_dqfreelist.qh_version++;
2782
}
2783
 
2784
void
2785
xfs_qm_freelist_append(xfs_frlist_t *ql, xfs_dquot_t *dq)
2786
{
2787
        xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq);
2788
}
2789
 
2790
int
2791
xfs_qm_dqhashlock_nowait(
2792
        xfs_dquot_t *dqp)
2793
{
2794
        int locked;
2795
 
2796
        locked = mutex_trylock(&((dqp)->q_hash->qh_lock));
2797
        return (locked);
2798
}
2799
 
2800
int
2801
xfs_qm_freelist_lock_nowait(
2802
        xfs_qm_t *xqm)
2803
{
2804
        int locked;
2805
 
2806
        locked = mutex_trylock(&(xqm->qm_dqfreelist.qh_lock));
2807
        return (locked);
2808
}
2809
 
2810
int
2811
xfs_qm_mplist_nowait(
2812
        xfs_mount_t     *mp)
2813
{
2814
        int locked;
2815
 
2816
        ASSERT(mp->m_quotainfo);
2817
        locked = mutex_trylock(&(XFS_QI_MPLLOCK(mp)));
2818
        return (locked);
2819
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.