xfs_dquot.c 31.8 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
Linus Torvalds's avatar
Linus Torvalds committed
2
/*
3 4
 * Copyright (c) 2000-2003 Silicon Graphics, Inc.
 * All Rights Reserved.
Linus Torvalds's avatar
Linus Torvalds committed
5 6 7
 */
#include "xfs.h"
#include "xfs_fs.h"
8
#include "xfs_format.h"
9
#include "xfs_log_format.h"
10
#include "xfs_shared.h"
11
#include "xfs_trans_resv.h"
12
#include "xfs_bit.h"
Linus Torvalds's avatar
Linus Torvalds committed
13
#include "xfs_mount.h"
14
#include "xfs_defer.h"
Linus Torvalds's avatar
Linus Torvalds committed
15 16
#include "xfs_inode.h"
#include "xfs_bmap.h"
17 18
#include "xfs_quota.h"
#include "xfs_trans.h"
Linus Torvalds's avatar
Linus Torvalds committed
19 20 21 22
#include "xfs_buf_item.h"
#include "xfs_trans_space.h"
#include "xfs_trans_priv.h"
#include "xfs_qm.h"
23
#include "xfs_trace.h"
24
#include "xfs_log.h"
25
#include "xfs_bmap_btree.h"
Linus Torvalds's avatar
Linus Torvalds committed
26 27

/*
28 29 30
 * Lock order:
 *
 * ip->i_lock
31
 *   qi->qi_tree_lock
32 33 34
 *     dquot->q_qlock (xfs_dqlock() and friends)
 *       dquot->q_flush (xfs_dqflock() and friends)
 *       qi->qi_lru_lock
35 36 37 38
 *
 * If two dquots need to be locked the order is user before group/project,
 * otherwise by the lowest id first, see xfs_dqlock2.
 */
Linus Torvalds's avatar
Linus Torvalds committed
39

40 41 42
struct kmem_zone		*xfs_qm_dqtrxzone;
static struct kmem_zone		*xfs_qm_dqzone;

43 44
static struct lock_class_key xfs_dquot_group_class;
static struct lock_class_key xfs_dquot_project_class;
45

Linus Torvalds's avatar
Linus Torvalds committed
46 47 48 49 50
/*
 * This is called to free all the memory associated with a dquot
 */
void
xfs_qm_dqdestroy(
51
	struct xfs_dquot	*dqp)
Linus Torvalds's avatar
Linus Torvalds committed
52
{
53
	ASSERT(list_empty(&dqp->q_lru));
Linus Torvalds's avatar
Linus Torvalds committed
54

55
	kmem_free(dqp->q_logitem.qli_item.li_lv_shadow);
Linus Torvalds's avatar
Linus Torvalds committed
56
	mutex_destroy(&dqp->q_qlock);
57

58
	XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot);
59
	kmem_cache_free(xfs_qm_dqzone, dqp);
Linus Torvalds's avatar
Linus Torvalds committed
60 61 62 63 64 65 66 67 68
}

/*
 * If default limits are in force, push them into the dquot now.
 * We overwrite the dquot limits only if they are zero and this
 * is not the root dquot.
 */
void
xfs_qm_adjust_dqlimits(
69 70
	struct xfs_mount	*mp,
	struct xfs_dquot	*dq)
Linus Torvalds's avatar
Linus Torvalds committed
71
{
72 73
	struct xfs_quotainfo	*q = mp->m_quotainfo;
	struct xfs_disk_dquot	*d = &dq->q_core;
74
	struct xfs_def_quota	*defq;
75
	int			prealloc = 0;
Linus Torvalds's avatar
Linus Torvalds committed
76 77

	ASSERT(d->d_id);
78
	defq = xfs_get_defquota(q, xfs_dquot_type(dq));
Linus Torvalds's avatar
Linus Torvalds committed
79

80 81
	if (defq->bsoftlimit && !d->d_blk_softlimit) {
		d->d_blk_softlimit = cpu_to_be64(defq->bsoftlimit);
82 83
		prealloc = 1;
	}
84 85
	if (defq->bhardlimit && !d->d_blk_hardlimit) {
		d->d_blk_hardlimit = cpu_to_be64(defq->bhardlimit);
86 87
		prealloc = 1;
	}
88 89 90 91 92 93 94 95
	if (defq->isoftlimit && !d->d_ino_softlimit)
		d->d_ino_softlimit = cpu_to_be64(defq->isoftlimit);
	if (defq->ihardlimit && !d->d_ino_hardlimit)
		d->d_ino_hardlimit = cpu_to_be64(defq->ihardlimit);
	if (defq->rtbsoftlimit && !d->d_rtb_softlimit)
		d->d_rtb_softlimit = cpu_to_be64(defq->rtbsoftlimit);
	if (defq->rtbhardlimit && !d->d_rtb_hardlimit)
		d->d_rtb_hardlimit = cpu_to_be64(defq->rtbhardlimit);
96 97 98

	if (prealloc)
		xfs_dquot_set_prealloc_limits(dq);
Linus Torvalds's avatar
Linus Torvalds committed
99 100 101 102 103 104 105 106 107 108 109
}

/*
 * Check the limits and timers of a dquot and start or reset timers
 * if necessary.
 * This gets called even when quota enforcement is OFF, which makes our
 * life a little less complicated. (We just don't reject any quota
 * reservations in that case, when enforcement is off).
 * We also return 0 as the values of the timers in Q_GETQUOTA calls, when
 * enforcement's off.
 * In contrast, warnings are a little different in that they don't
110 111 112
 * 'automatically' get started when limits get exceeded.  They do
 * get reset to zero, however, when we find the count to be under
 * the soft limit (they are only ever set non-zero via userspace).
Linus Torvalds's avatar
Linus Torvalds committed
113 114 115
 */
void
xfs_qm_adjust_dqtimers(
116
	struct xfs_mount	*mp,
117
	struct xfs_dquot	*dq)
