Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 06d10dd9 authored by Nathan Scott's avatar Nathan Scott
Browse files

[XFS] Merge fixes into realtime quota code, since one/two reported, still


not enabled though.

SGI-PV: 938145
SGI-Modid: xfs-linux:xfs-kern:22900a

Signed-off-by: default avatarNathan Scott <nathans@sgi.com>
parent 77bc5beb
Loading
Loading
Loading
Loading
+18 −16
Original line number Diff line number Diff line
@@ -1251,6 +1251,10 @@ xfs_qm_init_quotainfo(
				INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ?
				INT_GET(ddqp->d_iwarns, ARCH_CONVERT) :
				XFS_QM_IWARNLIMIT;
		qinf->qi_rtbwarnlimit =
				INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) ?
				INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) :
				XFS_QM_RTBWARNLIMIT;
		qinf->qi_bhardlimit =
				INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT);
		qinf->qi_bsoftlimit =
@@ -1276,6 +1280,7 @@ xfs_qm_init_quotainfo(
		qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT;
		qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT;
		qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT;
		qinf->qi_rtbwarnlimit = XFS_QM_RTBWARNLIMIT;
	}

	return (0);
@@ -2624,6 +2629,9 @@ xfs_qm_vop_chown(
	xfs_dquot_t	*newdq)
{
	xfs_dquot_t	*prevdq;
	uint		bfield = XFS_IS_REALTIME_INODE(ip) ?
				 XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT;

	ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
	ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));

