Skip to content

Commit 02b7ee4

Browse files
author
Darrick J. Wong
committed
xfs: reserve data and rt quota at the same time
Modify xfs_trans_reserve_quota_nblks so that we can reserve data and realtime blocks from the dquot at the same time. This change has the theoretical side effect that for allocations to realtime files we will reserve from the dquot both the number of rtblocks being allocated and the number of bmbt blocks that might be needed to add the mapping. However, since the mount code disables quota if it finds a realtime device, this should not result in any behavior changes. Now that we've moved the inode creation callers away from using the _nblks function, we can repurpose the (now unused) ninos argument for realtime blocks, so make that change. This also replaces the flags argument with a boolean parameter to force the reservation since we don't need to distinguish between data and rt quota reservations any more, and the only flag being passed in was FORCE_RES. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Brian Foster <[email protected]>
1 parent 7ac6eb4 commit 02b7ee4

File tree

7 files changed

+60
-56
lines changed

7 files changed

+60
-56
lines changed

fs/xfs/libxfs/xfs_attr.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -474,12 +474,8 @@ xfs_attr_set(
474474
}
475475

476476
if (args->value) {
477-
unsigned int quota_flags = XFS_QMOPT_RES_REGBLKS;
478-
479-
if (rsvd)
480-
quota_flags |= XFS_QMOPT_FORCE_RES;
481477
error = xfs_trans_reserve_quota_nblks(args->trans, dp,
482-
args->total, 0, quota_flags);
478+
args->total, 0, rsvd);
483479
if (error)
484480
goto out_trans_cancel;
485481

fs/xfs/libxfs/xfs_bmap.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,9 +1085,7 @@ xfs_bmap_add_attrfork(
10851085
return error;
10861086

10871087
xfs_ilock(ip, XFS_ILOCK_EXCL);
1088-
error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ?
1089-
XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
1090-
XFS_QMOPT_RES_REGBLKS);
1088+
error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd);
10911089
if (error)
10921090
goto trans_cancel;
10931091
if (XFS_IFORK_Q(ip))