Linus Torvalds's avatar
Linus Torvalds committed
118
{
119
	struct xfs_quotainfo	*qi = mp->m_quotainfo;
120
	struct xfs_disk_dquot	*d = &dq->q_core;
121 122
	struct xfs_def_quota	*defq;

Linus Torvalds's avatar
Linus Torvalds committed
123
	ASSERT(d->d_id);
124
	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
Linus Torvalds's avatar
Linus Torvalds committed
125

126
#ifdef DEBUG
127 128 129 130 131 132 133 134 135
	if (d->d_blk_hardlimit)
		ASSERT(be64_to_cpu(d->d_blk_softlimit) <=
		       be64_to_cpu(d->d_blk_hardlimit));
	if (d->d_ino_hardlimit)
		ASSERT(be64_to_cpu(d->d_ino_softlimit) <=
		       be64_to_cpu(d->d_ino_hardlimit));
	if (d->d_rtb_hardlimit)
		ASSERT(be64_to_cpu(d->d_rtb_softlimit) <=
		       be64_to_cpu(d->d_rtb_hardlimit));
Linus Torvalds's avatar
Linus Torvalds committed
136
#endif
137

Linus Torvalds's avatar
Linus Torvalds committed
138
	if (!d->d_btimer) {
139
		if ((d->d_blk_softlimit &&
140
		     (be64_to_cpu(d->d_bcount) >
141 142
		      be64_to_cpu(d->d_blk_softlimit))) ||
		    (d->d_blk_hardlimit &&
143
		     (be64_to_cpu(d->d_bcount) >
144
		      be64_to_cpu(d->d_blk_hardlimit)))) {
145
			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
146
					defq->btimelimit);
147 148
		} else {
			d->d_bwarns = 0;
Linus Torvalds's avatar
Linus Torvalds committed
149 150 151
		}
	} else {
		if ((!d->d_blk_softlimit ||
152
		     (be64_to_cpu(d->d_bcount) <=
153
		      be64_to_cpu(d->d_blk_softlimit))) &&
Linus Torvalds's avatar
Linus Torvalds committed
154
		    (!d->d_blk_hardlimit ||
155
		    (be64_to_cpu(d->d_bcount) <=
156
		     be64_to_cpu(d->d_blk_hardlimit)))) {
Linus Torvalds's avatar
Linus Torvalds committed
157 158 159 160 161
			d->d_btimer = 0;
		}
	}

	if (!d->d_itimer) {
162
		if ((d->d_ino_softlimit &&
163
		     (be64_to_cpu(d->d_icount) >
164 165
		      be64_to_cpu(d->d_ino_softlimit))) ||
		    (d->d_ino_hardlimit &&
166
		     (be64_to_cpu(d->d_icount) >
167
		      be64_to_cpu(d->d_ino_hardlimit)))) {
168
			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
169
					defq->itimelimit);
170 171
		} else {
			d->d_iwarns = 0;
Linus Torvalds's avatar
Linus Torvalds committed
172 173 174
		}
	} else {
		if ((!d->d_ino_softlimit ||
175
		     (be64_to_cpu(d->d_icount) <=
176
		      be64_to_cpu(d->d_ino_softlimit)))  &&
Linus Torvalds's avatar
Linus Torvalds committed
177
		    (!d->d_ino_hardlimit ||
178
		     (be64_to_cpu(d->d_icount) <=
179
		      be64_to_cpu(d->d_ino_hardlimit)))) {
Linus Torvalds's avatar
Linus Torvalds committed
180 181 182 183 184
			d->d_itimer = 0;
		}
	}

	if (!d->d_rtbtimer) {
185
		if ((d->d_rtb_softlimit &&
186
		     (be64_to_cpu(d->d_rtbcount) >
187 188
		      be64_to_cpu(d->d_rtb_softlimit))) ||
		    (d->d_rtb_hardlimit &&
189
		     (be64_to_cpu(d->d_rtbcount) >
190
		      be64_to_cpu(d->d_rtb_hardlimit)))) {
191
			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
192
					defq->rtbtimelimit);
193 194
		} else {
			d->d_rtbwarns = 0;
Linus Torvalds's avatar
Linus Torvalds committed
195 196 197
		}
	} else {
		if ((!d->d_rtb_softlimit ||
198
		     (be64_to_cpu(d->d_rtbcount) <=
199
		      be64_to_cpu(d->d_rtb_softlimit))) &&
Linus Torvalds's avatar
Linus Torvalds committed
200
		    (!d->d_rtb_hardlimit ||
201
		     (be64_to_cpu(d->d_rtbcount) <=
202
		      be64_to_cpu(d->d_rtb_hardlimit)))) {
Linus Torvalds's avatar
Linus Torvalds committed
203 204 205 206 207 208 209 210 211 212
			d->d_rtbtimer = 0;
		}
	}
}

/*
 * initialize a buffer full of dquots and log the whole thing
 */
STATIC void
xfs_qm_init_dquot_blk(
213 214 215 216 217
	struct xfs_trans	*tp,
	struct xfs_mount	*mp,
	xfs_dqid_t		id,
	uint			type,
	struct xfs_buf		*bp)
Linus Torvalds's avatar
Linus Torvalds committed
218
{
219
	struct xfs_quotainfo	*q = mp->m_quotainfo;
220 221 222 223 224
	struct xfs_dqblk	*d;
	xfs_dqid_t		curid;
	unsigned int		qflag;
	unsigned int		blftype;
	int			i;
Linus Torvalds's avatar
Linus Torvalds committed
225 226

	ASSERT(tp);
227
	ASSERT(xfs_buf_islocked(bp));
Linus Torvalds's avatar
Linus Torvalds committed
228

229
	d = bp->b_addr;
Linus Torvalds's avatar
Linus Torvalds committed
230 231 232 233

	/*
	 * ID of the first dquot in the block - id's are zero based.
	 */
234 235
	curid = id - (id % q->qi_dqperchunk);
	memset(d, 0, BBTOB(q->qi_dqchunklen));
236 237 238 239 240
	for (i = 0; i < q->qi_dqperchunk; i++, d++, curid++) {
		d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC);
		d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
		d->dd_diskdq.d_id = cpu_to_be32(curid);
		d->dd_diskdq.d_flags = type;
Dave Chinner's avatar
Dave Chinner committed
241
		if (xfs_sb_version_hascrc(&mp->m_sb)) {
242
			uuid_copy(&d->dd_uuid, &mp->m_sb.sb_meta_uuid);
Dave Chinner's avatar
Dave Chinner committed
243 244 245
			xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
					 XFS_DQUOT_CRC_OFF);
		}
246 247
	}

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
	if (type & XFS_DQ_USER) {
		qflag = XFS_UQUOTA_CHKD;
		blftype = XFS_BLF_UDQUOT_BUF;
	} else if (type & XFS_DQ_PROJ) {
		qflag = XFS_PQUOTA_CHKD;
		blftype = XFS_BLF_PDQUOT_BUF;
	} else {
		qflag = XFS_GQUOTA_CHKD;
		blftype = XFS_BLF_GDQUOT_BUF;
	}

	xfs_trans_dquot_buf(tp, bp, blftype);

	/*
	 * quotacheck uses delayed writes to update all the dquots on disk in an
	 * efficient manner instead of logging the individual dquot changes as
	 * they are made. However if we log the buffer allocated here and crash
	 * after quotacheck while the logged initialisation is still in the
	 * active region of the log, log recovery can replay the dquot buffer
	 * initialisation over the top of the checked dquots and corrupt quota
	 * accounting.
	 *
	 * To avoid this problem, quotacheck cannot log the initialised buffer.
	 * We must still dirty the buffer and write it back before the
	 * allocation transaction clears the log. Therefore, mark the buffer as
	 * ordered instead of logging it directly. This is safe for quotacheck
	 * because it detects and repairs allocated but initialized dquot blocks
	 * in the quota inodes.
	 */
	if (!(mp->m_qflags & qflag))
		xfs_trans_ordered_buf(tp, bp);
	else
		xfs_trans_log_buf(tp, bp, 0, BBTOB(q->qi_dqchunklen) - 1);