@@ -2632,20 +2640,12 @@ xfs_qm_vop_chown(
	ASSERT(prevdq);
	ASSERT(prevdq != newdq);

	xfs_trans_mod_dquot(tp, prevdq,
			    XFS_TRANS_DQ_BCOUNT,
			    -(ip->i_d.di_nblocks));
	xfs_trans_mod_dquot(tp, prevdq,
			    XFS_TRANS_DQ_ICOUNT,
			    -1);
	xfs_trans_mod_dquot(tp, prevdq, bfield, -(ip->i_d.di_nblocks));
	xfs_trans_mod_dquot(tp, prevdq, XFS_TRANS_DQ_ICOUNT, -1);

	/* the sparkling new dquot */
	xfs_trans_mod_dquot(tp, newdq,
			    XFS_TRANS_DQ_BCOUNT,
			    ip->i_d.di_nblocks);
	xfs_trans_mod_dquot(tp, newdq,
			    XFS_TRANS_DQ_ICOUNT,
			    1);
	xfs_trans_mod_dquot(tp, newdq, bfield, ip->i_d.di_nblocks);
	xfs_trans_mod_dquot(tp, newdq, XFS_TRANS_DQ_ICOUNT, 1);

	/*
	 * Take an extra reference, because the inode
@@ -2673,7 +2673,7 @@ xfs_qm_vop_chown_reserve(
{
	int		error;
	xfs_mount_t	*mp;
	uint		delblks;
	uint		delblks, blkflags;
	xfs_dquot_t	*unresudq, *unresgdq, *delblksudq, *delblksgdq;

	ASSERT(XFS_ISLOCKED_INODE(ip));
@@ -2682,6 +2682,8 @@ xfs_qm_vop_chown_reserve(

	delblks = ip->i_delayed_blks;
	delblksudq = delblksgdq = unresudq = unresgdq = NULL;
	blkflags = XFS_IS_REALTIME_INODE(ip) ?
			XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;

	if (XFS_IS_UQUOTA_ON(mp) && udqp &&
	    ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) {
@@ -2711,7 +2713,7 @@ xfs_qm_vop_chown_reserve(

	if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
				delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
				flags | XFS_QMOPT_RES_REGBLKS)))
				flags | blkflags)))
		return (error);

	/*
@@ -2728,11 +2730,11 @@ xfs_qm_vop_chown_reserve(
		ASSERT(unresudq || unresgdq);
		if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
				delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
				flags | XFS_QMOPT_RES_REGBLKS)))
				flags | blkflags)))
			return (error);
		xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
				unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
				XFS_QMOPT_RES_REGBLKS);
				blkflags);
	}

	return (0);
+4 −2
Original line number Diff line number Diff line
@@ -133,8 +133,9 @@ typedef struct xfs_quotainfo {
	time_t		 qi_btimelimit;	 /* limit for blks timer */
	time_t		 qi_itimelimit;	 /* limit for inodes timer */
	time_t		 qi_rtbtimelimit;/* limit for rt blks timer */
	xfs_qwarncnt_t	 qi_bwarnlimit;	 /* limit for num warnings */
	xfs_qwarncnt_t	 qi_iwarnlimit;	 /* limit for num warnings */
	xfs_qwarncnt_t	 qi_bwarnlimit;	 /* limit for blks warnings */
	xfs_qwarncnt_t	 qi_iwarnlimit;	 /* limit for inodes warnings */
	xfs_qwarncnt_t	 qi_rtbwarnlimit;/* limit for rt blks warnings */
	mutex_t		 qi_quotaofflock;/* to serialize quotaoff */
	xfs_filblks_t	 qi_dqchunklen;	 /* # BBs in a chunk of dqs */
	uint		 qi_dqperchunk;	 /* # ondisk dqs in above chunk */
@@ -176,6 +177,7 @@ typedef struct xfs_dquot_acct {

#define XFS_QM_BWARNLIMIT	5
#define XFS_QM_IWARNLIMIT	5
#define XFS_QM_RTBWARNLIMIT	5

#define XFS_QM_LOCK(xqm)	(mutex_lock(&xqm##_lock, PINOD))
#define XFS_QM_UNLOCK(xqm)	(mutex_unlock(&xqm##_lock))
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@
#define XFS_QI_RTBTIMELIMIT(mp) ((mp)->m_quotainfo->qi_rtbtimelimit)
#define XFS_QI_ITIMELIMIT(mp)	((mp)->m_quotainfo->qi_itimelimit)
#define XFS_QI_BWARNLIMIT(mp)	((mp)->m_quotainfo->qi_bwarnlimit)
#define XFS_QI_RTBWARNLIMIT(mp)	((mp)->m_quotainfo->qi_rtbwarnlimit)
#define XFS_QI_IWARNLIMIT(mp)	((mp)->m_quotainfo->qi_iwarnlimit)
#define XFS_QI_QOFFLOCK(mp)	((mp)->m_quotainfo->qi_quotaofflock)

+25 −25
Original line number Diff line number Diff line
@@ -497,7 +497,7 @@ xfs_trans_apply_dquot_deltas(
			 * Adjust the RT reservation.
			 */
			if (qtrx->qt_rtblk_res != 0) {
				if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) {
				if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
					if (qtrx->qt_rtblk_res >
					    qtrx->qt_rtblk_res_used)
					       dqp->q_res_rtbcount -= (xfs_qcnt_t)
@@ -530,12 +530,6 @@ xfs_trans_apply_dquot_deltas(
					    (xfs_qcnt_t)qtrx->qt_icount_delta;
			}


#ifdef QUOTADEBUG
			if (qtrx->qt_rtblk_res != 0)
				cmn_err(CE_DEBUG, "RT res %d for 0x%p\n",
					(int) qtrx->qt_rtblk_res, dqp);
#endif
			ASSERT(dqp->q_res_bcount >=
				INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
			ASSERT(dqp->q_res_icount >=
@@ -636,7 +630,10 @@ xfs_trans_dqresv(
	int		error;
	xfs_qcnt_t	hardlimit;
	xfs_qcnt_t	softlimit;
	time_t		btimer;
	time_t		timer;
	xfs_qwarncnt_t	warns;
	xfs_qwarncnt_t	warnlimit;
	xfs_qcnt_t	count;
	xfs_qcnt_t	*resbcountp;
	xfs_quotainfo_t	*q = mp->m_quotainfo;

@@ -651,7 +648,9 @@ xfs_trans_dqresv(
		softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT);
		if (!softlimit)
			softlimit = q->qi_bsoftlimit;
		btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
		timer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
		warns = INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT);
		warnlimit = XFS_QI_BWARNLIMIT(dqp->q_mount);
		resbcountp = &dqp->q_res_bcount;
	} else {
		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
@@ -661,7 +660,9 @@ xfs_trans_dqresv(
		softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT);
		if (!softlimit)
			softlimit = q->qi_rtbsoftlimit;
		btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
		timer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
		warns = INT_GET(dqp->q_core.d_rtbwarns, ARCH_CONVERT);
		warnlimit = XFS_QI_RTBWARNLIMIT(dqp->q_mount);
		resbcountp = &dqp->q_res_rtbcount;
	}
	error = 0;
@@ -691,37 +692,36 @@ xfs_trans_dqresv(
				 * If timer or warnings has expired,
				 * return EDQUOT
				 */
				if ((btimer != 0 && get_seconds() > btimer) ||
				    (dqp->q_core.d_bwarns &&
				     INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) >=
				     XFS_QI_BWARNLIMIT(dqp->q_mount))) {
				if ((timer != 0 && get_seconds() > timer) ||
				    (warns != 0 && warns >= warnlimit)) {
					error = EDQUOT;
					goto error_return;
				}
			}
		}
		if (ninos > 0) {
			hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT);
			count = INT_GET(dqp->q_core.d_icount, ARCH_CONVERT);
			timer = INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT);
			warns = INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT);
			warnlimit = XFS_QI_IWARNLIMIT(dqp->q_mount);
			hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit,
						ARCH_CONVERT);
			if (!hardlimit)
				hardlimit = q->qi_ihardlimit;
			softlimit = INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT);
			softlimit = INT_GET(dqp->q_core.d_ino_softlimit,
						ARCH_CONVERT);
			if (!softlimit)
				softlimit = q->qi_isoftlimit;
			if (hardlimit > 0ULL &&
			    INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= hardlimit) {
			if (hardlimit > 0ULL && count >= hardlimit) {
				error = EDQUOT;
				goto error_return;
			} else if (softlimit > 0ULL &&
				   INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) {
			} else if (softlimit > 0ULL && count >= softlimit) {
				/*
				 * If timer or warnings has expired,
				 * return EDQUOT
				 */
				if ((dqp->q_core.d_itimer &&
				     get_seconds() > INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)) ||
				    (dqp->q_core.d_iwarns &&
				     INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) >=
				     XFS_QI_IWARNLIMIT(dqp->q_mount))) {
				if ((timer != 0 && get_seconds() > timer) ||
				     (warns != 0 && warns >= warnlimit)) {
					error = EDQUOT;
					goto error_return;
				}
+64 −48
Original line number Diff line number Diff line
@@ -4545,18 +4545,17 @@ xfs_bmapi(
	xfs_extlen_t	alen;		/* allocated extent length */
	xfs_fileoff_t	aoff;		/* allocated file offset */
	xfs_bmalloca_t	bma;		/* args for xfs_bmap_alloc */
	char		contig;		/* allocation must be one extent */
	xfs_btree_cur_t	*cur;		/* bmap btree cursor */
	char		delay;		/* this request is for delayed alloc */
	xfs_fileoff_t	end;		/* end of mapped file region */
	int		eof;		/* we've hit the end of extent list */
	char		contig;		/* allocation must be one extent */
	char		delay;		/* this request is for delayed alloc */
	char		exact;		/* don't do all of wasdelayed extent */
	xfs_bmbt_rec_t	*ep;		/* extent list entry pointer */
	int		error;		/* error return */
	char		exact;		/* don't do all of wasdelayed extent */
	xfs_bmbt_irec_t	got;		/* current extent list record */
	xfs_ifork_t	*ifp;		/* inode fork pointer */
	xfs_extlen_t	indlen;		/* indirect blocks length */
	char		inhole;		/* current location is hole in file */
	xfs_extnum_t	lastx;		/* last useful extent number */
	int		logflags;	/* flags for transaction logging */
	xfs_extlen_t	minleft;	/* min blocks left after allocation */
@@ -4567,13 +4566,15 @@ xfs_bmapi(
	xfs_extnum_t	nextents;	/* number of extents in file */
	xfs_fileoff_t	obno;		/* old block number (offset) */
	xfs_bmbt_irec_t	prev;		/* previous extent list record */
	char		stateless;	/* ignore state flag set */
	int		tmp_logflags;	/* temp flags holder */
	int		whichfork;	/* data or attr fork */
	char		inhole;		/* current location is hole in file */
	char		stateless;	/* ignore state flag set */
	char		trim;		/* output trimmed to match range */
	char		userdata;	/* allocating non-metadata */
	char		wasdelay;	/* old extent was delayed */
	int		whichfork;	/* data or attr fork */
	char		wr;		/* this is a write request */
	char		rt;		/* this is a realtime file */
	char		rsvd;		/* OK to allocate reserved blocks */
#ifdef DEBUG
	xfs_fileoff_t	orig_bno;	/* original block number value */
@@ -4603,6 +4604,7 @@ xfs_bmapi(
	}
	if (XFS_FORCED_SHUTDOWN(mp))
		return XFS_ERROR(EIO);
	rt = XFS_IS_REALTIME_INODE(ip);
	ifp = XFS_IFORK_PTR(ip, whichfork);
	ASSERT(ifp->if_ext_max ==
	       XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
@@ -4707,9 +4709,16 @@ xfs_bmapi(
			}
			minlen = contig ? alen : 1;
			if (delay) {
				indlen = (xfs_extlen_t)
					xfs_bmap_worst_indlen(ip, alen);
				ASSERT(indlen > 0);
				xfs_extlen_t	extsz = 0;

				/* Figure out the extent size, adjust alen */
				if (rt) {
					if (!(extsz = ip->i_d.di_extsize))
						extsz = mp->m_sb.sb_rextsize;
					alen = roundup(alen, extsz);
					extsz = alen / mp->m_sb.sb_rextsize;
				}

				/*
				 * Make a transaction-less quota reservation for
				 * delayed allocation blocks. This number gets
@@ -4717,8 +4726,10 @@ xfs_bmapi(
				 * We return EDQUOT if we haven't allocated
				 * blks already inside this loop;
				 */
				if (XFS_TRANS_RESERVE_BLKQUOTA(
						mp, NULL, ip, (long)alen)) {
				if (XFS_TRANS_RESERVE_QUOTA_NBLKS(
						mp, NULL, ip, (long)alen, 0,
						rt ? XFS_QMOPT_RES_RTBLKS :
						     XFS_QMOPT_RES_REGBLKS)) {
					if (n == 0) {
						*nmap = 0;
						ASSERT(cur == NULL);
@@ -4731,40 +4742,34 @@ xfs_bmapi(
				 * Split changing sb for alen and indlen since
				 * they could be coming from different places.
				 */
				if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) {
					xfs_extlen_t	extsz;
					xfs_extlen_t	ralen;
					if (!(extsz = ip->i_d.di_extsize))
						extsz = mp->m_sb.sb_rextsize;
					ralen = roundup(alen, extsz);
					ralen = ralen / mp->m_sb.sb_rextsize;
					if (xfs_mod_incore_sb(mp,
				indlen = (xfs_extlen_t)
					xfs_bmap_worst_indlen(ip, alen);
				ASSERT(indlen > 0);

				if (rt)
					error = xfs_mod_incore_sb(mp,
							XFS_SBS_FREXTENTS,
						-(ralen), rsvd)) {
						if (XFS_IS_QUOTA_ON(ip->i_mount))
							XFS_TRANS_UNRESERVE_BLKQUOTA(
						     		mp, NULL, ip,
								(long)alen);
						break;
					}
				} else {
					if (xfs_mod_incore_sb(mp,
							-(extsz), rsvd);
				else
					error = xfs_mod_incore_sb(mp,
							XFS_SBS_FDBLOCKS,
							-(alen), rsvd);
				if (!error)
					error = xfs_mod_incore_sb(mp,
							XFS_SBS_FDBLOCKS,
							      -(alen), rsvd)) {
							-(indlen), rsvd);

				if (error) {
					if (XFS_IS_QUOTA_ON(ip->i_mount))
							XFS_TRANS_UNRESERVE_BLKQUOTA(
						/* unreserve the blocks now */
						XFS_TRANS_UNRESERVE_QUOTA_NBLKS(
							mp, NULL, ip,
								(long)alen);
							(long)alen, 0, rt ?
							XFS_QMOPT_RES_RTBLKS :
							XFS_QMOPT_RES_REGBLKS);
					break;
				}
				}

				if (xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
						-(indlen), rsvd)) {
					XFS_TRANS_UNRESERVE_BLKQUOTA(
						mp, NULL, ip, (long)alen);
					break;
				}
				ip->i_delayed_blks += alen;
				abno = NULLSTARTBLOCK(indlen);
			} else {
@@ -5389,13 +5394,24 @@ xfs_bunmapi(
		}
		if (wasdel) {
			ASSERT(STARTBLOCKVAL(del.br_startblock) > 0);
			/* Update realtim/data freespace, unreserve quota */
			if (isrt) {
				xfs_filblks_t rtexts;

				rtexts = XFS_FSB_TO_B(mp, del.br_blockcount);
				do_div(rtexts, mp->m_sb.sb_rextsize);
				xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,
						(int)rtexts, rsvd);
				XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,
					-((long)del.br_blockcount), 0,
					XFS_QMOPT_RES_RTBLKS);
			} else {
				xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
						(int)del.br_blockcount, rsvd);
			/* Unreserve our quota space */
			XFS_TRANS_RESERVE_QUOTA_NBLKS(
				mp, NULL, ip, -((long)del.br_blockcount), 0,
				isrt ?	XFS_QMOPT_RES_RTBLKS :
				XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,
					-((long)del.br_blockcount), 0,
					XFS_QMOPT_RES_REGBLKS);
			}
			ip->i_delayed_blks -= del.br_blockcount;
			if (cur)
				cur->bc_private.b.flags |=
Loading