fs/xfs/xfs_bmap_util.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -727,11 +727,10 @@ xfs_alloc_file_space(
727727
xfs_fileoff_t startoffset_fsb;
728728
xfs_fileoff_t endoffset_fsb;
729729
int nimaps;
730-
int quota_flag;
731730
int rt;
732731
xfs_trans_t *tp;
733732
xfs_bmbt_irec_t imaps[1], *imapp;
734-
uint qblocks, resblks, resrtextents;
733+
uint resblks, resrtextents;
735734
int error;
736735

737736
trace_xfs_alloc_file_space(ip);
@@ -761,6 +760,7 @@ xfs_alloc_file_space(
761760
*/
762761
while (allocatesize_fsb && !error) {
763762
xfs_fileoff_t s, e;
763+
unsigned int dblocks, rblocks;
764764

765765
/*
766766
* Determine space reservations for data/realtime.
@@ -790,20 +790,19 @@ xfs_alloc_file_space(
790790
*/
791791
resblks = min_t(xfs_fileoff_t, (e - s), (MAXEXTLEN * nimaps));
792792
if (unlikely(rt)) {
793-
resrtextents = qblocks = resblks;
793+
resrtextents = resblks;
794794
resrtextents /= mp->m_sb.sb_rextsize;
795-
resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
796-
quota_flag = XFS_QMOPT_RES_RTBLKS;
795+
dblocks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
796+
rblocks = resblks;
797797
} else {
798-
resrtextents = 0;
799-
resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resblks);
800-
quota_flag = XFS_QMOPT_RES_REGBLKS;
798+
dblocks = XFS_DIOSTRAT_SPACE_RES(mp, resblks);
799+
rblocks = 0;
801800
}
802801

803802
/*
804803
* Allocate and setup the transaction.
805804
*/
806-
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks,
805+
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, dblocks,
807806
resrtextents, 0, &tp);
808807

809808
/*
@@ -817,8 +816,8 @@ xfs_alloc_file_space(
817816
break;
818817
}
819818
xfs_ilock(ip, XFS_ILOCK_EXCL);
820-
error = xfs_trans_reserve_quota_nblks(tp, ip, qblocks,
821-
0, quota_flag);
819+
error = xfs_trans_reserve_quota_nblks(tp, ip, dblocks, rblocks,
820+
false);
822821
if (error)
823822
goto error;
824823

@@ -881,8 +880,7 @@ xfs_unmap_extent(
881880
}
882881

883882
xfs_ilock(ip, XFS_ILOCK_EXCL);
884-
error = xfs_trans_reserve_quota_nblks(tp, ip, resblks, 0,
885-
XFS_QMOPT_RES_REGBLKS);
883+
error = xfs_trans_reserve_quota_nblks(tp, ip, resblks, 0, false);
886884
if (error)
887885
goto out_trans_cancel;
888886

fs/xfs/xfs_iomap.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -194,25 +194,25 @@ xfs_iomap_write_direct(
194194
struct xfs_trans *tp;
195195
xfs_filblks_t resaligned;
196196
int nimaps;
197-
int quota_flag;
198-
uint qblocks, resblks;
197+
unsigned int dblocks, rblocks;
199198
unsigned int resrtextents = 0;
200199
int error;
201200
int bmapi_flags = XFS_BMAPI_PREALLOC;
202-
uint tflags = 0;
201+
int tflags = 0;
202+
bool force = false;
203203

204204
ASSERT(count_fsb > 0);
205205

206206
resaligned = xfs_aligned_fsb_count(offset_fsb, count_fsb,
207207
xfs_get_extsz_hint(ip));
208208
if (unlikely(XFS_IS_REALTIME_INODE(ip))) {
209-
resrtextents = qblocks = resaligned;
209+
resrtextents = resaligned;
210210
resrtextents /= mp->m_sb.sb_rextsize;
211-
resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
212-
quota_flag = XFS_QMOPT_RES_RTBLKS;
211+
dblocks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
212+
rblocks = resaligned;
213213
} else {
214-
resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned);
215-
quota_flag = XFS_QMOPT_RES_REGBLKS;
214+
dblocks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned);
215+
rblocks = 0;
216216
}
217217

218218
error = xfs_qm_dqattach(ip);
@@ -235,18 +235,19 @@ xfs_iomap_write_direct(
235235
if (IS_DAX(VFS_I(ip))) {
236236
bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO;
237237
if (imap->br_state == XFS_EXT_UNWRITTEN) {
238+
force = true;
238239
tflags |= XFS_TRANS_RESERVE;
239-
resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1;
240+
dblocks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1;
240241
}
241242
}
242-
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, resrtextents,
243+
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, dblocks, resrtextents,
243244
tflags, &tp);
244245
if (error)
245246
return error;
246247

247248
xfs_ilock(ip, XFS_ILOCK_EXCL);
248249

249-
error = xfs_trans_reserve_quota_nblks(tp, ip, qblocks, 0, quota_flag);
250+
error = xfs_trans_reserve_quota_nblks(tp, ip, dblocks, rblocks, force);
250251
if (error)
251252
goto out_trans_cancel;
252253

@@ -559,8 +560,7 @@ xfs_iomap_write_unwritten(
559560
xfs_ilock(ip, XFS_ILOCK_EXCL);
560561
xfs_trans_ijoin(tp, ip, 0);
561562

562-
error = xfs_trans_reserve_quota_nblks(tp, ip, resblks, 0,
563-
XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES);
563+
error = xfs_trans_reserve_quota_nblks(tp, ip, resblks, 0, true);
564564
if (error)
565565
goto error_on_bmapi_transaction;
566566

fs/xfs/xfs_quota.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ extern void xfs_trans_mod_dquot_byino(struct xfs_trans *, struct xfs_inode *,
8181
uint, int64_t);
8282
extern void xfs_trans_apply_dquot_deltas(struct xfs_trans *);
8383
extern void xfs_trans_unreserve_and_mod_dquots(struct xfs_trans *);
84-
extern int xfs_trans_reserve_quota_nblks(struct xfs_trans *,
85-
struct xfs_inode *, int64_t, long, uint);
84+
int xfs_trans_reserve_quota_nblks(struct xfs_trans *tp, struct xfs_inode *ip,
85+
int64_t dblocks, int64_t rblocks, bool force);
8686
extern int xfs_trans_reserve_quota_bydquots(struct xfs_trans *,
8787
struct xfs_mount *, struct xfs_dquot *,
8888
struct xfs_dquot *, struct xfs_dquot *, int64_t, long, uint);
@@ -114,8 +114,7 @@ extern void xfs_qm_unmount_quotas(struct xfs_mount *);
114114
static inline int
115115
xfs_quota_reserve_blkres(struct xfs_inode *ip, int64_t blocks)
116116
{
117-
return xfs_trans_reserve_quota_nblks(NULL, ip, blocks, 0,
118-
XFS_QMOPT_RES_REGBLKS);
117+
return xfs_trans_reserve_quota_nblks(NULL, ip, blocks, 0, false);
119118
}
120119
#else
121120
static inline int
@@ -134,7 +133,8 @@ xfs_qm_vop_dqalloc(struct xfs_inode *ip, kuid_t kuid, kgid_t kgid,
134133
#define xfs_trans_apply_dquot_deltas(tp)
135134
#define xfs_trans_unreserve_and_mod_dquots(tp)
136135
static inline int xfs_trans_reserve_quota_nblks(struct xfs_trans *tp,
137-
struct xfs_inode *ip, int64_t nblks, long ninos, uint flags)
136+
struct xfs_inode *ip, int64_t dblocks, int64_t rblocks,
137+
bool force)
138138
{
139139
return 0;
140140
}

fs/xfs/xfs_reflink.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,7 @@ xfs_reflink_allocate_cow(
398398
goto convert;
399399
}
400400

401-
error = xfs_trans_reserve_quota_nblks(tp, ip, resblks, 0,
402-
XFS_QMOPT_RES_REGBLKS);
401+
error = xfs_trans_reserve_quota_nblks(tp, ip, resblks, 0, false);
403402
if (error)
404403
goto out_trans_cancel;
405404

@@ -1090,8 +1089,7 @@ xfs_reflink_remap_extent(
10901089
if (!smap_real && dmap_written)
10911090
qres += dmap->br_blockcount;
10921091
if (qres > 0) {
1093-
error = xfs_trans_reserve_quota_nblks(tp, ip, qres, 0,
1094-
XFS_QMOPT_RES_REGBLKS);
1092+
error = xfs_trans_reserve_quota_nblks(tp, ip, qres, 0, false);
10951093
if (error)
10961094
goto out_cancel;
10971095
}

fs/xfs/xfs_trans_dquot.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -780,28 +780,42 @@ int
780780
xfs_trans_reserve_quota_nblks(
781781
struct xfs_trans *tp,
782782
struct xfs_inode *ip,
783-
int64_t nblks,
784-
long ninos,
785-
uint flags)
783+
int64_t dblocks,
784+
int64_t rblocks,
785+
bool force)
786786
{
787787
struct xfs_mount *mp = ip->i_mount;
788+
unsigned int qflags = 0;
789+
int error;
788790

789791
if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
790792
return 0;
791793

792794
ASSERT(!xfs_is_quota_inode(&mp->m_sb, ip->i_ino));
793-
794795
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
795-
ASSERT((flags & ~(XFS_QMOPT_FORCE_RES)) == XFS_TRANS_DQ_RES_RTBLKS ||
796-
(flags & ~(XFS_QMOPT_FORCE_RES)) == XFS_TRANS_DQ_RES_BLKS);
797796

798-
/*
799-
* Reserve nblks against these dquots, with trans as the mediator.
800-
*/
801-
return xfs_trans_reserve_quota_bydquots(tp, mp,
802-
ip->i_udquot, ip->i_gdquot,
803-
ip->i_pdquot,
804-
nblks, ninos, flags);
797+
if (force)
798+
qflags |= XFS_QMOPT_FORCE_RES;
799+
800+
/* Reserve data device quota against the inode's dquots. */
801+
error = xfs_trans_reserve_quota_bydquots(tp, mp, ip->i_udquot,
802+
ip->i_gdquot, ip->i_pdquot, dblocks, 0,
803+
XFS_QMOPT_RES_REGBLKS | qflags);
804+
if (error)
805+
return error;
806+
807+
/* Do the same but for realtime blocks. */
808+
error = xfs_trans_reserve_quota_bydquots(tp, mp, ip->i_udquot,
809+
ip->i_gdquot, ip->i_pdquot, rblocks, 0,
810+
XFS_QMOPT_RES_RTBLKS | qflags);
811+
if (error) {
812+
xfs_trans_reserve_quota_bydquots(tp, mp, ip->i_udquot,
813+
ip->i_gdquot, ip->i_pdquot, -dblocks, 0,
814+
XFS_QMOPT_RES_REGBLKS);
815+
return error;
816+
}
817+
818+
return 0;
805819
}
806820

807821
/* Change the quota reservations for an inode creation activity. */

0 commit comments

Comments
 (0)