Linus Torvalds's avatar
Linus Torvalds committed
281 282
}

283 284 285 286 287 288 289 290
/*
 * Initialize the dynamic speculative preallocation thresholds. The lo/hi
 * watermarks correspond to the soft and hard limits by default. If a soft limit
 * is not specified, we use 95% of the hard limit.
 */
void
xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp)
{
291
	uint64_t space;
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308

	dqp->q_prealloc_hi_wmark = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
	dqp->q_prealloc_lo_wmark = be64_to_cpu(dqp->q_core.d_blk_softlimit);
	if (!dqp->q_prealloc_lo_wmark) {
		dqp->q_prealloc_lo_wmark = dqp->q_prealloc_hi_wmark;
		do_div(dqp->q_prealloc_lo_wmark, 100);
		dqp->q_prealloc_lo_wmark *= 95;
	}

	space = dqp->q_prealloc_hi_wmark;

	do_div(space, 100);
	dqp->q_low_space[XFS_QLOWSP_1_PCNT] = space;
	dqp->q_low_space[XFS_QLOWSP_3_PCNT] = space * 3;
	dqp->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5;
}

Linus Torvalds's avatar
Linus Torvalds committed
309
/*
310
 * Ensure that the given in-core dquot has a buffer on disk backing it, and
311 312
 * return the buffer locked and held. This is called when the bmapi finds a
 * hole.
Linus Torvalds's avatar
Linus Torvalds committed
313 314
 */
STATIC int
315 316 317 318
xfs_dquot_disk_alloc(
	struct xfs_trans	**tpp,
	struct xfs_dquot	*dqp,
	struct xfs_buf		**bpp)
Linus Torvalds's avatar
Linus Torvalds committed
319
{
320
	struct xfs_bmbt_irec	map;
321 322
	struct xfs_trans	*tp = *tpp;
	struct xfs_mount	*mp = tp->t_mountp;
323 324 325 326
	struct xfs_buf		*bp;
	struct xfs_inode	*quotip = xfs_quota_inode(mp, dqp->dq_flags);
	int			nmaps = 1;
	int			error;
327 328

	trace_xfs_dqalloc(dqp);
Linus Torvalds's avatar
Linus Torvalds committed
329 330

	xfs_ilock(quotip, XFS_ILOCK_EXCL);
331
	if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) {
332 333 334 335
		/*
		 * Return if this type of quotas is turned off while we didn't
		 * have an inode lock
		 */
Linus Torvalds's avatar
Linus Torvalds committed
336
		xfs_iunlock(quotip, XFS_ILOCK_EXCL);
337
		return -ESRCH;
Linus Torvalds's avatar
Linus Torvalds committed
338 339
	}

340
	/* Create the block mapping. */
341 342
	xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL);
	error = xfs_bmapi_write(tp, quotip, dqp->q_fileoffset,
343 344
			XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, 0, &map,
			&nmaps);
345
	if (error)
346
		return error;
Linus Torvalds's avatar
Linus Torvalds committed
347 348 349 350 351 352 353 354 355 356 357
	ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
	ASSERT(nmaps == 1);
	ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
	       (map.br_startblock != HOLESTARTBLOCK));

	/*
	 * Keep track of the blkno to save a lookup later
	 */
	dqp->q_blkno = XFS_FSB_TO_DADDR(mp, map.br_startblock);

	/* now we can just get the buffer (there's nothing to read yet) */
358 359 360 361
	error = xfs_trans_get_buf(tp, mp->m_ddev_targp, dqp->q_blkno,
			mp->m_quotainfo->qi_dqchunklen, 0, &bp);
	if (error)
		return error;
362
	bp->b_ops = &xfs_dquot_buf_ops;
363

Linus Torvalds's avatar
Linus Torvalds committed
364 365 366 367
	/*
	 * Make a chunk of dquots out of this buffer and log
	 * the entire thing.
	 */
368
	xfs_qm_init_dquot_blk(tp, mp, be32_to_cpu(dqp->q_core.d_id),
369
			      dqp->dq_flags & XFS_DQ_ALLTYPES, bp);
370
	xfs_buf_set_ref(bp, XFS_DQUOT_REF);
Linus Torvalds's avatar
Linus Torvalds committed
371

372
	/*
373 374 375 376 377 378 379 380
	 * Hold the buffer and join it to the dfops so that we'll still own
	 * the buffer when we return to the caller.  The buffer disposal on
	 * error must be paid attention to very carefully, as it has been
	 * broken since commit efa092f3d4c6 "[XFS] Fixes a bug in the quota
	 * code when allocating a new dquot record" in 2005, and the later
	 * conversion to xfs_defer_ops in commit 310a75a3c6c747 failed to keep
	 * the buffer locked across the _defer_finish call.  We can now do
	 * this correctly with xfs_defer_bjoin.
381
	 *
382 383
	 * Above, we allocated a disk block for the dquot information and used
	 * get_buf to initialize the dquot. If the _defer_finish fails, the old
384 385
	 * transaction is gone but the new buffer is not joined or held to any
	 * transaction, so we must _buf_relse it.
386
	 *
387
	 * If everything succeeds, the caller of this function is returned a
388
	 * buffer that is locked and held to the transaction.  The caller
389
	 * is responsible for unlocking any buffer passed back, either
390 391
	 * manually or by committing the transaction.  On error, the buffer is
	 * released and not passed back.
392
	 */
393
	xfs_trans_bhold(tp, bp);
394
	error = xfs_defer_finish(tpp);
395
	if (error) {
396 397
		xfs_trans_bhold_release(*tpp, bp);
		xfs_trans_brelse(*tpp, bp);
398
		return error;
399
	}
400
	*bpp = bp;
Linus Torvalds's avatar
Linus Torvalds committed
401 402
	return 0;
}
403

Linus Torvalds's avatar
Linus Torvalds committed
404
/*
405 406
 * Read in the in-core dquot's on-disk metadata and return the buffer.
 * Returns ENOENT to signal a hole.
Linus Torvalds's avatar
Linus Torvalds committed
407 408
 */
STATIC int
409 410 411 412
xfs_dquot_disk_read(
	struct xfs_mount	*mp,
	struct xfs_dquot	*dqp,
	struct xfs_buf		**bpp)
Linus Torvalds's avatar
Linus Torvalds committed
413
{
414 415
	struct xfs_bmbt_irec	map;
	struct xfs_buf		*bp;
416
	struct xfs_inode	*quotip = xfs_quota_inode(mp, dqp->dq_flags);
417
	uint			lock_mode;
418 419
	int			nmaps = 1;
	int			error;
Linus Torvalds's avatar
Linus Torvalds committed
420

421
	lock_mode = xfs_ilock_data_map_shared(quotip);
422
	if (!xfs_this_quota_on(mp, dqp->dq_flags)) {
Linus Torvalds's avatar
Linus Torvalds committed
423
		/*
424 425
		 * Return if this type of quotas is turned off while we
		 * didn't have the quota inode lock.
Linus Torvalds's avatar
Linus Torvalds committed
426
		 */
427
		xfs_iunlock(quotip, lock_mode);
428
		return -ESRCH;
429 430 431 432 433
	}

	/*
	 * Find the block map; no allocations yet
	 */
434
	error = xfs_bmapi_read(quotip, dqp->q_fileoffset,
435
			XFS_DQUOT_CLUSTER_SIZE_FSB, &map, &nmaps, 0);
436
	xfs_iunlock(quotip, lock_mode);
437 438 439 440
	if (error)
		return error;

	ASSERT(nmaps == 1);
441 442 443 444 445 446
	ASSERT(map.br_blockcount >= 1);
	ASSERT(map.br_startblock != DELAYSTARTBLOCK);
	if (map.br_startblock == HOLESTARTBLOCK)
		return -ENOENT;

	trace_xfs_dqtobp_read(dqp);
447 448

	/*
449 450
	 * store the blkno etc so that we don't have to do the
	 * mapping all the time
451
	 */
452
	dqp->q_blkno = XFS_FSB_TO_DADDR(mp, map.br_startblock);
Linus Torvalds's avatar
Linus Torvalds committed
453

454 455 456 457 458 459
	error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno,
			mp->m_quotainfo->qi_dqchunklen, 0, &bp,
			&xfs_dquot_buf_ops);
	if (error) {
		ASSERT(bp == NULL);
		return error;
Linus Torvalds's avatar
Linus Torvalds committed
460 461
	}

462
	ASSERT(xfs_buf_islocked(bp));
463 464
	xfs_buf_set_ref(bp, XFS_DQUOT_REF);
	*bpp = bp;
Linus Torvalds's avatar
Linus Torvalds committed
465

Eric Sandeen's avatar
Eric Sandeen committed
466
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
467 468
}

469 470 471
/* Allocate and initialize everything we need for an incore dquot. */
STATIC struct xfs_dquot *
xfs_dquot_alloc(
Christoph Hellwig's avatar
Christoph Hellwig committed
472 473
	struct xfs_mount	*mp,
	xfs_dqid_t		id,
474
	uint			type)
Linus Torvalds's avatar
Linus Torvalds committed
475
{
Christoph Hellwig's avatar
Christoph Hellwig committed
476
	struct xfs_dquot	*dqp;
477

478
	dqp = kmem_zone_zalloc(xfs_qm_dqzone, 0);
479 480 481 482

	dqp->dq_flags = type;
	dqp->q_core.d_id = cpu_to_be32(id);
	dqp->q_mount = mp;
483
	INIT_LIST_HEAD(&dqp->q_lru);
484 485
	mutex_init(&dqp->q_qlock);
	init_waitqueue_head(&dqp->q_pinwait);
486 487 488 489 490 491
	dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk;
	/*
	 * Offset of dquot in the (fixed sized) dquot chunk.
	 */
	dqp->q_bufoffset = (id % mp->m_quotainfo->qi_dqperchunk) *
			sizeof(xfs_dqblk_t);
492 493 494 495 496 497 498 499 500 501 502 503 504

	/*
	 * Because we want to use a counting completion, complete
	 * the flush completion once to allow a single access to
	 * the flush completion without blocking.
	 */
	init_completion(&dqp->q_flush);
	complete(&dqp->q_flush);

	/*
	 * Make sure group quotas have a different lock class than user
	 * quotas.
	 */
505 506 507 508 509 510 511 512 513 514 515 516 517 518
	switch (type) {
	case XFS_DQ_USER:
		/* uses the default lock class */
		break;
	case XFS_DQ_GROUP:
		lockdep_set_class(&dqp->q_qlock, &xfs_dquot_group_class);
		break;
	case XFS_DQ_PROJ:
		lockdep_set_class(&dqp->q_qlock, &xfs_dquot_project_class);
		break;
	default:
		ASSERT(0);
		break;
	}
519

520 521
	xfs_qm_dquot_logitem_init(dqp);

522
	XFS_STATS_INC(mp, xs_qm_dquot);
523 524 525 526 527 528 529
	return dqp;
}

/* Copy the in-core quota fields in from the on-disk buffer. */
STATIC void
xfs_dquot_from_disk(
	struct xfs_dquot	*dqp,
530
	struct xfs_buf		*bp)
531
{
532 533
	struct xfs_disk_dquot	*ddqp = bp->b_addr + dqp->q_bufoffset;

534
	/* copy everything from disk dquot to the incore dquot */
535
	memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot));
536 537 538 539 540 541 542 543 544 545 546 547

	/*
	 * Reservation counters are defined as reservation plus current usage
	 * to avoid having to add every time.
	 */
	dqp->q_res_bcount = be64_to_cpu(ddqp->d_bcount);
	dqp->q_res_icount = be64_to_cpu(ddqp->d_icount);
	dqp->q_res_rtbcount = be64_to_cpu(ddqp->d_rtbcount);

	/* initialize the dquot speculative prealloc thresholds */
	xfs_dquot_set_prealloc_limits(dqp);
}
Linus Torvalds's avatar
Linus Torvalds committed
548

549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
/* Allocate and initialize the dquot buffer for this in-core dquot. */
static int
xfs_qm_dqread_alloc(
	struct xfs_mount	*mp,
	struct xfs_dquot	*dqp,
	struct xfs_buf		**bpp)
{
	struct xfs_trans	*tp;
	int			error;

	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_dqalloc,
			XFS_QM_DQALLOC_SPACE_RES(mp), 0, 0, &tp);
	if (error)
		goto err;

564
	error = xfs_dquot_disk_alloc(&tp, dqp, bpp);
565 566 567 568 569 570 571 572 573
	if (error)
		goto err_cancel;

	error = xfs_trans_commit(tp);
	if (error) {
		/*
		 * Buffer was held to the transaction, so we have to unlock it
		 * manually here because we're not passing it back.
		 */
574 575
		xfs_buf_relse(*bpp);
		*bpp = NULL;
576 577 578 579 580 581 582 583 584 585
		goto err;
	}
	return 0;

err_cancel:
	xfs_trans_cancel(tp);
err:
	return error;
}

586 587
/*
 * Read in the ondisk dquot using dqtobp() then copy it to an incore version,
588 589
 * and release the buffer immediately.  If @can_alloc is true, fill any
 * holes in the on-disk metadata.
590
 */
591
static int
592 593 594 595
xfs_qm_dqread(
	struct xfs_mount	*mp,
	xfs_dqid_t		id,
	uint			type,
596
	bool			can_alloc,
597
	struct xfs_dquot	**dqpp)
598 599 600 601 602 603
{
	struct xfs_dquot	*dqp;
	struct xfs_buf		*bp;
	int			error;

	dqp = xfs_dquot_alloc(mp, id, type);
604 605
	trace_xfs_dqread(dqp);

606 607
	/* Try to read the buffer, allocating if necessary. */
	error = xfs_dquot_disk_read(mp, dqp, &bp);
608
	if (error == -ENOENT && can_alloc)
609 610 611
		error = xfs_qm_dqread_alloc(mp, dqp, &bp);
	if (error)
		goto err;
Linus Torvalds's avatar
Linus Torvalds committed
612 613

	/*
614 615 616 617
	 * At this point we should have a clean locked buffer.  Copy the data
	 * to the incore dquot and release the buffer since the incore dquot
	 * has its own locking protocol so we needn't tie up the buffer any
	 * further.
Linus Torvalds's avatar
Linus Torvalds committed
618
	 */
619
	ASSERT(xfs_buf_islocked(bp));
620
	xfs_dquot_from_disk(dqp, bp);
Linus Torvalds's avatar
Linus Torvalds committed
621

622 623
	xfs_buf_relse(bp);
	*dqpp = dqp;
Christoph Hellwig's avatar
Christoph Hellwig committed
624
	return error;
Linus Torvalds's avatar
Linus Torvalds committed
625

626 627
err:
	trace_xfs_dqread_fail(dqp);
Linus Torvalds's avatar
Linus Torvalds committed
628
	xfs_qm_dqdestroy(dqp);
629
	*dqpp = NULL;
Christoph Hellwig's avatar
Christoph Hellwig committed
630
	return error;
Linus Torvalds's avatar
Linus Torvalds committed
631 632
}

633 634 635 636 637
/*
 * Advance to the next id in the current chunk, or if at the
 * end of the chunk, skip ahead to first id in next allocated chunk
 * using the SEEK_DATA interface.
 */
Eryu Guan's avatar
Eryu Guan committed
638
static int
639
xfs_dq_get_next_id(
640
	struct xfs_mount	*mp,
641
	uint			type,
642
	xfs_dqid_t		*id)
643
{
644 645 646 647
	struct xfs_inode	*quotip = xfs_quota_inode(mp, type);
	xfs_dqid_t		next_id = *id + 1; /* simple advance */
	uint			lock_flags;
	struct xfs_bmbt_irec	got;
648
	struct xfs_iext_cursor	cur;
649 650 651
	xfs_fsblock_t		start;
	int			error = 0;

652 653 654 655
	/* If we'd wrap past the max ID, stop */
	if (next_id < *id)
		return -ENOENT;

656 657 658 659 660 661 662 663 664
	/* If new ID is within the current chunk, advancing it sufficed */
	if (next_id % mp->m_quotainfo->qi_dqperchunk) {
		*id = next_id;
		return 0;
	}

	/* Nope, next_id is now past the current chunk, so find the next one */
	start = (xfs_fsblock_t)next_id / mp->m_quotainfo->qi_dqperchunk;

665 666 667 668 669 670
	lock_flags = xfs_ilock_data_map_shared(quotip);
	if (!(quotip->i_df.if_flags & XFS_IFEXTENTS)) {
		error = xfs_iread_extents(NULL, quotip, XFS_DATA_FORK);
		if (error)
			return error;
	}
671

672
	if (xfs_iext_lookup_extent(quotip, &quotip->i_df, start, &cur, &got)) {
673 674 675
		/* contiguous chunk, bump startoff for the id calculation */
		if (got.br_startoff < start)
			got.br_startoff = start;
676
		*id = got.br_startoff * mp->m_quotainfo->qi_dqperchunk;
677
	} else {
678
		error = -ENOENT;
679 680
	}

681
	xfs_iunlock(quotip, lock_flags);
682

683
	return error;
684 685
}

686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760
/*
 * Look up the dquot in the in-core cache.  If found, the dquot is returned
 * locked and ready to go.
 */
static struct xfs_dquot *
xfs_qm_dqget_cache_lookup(
	struct xfs_mount	*mp,
	struct xfs_quotainfo	*qi,
	struct radix_tree_root	*tree,
	xfs_dqid_t		id)
{
	struct xfs_dquot	*dqp;

restart:
	mutex_lock(&qi->qi_tree_lock);
	dqp = radix_tree_lookup(tree, id);
	if (!dqp) {
		mutex_unlock(&qi->qi_tree_lock);
		XFS_STATS_INC(mp, xs_qm_dqcachemisses);
		return NULL;
	}

	xfs_dqlock(dqp);
	if (dqp->dq_flags & XFS_DQ_FREEING) {
		xfs_dqunlock(dqp);
		mutex_unlock(&qi->qi_tree_lock);
		trace_xfs_dqget_freeing(dqp);
		delay(1);
		goto restart;
	}

	dqp->q_nrefs++;
	mutex_unlock(&qi->qi_tree_lock);

	trace_xfs_dqget_hit(dqp);
	XFS_STATS_INC(mp, xs_qm_dqcachehits);
	return dqp;
}

/*
 * Try to insert a new dquot into the in-core cache.  If an error occurs the
 * caller should throw away the dquot and start over.  Otherwise, the dquot
 * is returned locked (and held by the cache) as if there had been a cache
 * hit.
 */
static int
xfs_qm_dqget_cache_insert(
	struct xfs_mount	*mp,
	struct xfs_quotainfo	*qi,
	struct radix_tree_root	*tree,
	xfs_dqid_t		id,
	struct xfs_dquot	*dqp)
{
	int			error;

	mutex_lock(&qi->qi_tree_lock);
	error = radix_tree_insert(tree, id, dqp);
	if (unlikely(error)) {
		/* Duplicate found!  Caller must try again. */
		WARN_ON(error != -EEXIST);
		mutex_unlock(&qi->qi_tree_lock);
		trace_xfs_dqget_dup(dqp);
		return error;
	}

	/* Return a locked dquot to the caller, with a reference taken. */
	xfs_dqlock(dqp);
	dqp->q_nrefs = 1;

	qi->qi_dquots++;
	mutex_unlock(&qi->qi_tree_lock);

	return 0;
}

761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
/* Check our input parameters. */
static int
xfs_qm_dqget_checks(
	struct xfs_mount	*mp,
	uint			type)
{
	if (WARN_ON_ONCE(!XFS_IS_QUOTA_RUNNING(mp)))
		return -ESRCH;

	switch (type) {
	case XFS_DQ_USER:
		if (!XFS_IS_UQUOTA_ON(mp))
			return -ESRCH;
		return 0;
	case XFS_DQ_GROUP:
		if (!XFS_IS_GQUOTA_ON(mp))
			return -ESRCH;
		return 0;
	case XFS_DQ_PROJ:
		if (!XFS_IS_PQUOTA_ON(mp))
			return -ESRCH;
		return 0;
	default:
		WARN_ON_ONCE(0);
		return -EINVAL;
	}
}

Linus Torvalds's avatar
Linus Torvalds committed
789
/*
790 791
 * Given the file system, id, and type (UDQUOT/GDQUOT), return a a locked
 * dquot, doing an allocation (if requested) as needed.
Linus Torvalds's avatar
Linus Torvalds committed
792 793 794
 */
int
xfs_qm_dqget(
795 796 797
	struct xfs_mount	*mp,
	xfs_dqid_t		id,
	uint			type,
798
	bool			can_alloc,
799
	struct xfs_dquot	**O_dqpp)
Linus Torvalds's avatar
Linus Torvalds committed
800
{
801
	struct xfs_quotainfo	*qi = mp->m_quotainfo;
802
	struct radix_tree_root	*tree = xfs_dquot_tree(qi, type);
803 804
	struct xfs_dquot	*dqp;
	int			error;
Linus Torvalds's avatar
Linus Torvalds committed
805

806 807 808
	error = xfs_qm_dqget_checks(mp, type);
	if (error)
		return error;
Linus Torvalds's avatar
Linus Torvalds committed
809

810 811 812 813 814 815 816
restart:
	dqp = xfs_qm_dqget_cache_lookup(mp, qi, tree, id);
	if (dqp) {
		*O_dqpp = dqp;
		return 0;
	}

817
	error = xfs_qm_dqread(mp, id, type, can_alloc, &dqp);
818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836
	if (error)
		return error;

	error = xfs_qm_dqget_cache_insert(mp, qi, tree, id, dqp);
	if (error) {
		/*
		 * Duplicate found. Just throw away the new dquot and start
		 * over.
		 */
		xfs_qm_dqdestroy(dqp);
		XFS_STATS_INC(mp, xs_qm_dquot_dups);
		goto restart;
	}

	trace_xfs_dqget_miss(dqp);
	*O_dqpp = dqp;
	return 0;
}

837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
/*
 * Given a dquot id and type, read and initialize a dquot from the on-disk
 * metadata.  This function is only for use during quota initialization so
 * it ignores the dquot cache assuming that the dquot shrinker isn't set up.
 * The caller is responsible for _qm_dqdestroy'ing the returned dquot.
 */
int
xfs_qm_dqget_uncached(
	struct xfs_mount	*mp,
	xfs_dqid_t		id,
	uint			type,
	struct xfs_dquot	**dqpp)
{
	int			error;

	error = xfs_qm_dqget_checks(mp, type);
	if (error)
		return error;

	return xfs_qm_dqread(mp, id, type, 0, dqpp);
}

859 860 861 862 863 864 865 866
/* Return the quota id for a given inode and type. */
xfs_dqid_t
xfs_qm_id_for_quotatype(
	struct xfs_inode	*ip,
	uint			type)
{
	switch (type) {
	case XFS_DQ_USER:
867
		return i_uid_read(VFS_I(ip));
868
	case XFS_DQ_GROUP:
869
		return i_gid_read(VFS_I(ip));
870
	case XFS_DQ_PROJ:
871
		return ip->i_d.di_projid;
Linus Torvalds's avatar
Linus Torvalds committed
872
	}
873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
	ASSERT(0);
	return 0;
}

/*
 * Return the dquot for a given inode and type.  If @can_alloc is true, then
 * allocate blocks if needed.  The inode's ILOCK must be held and it must not
 * have already had an inode attached.
 */
int
xfs_qm_dqget_inode(
	struct xfs_inode	*ip,
	uint			type,
	bool			can_alloc,
	struct xfs_dquot	**O_dqpp)
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_quotainfo	*qi = mp->m_quotainfo;
	struct radix_tree_root	*tree = xfs_dquot_tree(qi, type);
	struct xfs_dquot	*dqp;
	xfs_dqid_t		id;
	int			error;

	error = xfs_qm_dqget_checks(mp, type);
	if (error)
		return error;

	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
	ASSERT(xfs_inode_dquot(ip, type) == NULL);

	id = xfs_qm_id_for_quotatype(ip, type);
904 905

restart:
906
	dqp = xfs_qm_dqget_cache_lookup(mp, qi, tree, id);
907 908 909
	if (dqp) {
		*O_dqpp = dqp;
		return 0;
Linus Torvalds's avatar
Linus Torvalds committed
910 911 912 913 914 915 916 917 918
	}

	/*
	 * Dquot cache miss. We don't want to keep the inode lock across
	 * a (potential) disk read. Also we don't want to deal with the lock
	 * ordering between quotainode and this inode. OTOH, dropping the inode
	 * lock here means dealing with a chown that can happen before
	 * we re-acquire the lock.
	 */
919
	xfs_iunlock(ip, XFS_ILOCK_EXCL);
920
	error = xfs_qm_dqread(mp, id, type, can_alloc, &dqp);
921
	xfs_ilock(ip, XFS_ILOCK_EXCL);
922 923
	if (error)
		return error;
Linus Torvalds's avatar
Linus Torvalds committed
924

925 926 927 928 929 930 931 932 933
	/*
	 * A dquot could be attached to this inode by now, since we had
	 * dropped the ilock.
	 */
	if (xfs_this_quota_on(mp, type)) {
		struct xfs_dquot	*dqp1;

		dqp1 = xfs_inode_dquot(ip, type);
		if (dqp1) {
934
			xfs_qm_dqdestroy(dqp);
935 936 937
			dqp = dqp1;
			xfs_dqlock(dqp);
			goto dqret;
Linus Torvalds's avatar
Linus Torvalds committed
938
		}
939 940 941 942
	} else {
		/* inode stays locked on return */
		xfs_qm_dqdestroy(dqp);
		return -ESRCH;
Linus Torvalds's avatar
Linus Torvalds committed
943 944
	}

945 946
	error = xfs_qm_dqget_cache_insert(mp, qi, tree, id, dqp);
	if (error) {
Linus Torvalds's avatar
Linus Torvalds committed
947
		/*
948 949
		 * Duplicate found. Just throw away the new dquot and start
		 * over.
Linus Torvalds's avatar
Linus Torvalds committed
950
		 */
951
		xfs_qm_dqdestroy(dqp);
952
		XFS_STATS_INC(mp, xs_qm_dquot_dups);
953
		goto restart;
Linus Torvalds's avatar
Linus Torvalds committed
954 955
	}

956 957
dqret:
	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
958
	trace_xfs_dqget_miss(dqp);
Linus Torvalds's avatar
Linus Torvalds committed
959
	*O_dqpp = dqp;
Eric Sandeen's avatar
Eric Sandeen committed
960
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
961 962
}

963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
/*
 * Starting at @id and progressing upwards, look for an initialized incore
 * dquot, lock it, and return it.
 */
int
xfs_qm_dqget_next(
	struct xfs_mount	*mp,
	xfs_dqid_t		id,
	uint			type,
	struct xfs_dquot	**dqpp)
{
	struct xfs_dquot	*dqp;
	int			error = 0;

	*dqpp = NULL;
	for (; !error; error = xfs_dq_get_next_id(mp, type, &id)) {
979
		error = xfs_qm_dqget(mp, id, type, false, &dqp);
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995
		if (error == -ENOENT)
			continue;
		else if (error != 0)
			break;

		if (!XFS_IS_DQUOT_UNINITIALIZED(dqp)) {
			*dqpp = dqp;
			return 0;
		}

		xfs_qm_dqput(dqp);
	}

	return error;
}

996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
/*
 * Release a reference to the dquot (decrement ref-count) and unlock it.
 *
 * If there is a group quota attached to this dquot, carefully release that
 * too without tripping over deadlocks'n'stuff.
 */
void
xfs_qm_dqput(
	struct xfs_dquot	*dqp)
{
	ASSERT(dqp->q_nrefs > 0);
	ASSERT(XFS_DQ_IS_LOCKED(dqp));

	trace_xfs_dqput(dqp);

Dave Chinner's avatar
Dave Chinner committed
1011 1012 1013 1014 1015
	if (--dqp->q_nrefs == 0) {
		struct xfs_quotainfo	*qi = dqp->q_mount->m_quotainfo;
		trace_xfs_dqput_free(dqp);

		if (list_lru_add(&qi->qi_lru, &dqp->q_lru))
1016
			XFS_STATS_INC(dqp->q_mount, xs_qm_dquot_unused);
Dave Chinner's avatar
Dave Chinner committed
1017 1018
	}
	xfs_dqunlock(dqp);
Linus Torvalds's avatar
Linus Torvalds committed
1019 1020 1021 1022 1023 1024 1025 1026
}

/*
 * Release a dquot. Flush it if dirty, then dqput() it.
 * dquot must not be locked.
 */
void
xfs_qm_dqrele(
1027
	struct xfs_dquot	*dqp)
Linus Torvalds's avatar
Linus Torvalds committed
1028
{
Christoph Hellwig's avatar
Christoph Hellwig committed
1029 1030 1031
	if (!dqp)
		return;

1032
	trace_xfs_dqrele(dqp);
Linus Torvalds's avatar
Linus Torvalds committed
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043

	xfs_dqlock(dqp);
	/*
	 * We don't care to flush it if the dquot is dirty here.
	 * That will create stutters that we want to avoid.
	 * Instead we do a delayed write when we try to reclaim
	 * a dirty dquot. Also xfs_sync will take part of the burden...
	 */
	xfs_qm_dqput(dqp);
}

1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
/*
 * This is the dquot flushing I/O completion routine.  It is called
 * from interrupt level when the buffer containing the dquot is
 * flushed to disk.  It is responsible for removing the dquot logitem
 * from the AIL if it has not been re-logged, and unlocking the dquot's
 * flush lock. This behavior is very similar to that of inodes..
 */
STATIC void
xfs_qm_dqflush_done(
	struct xfs_buf		*bp,
	struct xfs_log_item	*lip)
{
1056
	struct xfs_dq_logitem	*qip = (struct xfs_dq_logitem *)lip;
1057
	struct xfs_dquot	*dqp = qip->qli_dquot;
1058
	struct xfs_ail		*ailp = lip->li_ailp;
1059
	xfs_lsn_t		tail_lsn;
1060 1061 1062 1063 1064 1065 1066 1067 1068

	/*
	 * We only want to pull the item from the AIL if its
	 * location in the log has not changed since we started the flush.
	 * Thus, we only bother if the dquot's lsn has
	 * not changed. First we check the lsn outside the lock
	 * since it's cheaper, and then we recheck while
	 * holding the lock before removing the dquot from the AIL.
	 */
1069
	if (test_bit(XFS_LI_IN_AIL, &lip->li_flags) &&
1070
	    ((lip->li_lsn == qip->qli_flush_lsn) ||
1071
	     test_bit(XFS_LI_FAILED, &lip->li_flags))) {
1072

1073
		spin_lock(&ailp->ail_lock);
1074
		if (lip->li_lsn == qip->qli_flush_lsn) {
1075 1076 1077
			/* xfs_ail_update_finish() drops the AIL lock */
			tail_lsn = xfs_ail_delete_one(ailp, lip);
			xfs_ail_update_finish(ailp, tail_lsn);
1078 1079 1080 1081 1082
		} else {
			/*
			 * Clear the failed state since we are about to drop the
			 * flush lock
			 */
1083
			xfs_clear_li_failed(lip);
1084
			spin_unlock(&ailp->ail_lock);
1085
		}
1086 1087 1088 1089 1090 1091 1092
	}

	/*
	 * Release the dq's flush lock since we're done with it.
	 */
	xfs_dqfunlock(dqp);
}
Linus Torvalds's avatar
Linus Torvalds committed
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103

/*
 * Write a modified dquot to disk.
 * The dquot must be locked and the flush lock too taken by caller.
 * The flush lock will not be unlocked until the dquot reaches the disk,
 * but the dquot is free to be unlocked and modified by the caller
 * in the interim. Dquot is still locked on return. This behavior is
 * identical to that of inodes.
 */
int
xfs_qm_dqflush(
1104 1105
	struct xfs_dquot	*dqp,
	struct xfs_buf		**bpp)
Linus Torvalds's avatar
Linus Torvalds committed
1106
{
1107
	struct xfs_mount	*mp = dqp->q_mount;
1108
	struct xfs_log_item	*lip = &dqp->q_logitem.qli_item;
1109
	struct xfs_buf		*bp;
1110
	struct xfs_dqblk	*dqb;
1111
	struct xfs_disk_dquot	*ddqp;
1112
	xfs_failaddr_t		fa;
Linus Torvalds's avatar
Linus Torvalds committed
1113 1114 1115
	int			error;

	ASSERT(XFS_DQ_IS_LOCKED(dqp));
1116
	ASSERT(!completion_done(&dqp->q_flush));
1117

1118
	trace_xfs_dqflush(dqp);
Linus Torvalds's avatar
Linus Torvalds committed
1119

1120 1121
	*bpp = NULL;

Linus Torvalds's avatar
Linus Torvalds committed
1122 1123 1124 1125 1126
	xfs_qm_dqunpin_wait(dqp);

	/*
	 * Get the buffer containing the on-disk dquot
	 */
1127
	error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno,
1128 1129
				   mp->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK,
				   &bp, &xfs_dquot_buf_ops);
1130
	if (error == -EAGAIN)
1131
		goto out_unlock;
1132 1133
	if (error)
		goto out_abort;
Linus Torvalds's avatar
Linus Torvalds committed
1134

1135 1136 1137
	/*
	 * Calculate the location of the dquot inside the buffer.
	 */
1138 1139
	dqb = bp->b_addr + dqp->q_bufoffset;
	ddqp = &dqb->dd_diskdq;
1140

1141 1142 1143
	/* sanity check the in-core structure before we flush */
	fa = xfs_dquot_verify(mp, &dqp->q_core, be32_to_cpu(dqp->q_core.d_id),
			      0);
1144 1145
	if (fa) {
		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
1146
				be32_to_cpu(dqp->q_core.d_id), fa);
1147
		xfs_buf_relse(bp);
1148 1149
		error = -EFSCORRUPTED;
		goto out_abort;
Linus Torvalds's avatar
Linus Torvalds committed
1150 1151 1152
	}

	/* This is the only portion of data that needs to persist */
1153
	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
Linus Torvalds's avatar
Linus Torvalds committed
1154 1155 1156 1157

	/*
	 * Clear the dirty field and remember the flush lsn for later use.
	 */
1158
	dqp->dq_flags &= ~XFS_DQ_DIRTY;
Linus Torvalds's avatar
Linus Torvalds committed
1159

1160 1161
	xfs_trans_ail_copy_lsn(mp->m_ail, &dqp->q_logitem.qli_flush_lsn,
					&dqp->q_logitem.qli_item.li_lsn);
Linus Torvalds's avatar
Linus Torvalds committed
1162

1163 1164 1165 1166
	/*
	 * copy the lsn into the on-disk dquot now while we have the in memory
	 * dquot here. This can't be done later in the write verifier as we
	 * can't get access to the log item at that point in time.
Dave Chinner's avatar
Dave Chinner committed
1167 1168 1169 1170
	 *
	 * We also calculate the CRC here so that the on-disk dquot in the
	 * buffer always has a valid CRC. This ensures there is no possibility
	 * of a dquot without an up-to-date CRC getting to disk.
1171 1172 1173
	 */
	if (xfs_sb_version_hascrc(&mp->m_sb)) {
		dqb->dd_lsn = cpu_to_be64(dqp->q_logitem.qli_item.li_lsn);
Dave Chinner's avatar
Dave Chinner committed
1174 1175
		xfs_update_cksum((char *)dqb, sizeof(struct xfs_dqblk),
				 XFS_DQUOT_CRC_OFF);
1176 1177
	}

Linus Torvalds's avatar
Linus Torvalds committed
1178 1179 1180 1181
	/*
	 * Attach an iodone routine so that we can remove this dquot from the
	 * AIL and release the flush lock once the dquot is synced to disk.
	 */
1182
	bp->b_flags |= _XBF_DQUOTS;
1183 1184 1185
	xfs_buf_attach_iodone(bp, xfs_qm_dqflush_done,
				  &dqp->q_logitem.qli_item);

Linus Torvalds's avatar
Linus Torvalds committed
1186 1187 1188 1189
	/*
	 * If the buffer is pinned then push on the log so we won't
	 * get stuck waiting in the write for too long.
	 */
1190
	if (xfs_buf_ispinned(bp)) {
1191
		trace_xfs_dqflush_force(dqp);
1192
		xfs_log_force(mp, 0);
Linus Torvalds's avatar
Linus Torvalds committed
1193 1194
	}

1195
	trace_xfs_dqflush_done(dqp);
1196 1197
	*bpp = bp;
	return 0;
1198

1199 1200
out_abort:
	dqp->dq_flags &= ~XFS_DQ_DIRTY;
1201
	xfs_trans_ail_delete(lip, 0);
1202
	xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
1203 1204
out_unlock:
	xfs_dqfunlock(dqp);
1205
	return error;
Linus Torvalds's avatar
Linus Torvalds committed
1206 1207
}

1208 1209 1210 1211 1212 1213
/*
 * Lock two xfs_dquot structures.
 *
 * To avoid deadlocks we always lock the quota structure with
 * the lowerd id first.
 */
Linus Torvalds's avatar
Linus Torvalds committed
1214 1215
void
xfs_dqlock2(
1216 1217
	struct xfs_dquot	*d1,
	struct xfs_dquot	*d2)
Linus Torvalds's avatar
Linus Torvalds committed
1218 1219 1220
{
	if (d1 && d2) {
		ASSERT(d1 != d2);
1221 1222
		if (be32_to_cpu(d1->q_core.d_id) >
		    be32_to_cpu(d2->q_core.d_id)) {
1223 1224
			mutex_lock(&d2->q_qlock);
			mutex_lock_nested(&d1->q_qlock, XFS_QLOCK_NESTED);
Linus Torvalds's avatar
Linus Torvalds committed
1225
		} else {
1226 1227
			mutex_lock(&d1->q_qlock);
			mutex_lock_nested(&d2->q_qlock, XFS_QLOCK_NESTED);
Linus Torvalds's avatar
Linus Torvalds committed
1228
		}
1229 1230 1231 1232
	} else if (d1) {
		mutex_lock(&d1->q_qlock);
	} else if (d2) {
		mutex_lock(&d2->q_qlock);
Linus Torvalds's avatar
Linus Torvalds committed
1233 1234 1235
	}
}

1236 1237 1238
int __init
xfs_qm_init(void)
{
1239 1240 1241
	xfs_qm_dqzone = kmem_cache_create("xfs_dquot",
					  sizeof(struct xfs_dquot),
					  0, 0, NULL);
1242 1243 1244
	if (!xfs_qm_dqzone)
		goto out;

1245 1246 1247
	xfs_qm_dqtrxzone = kmem_cache_create("xfs_dqtrx",
					     sizeof(struct xfs_dquot_acct),
					     0, 0, NULL);
1248 1249 1250 1251 1252 1253
	if (!xfs_qm_dqtrxzone)
		goto out_free_dqzone;

	return 0;

out_free_dqzone:
1254
	kmem_cache_destroy(xfs_qm_dqzone);
1255 1256 1257 1258
out:
	return -ENOMEM;
}

1259
void
1260 1261
xfs_qm_exit(void)
{
1262 1263
	kmem_cache_destroy(xfs_qm_dqtrxzone);
	kmem_cache_destroy(xfs_qm_dqzone);
1264
}
1265 1266 1267 1268

/*
 * Iterate every dquot of a particular type.  The caller must ensure that the
 * particular quota type is active.  iter_fn can return negative error codes,
1269
 * or -ECANCELED to indicate that it wants to stop iterating.
1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296
 */
int
xfs_qm_dqiterate(
	struct xfs_mount	*mp,
	uint			dqtype,
	xfs_qm_dqiterate_fn	iter_fn,
	void			*priv)
{
	struct xfs_dquot	*dq;
	xfs_dqid_t		id = 0;
	int			error;

	do {
		error = xfs_qm_dqget_next(mp, id, dqtype, &dq);
		if (error == -ENOENT)
			return 0;
		if (error)
			return error;

		error = iter_fn(dq, dqtype, priv);
		id = be32_to_cpu(dq->q_core.d_id);
		xfs_qm_dqput(dq);
		id++;
	} while (error == 0 && id != 0);

	return error;
}