History

Merge tag 'for-linus-v3.11-rc1' of git://oss.sgi.com/xfs/xfs

Pull xfs update from Ben Myers: "This includes several bugfixes, part of the work for project quotas and group quotas to be used together, performance improvements for inode creation/deletion, buffer readahead, and bulkstat, implementation of the inode change count, an inode create transaction, and the removal of a bunch of dead code. There are also some duplicate commits that you already have from the 3.10-rc series. - part of the work to allow project quotas and group quotas to be used together - inode change count - inode create transaction - block queue plugging in buffer readahead and bulkstat - ordered log vector support - removal of dead code in and around xfs_sync_inode_grab, xfs_ialloc_get_rec, XFS_MOUNT_RETERR, XFS_ALLOCFREE_LOG_RES, XFS_DIROP_LOG_RES, xfs_chash, ctl_table, and xfs_growfs_data_private - don't keep silent if sunit/swidth can not be changed via mount - fix a leak of remote symlink blocks into the filesystem when xattrs are used on symlinks - fix for fiemap to return FIEMAP_EXTENT_UNKOWN flag on delay extents - part of a fix for xfs_fsr - disable speculative preallocation with small files - performance improvements for inode creates and deletes" * tag 'for-linus-v3.11-rc1' of git://oss.sgi.com/xfs/xfs: (61 commits) xfs: Remove incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD xfs: Change xfs_dquot_acct to be a 2-dimensional array xfs: Code cleanup and removal of some typedef usage xfs: Replace macro XFS_DQ_TO_QIP with a function xfs: Replace macro XFS_DQUOT_TREE with a function xfs: Define a new function xfs_is_quota_inode() xfs: implement inode change count xfs: Use inode create transaction xfs: Inode create item recovery xfs: Inode create transaction reservations xfs: Inode create log items xfs: Introduce an ordered buffer item xfs: Introduce ordered log vector support xfs: xfs_ifree doesn't need to modify the inode buffer xfs: don't do IO when creating an new inode xfs: don't use speculative prealloc for small files xfs: plug directory buffer readahead xfs: add pluging for bulkstat readahead xfs: Remove dead function prototype xfs_sync_inode_grab() xfs: Remove the left function variable from xfs_ialloc_get_rec() ...

Linus Torvalds committed 13 years ago

Commit da89bd22 parents be0c5d8 83e782e43 files · +1180 −477Browse files

Unified · Split

43 files
  1. fs/xfs/Makefile +1 −0
  2. fs/xfs/xfs_alloc.c +18 −6
  3. fs/xfs/xfs_bmap_btree.h +2 −0
  4. fs/xfs/xfs_buf_item.c +58 −29
  5. fs/xfs/xfs_buf_item.h +3 −1
  6. fs/xfs/xfs_dfrag.c +5 −3
  7. fs/xfs/xfs_dir2_leaf.c +3 −0
  8. fs/xfs/xfs_dquot.c +8 −8
  9. fs/xfs/xfs_dquot.h +0 −4
  10. fs/xfs/xfs_fsops.c +1 −1
  11. fs/xfs/xfs_ialloc.c +53 −21
  12. fs/xfs/xfs_ialloc.h +8 −0
  13. fs/xfs/xfs_icache.c +2 −1
  14. fs/xfs/xfs_icache.h +0 −1
  15. fs/xfs/xfs_icreate_item.c +195 −0
  16. fs/xfs/xfs_icreate_item.h +52 −0
  17. fs/xfs/xfs_inode.c +32 −36
  18. fs/xfs/xfs_iomap.c +13 −0
  19. fs/xfs/xfs_iops.c +2 −1
  20. fs/xfs/xfs_itable.c +4 −1
  21. fs/xfs/xfs_log.c +18 −4
  22. fs/xfs/xfs_log.h +4 −1
  23. fs/xfs/xfs_log_cil.c +51 −24
  24. fs/xfs/xfs_log_recover.c +109 −5
  25. fs/xfs/xfs_mount.c +66 −26
  26. fs/xfs/xfs_mount.h +0 −4
  27. fs/xfs/xfs_qm.c +92 −83
  28. fs/xfs/xfs_qm.h +58 −25
  29. fs/xfs/xfs_qm_syscalls.c +27 −24
  30. fs/xfs/xfs_quota.h +29 −18
  31. fs/xfs/xfs_quotaops.c +4 −2
  32. fs/xfs/xfs_sb.h +6 −0
  33. fs/xfs/xfs_super.c +23 −16
  34. fs/xfs/xfs_symlink.c +48 −3
  35. fs/xfs/xfs_symlink.h +1 −1
  36. fs/xfs/xfs_sysctl.c +13 −13
  37. fs/xfs/xfs_trace.h +5 −0
  38. fs/xfs/xfs_trans.c +77 −41
  39. fs/xfs/xfs_trans.h +7 −9
  40. fs/xfs/xfs_trans_buf.c +31 −3
  41. fs/xfs/xfs_trans_dquot.c +37 −50
  42. fs/xfs/xfs_trans_inode.c +11 −0
  43. fs/xfs/xfs_vnodeops.c +3 −12
fs/xfs/Makefile+1−0
@@ -71,6 +71,7 @@ xfs-y += xfs_alloc.o \ · 70 unmodified lines
7171 xfs_dir2_sf.o \
7272 xfs_ialloc.o \
7373 xfs_ialloc_btree.o \
74+ xfs_icreate_item.o \
7475 xfs_inode.o \
7576 xfs_log_recover.o \
7677 xfs_mount.o \
fs/xfs/xfs_alloc.c+18−6
@@ -175,6 +175,7 @@ xfs_alloc_compute_diff( · 174 unmodified lines
175175 xfs_agblock_t wantbno, /* target starting block */
176176 xfs_extlen_t wantlen, /* target length */
177177 xfs_extlen_t alignment, /* target alignment */
178+ char userdata, /* are we allocating data? */
178179 xfs_agblock_t freebno, /* freespace's starting block */
179180 xfs_extlen_t freelen, /* freespace's length */
180181 xfs_agblock_t *newbnop) /* result: best start block from free */
@@ -189,7 +190,14 @@ xfs_alloc_compute_diff( · 8 unmodified lines
189190 ASSERT(freelen >= wantlen);
190191 freeend = freebno + freelen;
191192 wantend = wantbno + wantlen;
192− if (freebno >= wantbno) {
193+ /*
194+ * We want to allocate from the start of a free extent if it is past
195+ * the desired block or if we are allocating user data and the free
196+ * extent is before desired block. The second case is there to allow
197+ * for contiguous allocation from the remaining free space if the file
198+ * grows in the short term.
199+ */
200+ if (freebno >= wantbno || (userdata && freeend < wantend)) {
193201 if ((newbno1 = roundup(freebno, alignment)) >= freeend)
194202 newbno1 = NULLAGBLOCK;
195203 } else if (freeend >= wantend && alignment > 1) {
@@ -805,7 +813,8 @@ xfs_alloc_find_best_extent( · 609 unmodified lines
805813 xfs_alloc_fix_len(args);
806814
807815 sdiff = xfs_alloc_compute_diff(args->agbno, args->len,
808− args->alignment, *sbnoa,
816+ args->alignment,
817+ args->userdata, *sbnoa,
809818 *slena, &new);
810819
811820 /*
@@ -976,7 +985,8 @@ restart: · 164 unmodified lines
976985 if (args->len < blen)
977986 continue;
978987 ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
979− args->alignment, ltbnoa, ltlena, &ltnew);
988+ args->alignment, args->userdata, ltbnoa,
989+ ltlena, &ltnew);
980990 if (ltnew != NULLAGBLOCK &&
981991 (args->len > blen || ltdiff < bdiff)) {
982992 bdiff = ltdiff;
@@ -1128,7 +1138,8 @@ restart: · 145 unmodified lines
11281138 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
11291139 xfs_alloc_fix_len(args);
11301140 ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
1131− args->alignment, ltbnoa, ltlena, &ltnew);
1141+ args->alignment, args->userdata, ltbnoa,
1142+ ltlena, &ltnew);
11321143
11331144 error = xfs_alloc_find_best_extent(args,
11341145 &bno_cur_lt, &bno_cur_gt,
@@ -1144,7 +1155,8 @@ restart: · 9 unmodified lines
11441155 args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen);
11451156 xfs_alloc_fix_len(args);
11461157 gtdiff = xfs_alloc_compute_diff(args->agbno, args->len,
1147− args->alignment, gtbnoa, gtlena, &gtnew);
1158+ args->alignment, args->userdata, gtbnoa,
1159+ gtlena, &gtnew);
11481160
11491161 error = xfs_alloc_find_best_extent(args,
11501162 &bno_cur_gt, &bno_cur_lt,
@@ -1203,7 +1215,7 @@ restart: · 52 unmodified lines
12031215 }
12041216 rlen = args->len;
12051217 (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment,
1206− ltbnoa, ltlena, &ltnew);
1218+ args->userdata, ltbnoa, ltlena, &ltnew);
12071219 ASSERT(ltnew >= ltbno);
12081220 ASSERT(ltnew + rlen <= ltbnoa + ltlena);
12091221 ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
fs/xfs/xfs_bmap_btree.h+2−0
@@ -196,6 +196,8 @@ typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; · 195 unmodified lines
196196 #define XFS_BMDR_SPACE_CALC(nrecs) \
197197 (int)(sizeof(xfs_bmdr_block_t) + \
198198 ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t))))
199+#define XFS_BMAP_BMDR_SPACE(bb) \
200+ (XFS_BMDR_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs)))
199201
200202 /*
201203 * Maximum number of bmap btree levels.
fs/xfs/xfs_buf_item.c+58−29
@@ -140,6 +140,16 @@ xfs_buf_item_size( · 139 unmodified lines
140140
141141 ASSERT(bip->bli_flags & XFS_BLI_LOGGED);
142142
143+ if (bip->bli_flags & XFS_BLI_ORDERED) {
144+ /*
145+ * The buffer has been logged just to order it.
146+ * It is not being included in the transaction
147+ * commit, so no vectors are used at all.
148+ */
149+ trace_xfs_buf_item_size_ordered(bip);
150+ return XFS_LOG_VEC_ORDERED;
151+ }
152+
143153 /*
144154 * the vector count is based on the number of buffer vectors we have
145155 * dirty bits in. This will only be greater than one when we have a
@@ -212,6 +222,7 @@ xfs_buf_item_format_segment( · 66 unmodified lines
212222 goto out;
213223 }
214224
225+
215226 /*
216227 * Fill in an iovec for each set of contiguous chunks.
217228 */
@@ -299,18 +310,36 @@ xfs_buf_item_format( · 81 unmodified lines
299310
300311 /*
301312 * If it is an inode buffer, transfer the in-memory state to the
302− * format flags and clear the in-memory state. We do not transfer
313+ * format flags and clear the in-memory state.
314+ *
315+ * For buffer based inode allocation, we do not transfer
303316 * this state if the inode buffer allocation has not yet been committed
304317 * to the log as setting the XFS_BLI_INODE_BUF flag will prevent
305318 * correct replay of the inode allocation.
319+ *
320+ * For icreate item based inode allocation, the buffers aren't written
321+ * to the journal during allocation, and hence we should always tag the
322+ * buffer as an inode buffer so that the correct unlinked list replay
323+ * occurs during recovery.
306324 */
307325 if (bip->bli_flags & XFS_BLI_INODE_BUF) {
308− if (!((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
326+ if (xfs_sb_version_hascrc(&lip->li_mountp->m_sb) ||
327+ !((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
309328 xfs_log_item_in_current_chkpt(lip)))
310329 bip->__bli_format.blf_flags |= XFS_BLF_INODE_BUF;
311330 bip->bli_flags &= ~XFS_BLI_INODE_BUF;
312331 }
313332
333+ if ((bip->bli_flags & (XFS_BLI_ORDERED|XFS_BLI_STALE)) ==
334+ XFS_BLI_ORDERED) {
335+ /*
336+ * The buffer has been logged just to order it. It is not being
337+ * included in the transaction commit, so don't format it.
338+ */
339+ trace_xfs_buf_item_format_ordered(bip);
340+ return;
341+ }
342+
314343 for (i = 0; i < bip->bli_format_count; i++) {
315344 vecp = xfs_buf_item_format_segment(bip, vecp, offset,
316345 &bip->bli_formats[i]);
@@ -340,6 +369,7 @@ xfs_buf_item_pin( · 23 unmodified lines
340369
341370 ASSERT(atomic_read(&bip->bli_refcount) > 0);
342371 ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
372+ (bip->bli_flags & XFS_BLI_ORDERED) ||
343373 (bip->bli_flags & XFS_BLI_STALE));
344374
345375 trace_xfs_buf_item_pin(bip);
@@ -512,8 +542,9 @@ xfs_buf_item_unlock( · 166 unmodified lines
512542 {
513543 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
514544 struct xfs_buf *bp = bip->bli_buf;
515− int aborted, clean, i;
516− uint hold;
545+ bool clean;
546+ bool aborted;
547+ int flags;
517548
518549 /* Clear the buffer's association with this transaction. */
519550 bp->b_transp = NULL;
@@ -524,23 +555,21 @@ xfs_buf_item_unlock( · 4 unmodified lines
524555 * (cancelled) buffers at unpin time, but we'll never go through the
525556 * pin/unpin cycle if we abort inside commit.
526557 */
527− aborted = (lip->li_flags & XFS_LI_ABORTED) != 0;
528−
558+ aborted = (lip->li_flags & XFS_LI_ABORTED) ? true : false;
529559 /*
530− * Before possibly freeing the buf item, determine if we should
531− * release the buffer at the end of this routine.
560+ * Before possibly freeing the buf item, copy the per-transaction state
561+ * so we can reference it safely later after clearing it from the
562+ * buffer log item.
532563 */
533− hold = bip->bli_flags & XFS_BLI_HOLD;
534−
535− /* Clear the per transaction state. */
536− bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_HOLD);
564+ flags = bip->bli_flags;
565+ bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_HOLD | XFS_BLI_ORDERED);
537566
538567 /*
539568 * If the buf item is marked stale, then don't do anything. We'll
540569 * unlock the buffer and free the buf item when the buffer is unpinned
541570 * for the last time.
542571 */
543− if (bip->bli_flags & XFS_BLI_STALE) {
572+ if (flags & XFS_BLI_STALE) {
544573 trace_xfs_buf_item_unlock_stale(bip);
545574 ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL);
546575 if (!aborted) {
@@ -557,13 +586,19 @@ xfs_buf_item_unlock( · 10 unmodified lines
557586 * be the only reference to the buf item, so we free it anyway
558587 * regardless of whether it is dirty or not. A dirty abort implies a
559588 * shutdown, anyway.
589+ *
590+ * Ordered buffers are dirty but may have no recorded changes, so ensure
591+ * we only release clean items here.
560592 */
561− clean = 1;
562− for (i = 0; i < bip->bli_format_count; i++) {
563− if (!xfs_bitmap_empty(bip->bli_formats[i].blf_data_map,
564− bip->bli_formats[i].blf_map_size)) {
565− clean = 0;
566− break;
593+ clean = (flags & XFS_BLI_DIRTY) ? false : true;
594+ if (clean) {
595+ int i;
596+ for (i = 0; i < bip->bli_format_count; i++) {
597+ if (!xfs_bitmap_empty(bip->bli_formats[i].blf_data_map,
598+ bip->bli_formats[i].blf_map_size)) {
599+ clean = false;
600+ break;
601+ }
567602 }
568603 }
569604 if (clean)
@@ -576,7 +611,7 @@ xfs_buf_item_unlock( · 6 unmodified lines
576611 } else
577612 atomic_dec(&bip->bli_refcount);
578613
579− if (!hold)
614+ if (!(flags & XFS_BLI_HOLD))
580615 xfs_buf_relse(bp);
581616 }
582617
@@ -841,12 +876,6 @@ xfs_buf_item_log( · 258 unmodified lines
841876 uint end;
842877 struct xfs_buf *bp = bip->bli_buf;
843878
844− /*
845− * Mark the item as having some dirty data for
846− * quick reference in xfs_buf_item_dirty.
847− */
848− bip->bli_flags |= XFS_BLI_DIRTY;
849−
850879 /*
851880 * walk each buffer segment and mark them dirty appropriately.
852881 */
@@ -873,7 +902,7 @@ xfs_buf_item_log( · 20 unmodified lines
873902
874903
875904 /*
876− * Return 1 if the buffer has some data that has been logged (at any
905+ * Return 1 if the buffer has been logged or ordered in a transaction (at any
877906 * point, not just the current transaction) and 0 if not.
878907 */
879908 uint
@@ -907,11 +936,11 @@ void · 27 unmodified lines
907936 xfs_buf_item_relse(
908937 xfs_buf_t *bp)
909938 {
910− xfs_buf_log_item_t *bip;
939+ xfs_buf_log_item_t *bip = bp->b_fspriv;
911940
912941 trace_xfs_buf_item_relse(bp, _RET_IP_);
942+ ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
913943
914− bip = bp->b_fspriv;
915944 bp->b_fspriv = bip->bli_item.li_bio_list;
916945 if (bp->b_fspriv == NULL)
917946 bp->b_iodone = NULL;
fs/xfs/xfs_buf_item.h+3−1
@@ -120,6 +120,7 @@ xfs_blft_from_flags(struct xfs_buf_log_format *blf) · 119 unmodified lines
120120 #define XFS_BLI_INODE_ALLOC_BUF 0x10
121121 #define XFS_BLI_STALE_INODE 0x20
122122 #define XFS_BLI_INODE_BUF 0x40
123+#define XFS_BLI_ORDERED 0x80
123124
124125 #define XFS_BLI_FLAGS \
125126 { XFS_BLI_HOLD, "HOLD" }, \
@@ -128,7 +129,8 @@ xfs_blft_from_flags(struct xfs_buf_log_format *blf) · 2 unmodified lines
128129 { XFS_BLI_LOGGED, "LOGGED" }, \
129130 { XFS_BLI_INODE_ALLOC_BUF, "INODE_ALLOC" }, \
130131 { XFS_BLI_STALE_INODE, "STALE_INODE" }, \
131− { XFS_BLI_INODE_BUF, "INODE_BUF" }
132+ { XFS_BLI_INODE_BUF, "INODE_BUF" }, \
133+ { XFS_BLI_ORDERED, "ORDERED" }
132134
133135
134136 #ifdef __KERNEL__
fs/xfs/xfs_dfrag.c+5−3
@@ -24,6 +24,9 @@ · 23 unmodified lines
2424 #include "xfs_ag.h"
2525 #include "xfs_mount.h"
2626 #include "xfs_bmap_btree.h"
27+#include "xfs_alloc_btree.h"
28+#include "xfs_ialloc_btree.h"
29+#include "xfs_btree.h"
2730 #include "xfs_dinode.h"
2831 #include "xfs_inode.h"
2932 #include "xfs_inode_item.h"
@@ -182,7 +185,7 @@ xfs_swap_extents_check_format( · 152 unmodified lines
182185 */
183186 if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE) {
184187 if (XFS_IFORK_BOFF(ip) &&
185− tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip))
188+ XFS_BMAP_BMDR_SPACE(tip->i_df.if_broot) > XFS_IFORK_BOFF(ip))
186189 return EINVAL;
187190 if (XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) <=
188191 XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK))
@@ -192,9 +195,8 @@ xfs_swap_extents_check_format( · 3 unmodified lines
192195 /* Reciprocal target->temp btree format checks */
193196 if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) {
194197 if (XFS_IFORK_BOFF(tip) &&
195− ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip))
198+ XFS_BMAP_BMDR_SPACE(ip->i_df.if_broot) > XFS_IFORK_BOFF(tip))
196199 return EINVAL;
197−
198200 if (XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) <=
199201 XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK))
200202 return EINVAL;
fs/xfs/xfs_dir2_leaf.c+3−0
@@ -1108,6 +1108,7 @@ xfs_dir2_leaf_readbuf( · 1107 unmodified lines
11081108 struct xfs_mount *mp = dp->i_mount;
11091109 struct xfs_buf *bp = *bpp;
11101110 struct xfs_bmbt_irec *map = mip->map;
1111+ struct blk_plug plug;
11111112 int error = 0;
11121113 int length;
11131114 int i;
@@ -1236,6 +1237,7 @@ xfs_dir2_leaf_readbuf( · 122 unmodified lines
12361237 /*
12371238 * Do we need more readahead?
12381239 */
1240+ blk_start_plug(&plug);
12391241 for (mip->ra_index = mip->ra_offset = i = 0;
12401242 mip->ra_want > mip->ra_current && i < mip->map_blocks;
12411243 i += mp->m_dirblkfsbs) {
@@ -1287,6 +1289,7 @@ xfs_dir2_leaf_readbuf( · 45 unmodified lines
12871289 }
12881290 }
12891291 }
1292+ blk_finish_plug(&plug);
12901293
12911294 out:
12921295 *bpp = bp;
fs/xfs/xfs_dquot.c+8−8
@@ -570,13 +570,13 @@ xfs_qm_dqtobp( · 569 unmodified lines
570570 xfs_buf_t **O_bpp,
571571 uint flags)
572572 {
573− xfs_bmbt_irec_t map;
574− int nmaps = 1, error;
575− xfs_buf_t *bp;
576− xfs_inode_t *quotip = XFS_DQ_TO_QIP(dqp);
577− xfs_mount_t *mp = dqp->q_mount;
578− xfs_dqid_t id = be32_to_cpu(dqp->q_core.d_id);
579− xfs_trans_t *tp = (tpp ? *tpp : NULL);
573+ struct xfs_bmbt_irec map;
574+ int nmaps = 1, error;
575+ struct xfs_buf *bp;
576+ struct xfs_inode *quotip = xfs_dq_to_quota_inode(dqp);
577+ struct xfs_mount *mp = dqp->q_mount;
578+ xfs_dqid_t id = be32_to_cpu(dqp->q_core.d_id);
579+ struct xfs_trans *tp = (tpp ? *tpp : NULL);
580580
581581 dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk;
582582
@@ -804,7 +804,7 @@ xfs_qm_dqget( · 221 unmodified lines
804804 xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */
805805 {
806806 struct xfs_quotainfo *qi = mp->m_quotainfo;
807− struct radix_tree_root *tree = XFS_DQUOT_TREE(qi, type);
807+ struct radix_tree_root *tree = xfs_dquot_tree(qi, type);
808808 struct xfs_dquot *dqp;
809809 int error;
810810
fs/xfs/xfs_dquot.h+0−4
@@ -143,10 +143,6 @@ static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type) · 142 unmodified lines
143143 #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)
144144 #define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQ_PROJ)
145145 #define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQ_GROUP)
146−#define XFS_DQ_TO_QINF(dqp) ((dqp)->q_mount->m_quotainfo)
147−#define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \
148− XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \
149− XFS_DQ_TO_QINF(dqp)->qi_gquotaip)
150146
151147 extern int xfs_qm_dqread(struct xfs_mount *, xfs_dqid_t, uint,
152148 uint, struct xfs_dquot **);
fs/xfs/xfs_fsops.c+1−1
@@ -176,7 +176,7 @@ xfs_growfs_data_private( · 175 unmodified lines
176176 if (!bp)
177177 return EIO;
178178 if (bp->b_error) {
179− int error = bp->b_error;
179+ error = bp->b_error;
180180 xfs_buf_relse(bp);
181181 return error;
182182 }
fs/xfs/xfs_ialloc.c+53−21
@@ -38,6 +38,7 @@ · 37 unmodified lines
3838 #include "xfs_bmap.h"
3939 #include "xfs_cksum.h"
4040 #include "xfs_buf_item.h"
41+#include "xfs_icreate_item.h"
4142
4243
4344 /*
@@ -150,12 +151,16 @@ xfs_check_agi_freecount( · 106 unmodified lines
150151 #endif
151152
152153 /*
153− * Initialise a new set of inodes.
154+ * Initialise a new set of inodes. When called without a transaction context
155+ * (e.g. from recovery) we initiate a delayed write of the inode buffers rather
156+ * than logging them (which in a transaction context puts them into the AIL
157+ * for writeback rather than the xfsbufd queue).
154158 */
155−STATIC int
159+int
156160 xfs_ialloc_inode_init(
157161 struct xfs_mount *mp,
158162 struct xfs_trans *tp,
163+ struct list_head *buffer_list,
159164 xfs_agnumber_t agno,
160165 xfs_agblock_t agbno,
161166 xfs_agblock_t length,
@@ -208,6 +213,18 @@ xfs_ialloc_inode_init( · 46 unmodified lines
208213 version = 3;
209214 ino = XFS_AGINO_TO_INO(mp, agno,
210215 XFS_OFFBNO_TO_AGINO(mp, agbno, 0));
216+
217+ /*
218+ * log the initialisation that is about to take place as an
219+ * logical operation. This means the transaction does not
220+ * need to log the physical changes to the inode buffers as log
221+ * recovery will know what initialisation is actually needed.
222+ * Hence we only need to log the buffers as "ordered" buffers so
223+ * they track in the AIL as if they were physically logged.
224+ */
225+ if (tp)
226+ xfs_icreate_log(tp, agno, agbno, XFS_IALLOC_INODES(mp),
227+ mp->m_sb.sb_inodesize, length, gen);
211228 } else if (xfs_sb_version_hasnlink(&mp->m_sb))
212229 version = 2;
213230 else
@@ -223,13 +240,8 @@ xfs_ialloc_inode_init( · 9 unmodified lines
223240 XBF_UNMAPPED);
224241 if (!fbuf)
225242 return ENOMEM;
226− /*
227− * Initialize all inodes in this buffer and then log them.
228− *
229− * XXX: It would be much better if we had just one transaction
230− * to log a whole cluster of inodes instead of all the
231− * individual transactions causing a lot of log traffic.
232− */
243+
244+ /* Initialize the inode buffers and log them appropriately. */
233245 fbuf->b_ops = &xfs_inode_buf_ops;
234246 xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length));
235247 for (i = 0; i < ninodes; i++) {
@@ -247,18 +259,39 @@ xfs_ialloc_inode_init( · 11 unmodified lines
247259 ino++;
248260 uuid_copy(&free->di_uuid, &mp->m_sb.sb_uuid);
249261 xfs_dinode_calc_crc(mp, free);
250− } else {
262+ } else if (tp) {
251263 /* just log the inode core */
252264 xfs_trans_log_buf(tp, fbuf, ioffset,
253265 ioffset + isize - 1);
254266 }
255267 }
256− if (version == 3) {
257− /* need to log the entire buffer */
258− xfs_trans_log_buf(tp, fbuf, 0,
259− BBTOB(fbuf->b_length) - 1);
268+
269+ if (tp) {
270+ /*
271+ * Mark the buffer as an inode allocation buffer so it
272+ * sticks in AIL at the point of this allocation
273+ * transaction. This ensures the they are on disk before
274+ * the tail of the log can be moved past this
275+ * transaction (i.e. by preventing relogging from moving
276+ * it forward in the log).
277+ */
278+ xfs_trans_inode_alloc_buf(tp, fbuf);
279+ if (version == 3) {
280+ /*
281+ * Mark the buffer as ordered so that they are
282+ * not physically logged in the transaction but
283+ * still tracked in the AIL as part of the
284+ * transaction and pin the log appropriately.
285+ */
286+ xfs_trans_ordered_buf(tp, fbuf);
287+ xfs_trans_log_buf(tp, fbuf, 0,
288+ BBTOB(fbuf->b_length) - 1);
289+ }
290+ } else {
291+ fbuf->b_flags |= XBF_DONE;
292+ xfs_buf_delwri_queue(fbuf, buffer_list);
293+ xfs_buf_relse(fbuf);
260294 }
261− xfs_trans_inode_alloc_buf(tp, fbuf);
262295 }
263296 return 0;
264297 }
@@ -303,7 +336,7 @@ xfs_ialloc_ag_alloc( · 38 unmodified lines
303336 * First try to allocate inodes contiguous with the last-allocated
304337 * chunk of inodes. If the filesystem is striped, this will fill
305338 * an entire stripe unit with inodes.
306− */
339+ */
307340 agi = XFS_BUF_TO_AGI(agbp);
308341 newino = be32_to_cpu(agi->agi_newino);
309342 agno = be32_to_cpu(agi->agi_seqno);
@@ -402,7 +435,7 @@ xfs_ialloc_ag_alloc( · 92 unmodified lines
402435 * rather than a linear progression to prevent the next generation
403436 * number from being easily guessable.
404437 */
405− error = xfs_ialloc_inode_init(args.mp, tp, agno, args.agbno,
438+ error = xfs_ialloc_inode_init(args.mp, tp, NULL, agno, args.agbno,
406439 args.len, prandom_u32());
407440
408441 if (error)
@@ -615,8 +648,7 @@ xfs_ialloc_get_rec( · 206 unmodified lines
615648 struct xfs_btree_cur *cur,
616649 xfs_agino_t agino,
617650 xfs_inobt_rec_incore_t *rec,
618− int *done,
619− int left)
651+ int *done)
620652 {
621653 int error;
622654 int i;
@@ -724,12 +756,12 @@ xfs_dialloc_ag( · 101 unmodified lines
724756 pag->pagl_leftrec != NULLAGINO &&
725757 pag->pagl_rightrec != NULLAGINO) {
726758 error = xfs_ialloc_get_rec(tcur, pag->pagl_leftrec,
727− &trec, &doneleft, 1);
759+ &trec, &doneleft);
728760 if (error)
729761 goto error1;
730762
731763 error = xfs_ialloc_get_rec(cur, pag->pagl_rightrec,
732− &rec, &doneright, 0);
764+ &rec, &doneright);
733765 if (error)
734766 goto error1;
735767 } else {
fs/xfs/xfs_ialloc.h+8−0
@@ -150,6 +150,14 @@ int xfs_inobt_lookup(struct xfs_btree_cur *cur, xfs_agino_t ino, · 149 unmodified lines
150150 int xfs_inobt_get_rec(struct xfs_btree_cur *cur,
151151 xfs_inobt_rec_incore_t *rec, int *stat);
152152
153+/*
154+ * Inode chunk initialisation routine
155+ */
156+int xfs_ialloc_inode_init(struct xfs_mount *mp, struct xfs_trans *tp,
157+ struct list_head *buffer_list,
158+ xfs_agnumber_t agno, xfs_agblock_t agbno,
159+ xfs_agblock_t length, unsigned int gen);
160+
153161 extern const struct xfs_buf_ops xfs_agi_buf_ops;
154162
155163 #endif /* __XFS_IALLOC_H__ */
fs/xfs/xfs_icache.c+2−1
@@ -335,7 +335,8 @@ xfs_iget_cache_miss( · 334 unmodified lines
335335 iflags = XFS_INEW;
336336 if (flags & XFS_IGET_DONTCACHE)
337337 iflags |= XFS_IDONTCACHE;
338− ip->i_udquot = ip->i_gdquot = NULL;
338+ ip->i_udquot = NULL;
339+ ip->i_gdquot = NULL;
339340 xfs_iflags_set(ip, iflags);
340341
341342 /* insert the new inode */
fs/xfs/xfs_icache.h+0−1
@@ -40,7 +40,6 @@ void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip); · 39 unmodified lines
4040 int xfs_icache_free_eofblocks(struct xfs_mount *, struct xfs_eofblocks *);
4141 void xfs_eofblocks_worker(struct work_struct *);
4242
43−int xfs_sync_inode_grab(struct xfs_inode *ip);
4443 int xfs_inode_ag_iterator(struct xfs_mount *mp,
4544 int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag,
4645 int flags, void *args),
fs/xfs/xfs_icreate_item.c+195−0
@@ -0,0 +1,195 @@
1+/*
2+ * Copyright (c) 2008-2010, 2013 Dave Chinner
3+ * All Rights Reserved.
4+ *
5+ * This program is free software; you can redistribute it and/or
6+ * modify it under the terms of the GNU General Public License as
7+ * published by the Free Software Foundation.
8+ *
9+ * This program is distributed in the hope that it would be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program; if not, write the Free Software Foundation,
16+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+ */
18+#include "xfs.h"
19+#include "xfs_fs.h"
20+#include "xfs_types.h"
21+#include "xfs_bit.h"
22+#include "xfs_log.h"
23+#include "xfs_inum.h"
24+#include "xfs_trans.h"
25+#include "xfs_buf_item.h"
26+#include "xfs_sb.h"
27+#include "xfs_ag.h"
28+#include "xfs_dir2.h"
29+#include "xfs_mount.h"
30+#include "xfs_trans_priv.h"
31+#include "xfs_bmap_btree.h"
32+#include "xfs_alloc_btree.h"
33+#include "xfs_ialloc_btree.h"
34+#include "xfs_attr_sf.h"
35+#include "xfs_dinode.h"
36+#include "xfs_inode.h"
37+#include "xfs_inode_item.h"
38+#include "xfs_btree.h"
39+#include "xfs_ialloc.h"
40+#include "xfs_error.h"
41+#include "xfs_icreate_item.h"
42+
43+kmem_zone_t *xfs_icreate_zone; /* inode create item zone */
44+
45+static inline struct xfs_icreate_item *ICR_ITEM(struct xfs_log_item *lip)
46+{
47+ return container_of(lip, struct xfs_icreate_item, ic_item);
48+}
49+
50+/*
51+ * This returns the number of iovecs needed to log the given inode item.
52+ *
53+ * We only need one iovec for the icreate log structure.
54+ */
55+STATIC uint
56+xfs_icreate_item_size(
57+ struct xfs_log_item *lip)
58+{
59+ return 1;
60+}
61+
62+/*
63+ * This is called to fill in the vector of log iovecs for the
64+ * given inode create log item.
65+ */
66+STATIC void
67+xfs_icreate_item_format(
68+ struct xfs_log_item *lip,
69+ struct xfs_log_iovec *log_vector)
70+{
71+ struct xfs_icreate_item *icp = ICR_ITEM(lip);
72+
73+ log_vector->i_addr = (xfs_caddr_t)&icp->ic_format;
74+ log_vector->i_len = sizeof(struct xfs_icreate_log);
75+ log_vector->i_type = XLOG_REG_TYPE_ICREATE;
76+}
77+
78+
79+/* Pinning has no meaning for the create item, so just return. */
80+STATIC void
81+xfs_icreate_item_pin(
82+ struct xfs_log_item *lip)
83+{
84+}
85+
86+
87+/* pinning has no meaning for the create item, so just return. */
88+STATIC void
89+xfs_icreate_item_unpin(
90+ struct xfs_log_item *lip,
91+ int remove)
92+{
93+}
94+
95+STATIC void
96+xfs_icreate_item_unlock(
97+ struct xfs_log_item *lip)
98+{
99+ struct xfs_icreate_item *icp = ICR_ITEM(lip);
100+
101+ if (icp->ic_item.li_flags & XFS_LI_ABORTED)
102+ kmem_zone_free(xfs_icreate_zone, icp);
103+ return;
104+}
105+
106+/*
107+ * Because we have ordered buffers being tracked in the AIL for the inode
108+ * creation, we don't need the create item after this. Hence we can free
109+ * the log item and return -1 to tell the caller we're done with the item.
110+ */
111+STATIC xfs_lsn_t
112+xfs_icreate_item_committed(
113+ struct xfs_log_item *lip,
114+ xfs_lsn_t lsn)
115+{
116+ struct xfs_icreate_item *icp = ICR_ITEM(lip);
117+
118+ kmem_zone_free(xfs_icreate_zone, icp);
119+ return (xfs_lsn_t)-1;
120+}
121+
122+/* item can never get into the AIL */
123+STATIC uint
124+xfs_icreate_item_push(
125+ struct xfs_log_item *lip,
126+ struct list_head *buffer_list)
127+{
128+ ASSERT(0);
129+ return XFS_ITEM_SUCCESS;
130+}
131+
132+/* Ordered buffers do the dependency tracking here, so this does nothing. */
133+STATIC void
134+xfs_icreate_item_committing(
135+ struct xfs_log_item *lip,
136+ xfs_lsn_t lsn)
137+{
138+}
139+
140+/*
141+ * This is the ops vector shared by all buf log items.
142+ */
143+static struct xfs_item_ops xfs_icreate_item_ops = {
144+ .iop_size = xfs_icreate_item_size,
145+ .iop_format = xfs_icreate_item_format,
146+ .iop_pin = xfs_icreate_item_pin,
147+ .iop_unpin = xfs_icreate_item_unpin,
148+ .iop_push = xfs_icreate_item_push,
149+ .iop_unlock = xfs_icreate_item_unlock,
150+ .iop_committed = xfs_icreate_item_committed,
151+ .iop_committing = xfs_icreate_item_committing,
152+};
153+
154+
155+/*
156+ * Initialize the inode log item for a newly allocated (in-core) inode.
157+ *
158+ * Inode extents can only reside within an AG. Hence specify the starting
159+ * block for the inode chunk by offset within an AG as well as the
160+ * length of the allocated extent.
161+ *
162+ * This joins the item to the transaction and marks it dirty so
163+ * that we don't need a separate call to do this, nor does the
164+ * caller need to know anything about the icreate item.
165+ */
166+void
167+xfs_icreate_log(
168+ struct xfs_trans *tp,
169+ xfs_agnumber_t agno,
170+ xfs_agblock_t agbno,
171+ unsigned int count,
172+ unsigned int inode_size,
173+ xfs_agblock_t length,
174+ unsigned int generation)
175+{
176+ struct xfs_icreate_item *icp;
177+
178+ icp = kmem_zone_zalloc(xfs_icreate_zone, KM_SLEEP);
179+
180+ xfs_log_item_init(tp->t_mountp, &icp->ic_item, XFS_LI_ICREATE,
181+ &xfs_icreate_item_ops);
182+
183+ icp->ic_format.icl_type = XFS_LI_ICREATE;
184+ icp->ic_format.icl_size = 1; /* single vector */
185+ icp->ic_format.icl_ag = cpu_to_be32(agno);
186+ icp->ic_format.icl_agbno = cpu_to_be32(agbno);
187+ icp->ic_format.icl_count = cpu_to_be32(count);
188+ icp->ic_format.icl_isize = cpu_to_be32(inode_size);
189+ icp->ic_format.icl_length = cpu_to_be32(length);
190+ icp->ic_format.icl_gen = cpu_to_be32(generation);
191+
192+ xfs_trans_add_item(tp, &icp->ic_item);
193+ tp->t_flags |= XFS_TRANS_DIRTY;
194+ icp->ic_item.li_desc->lid_flags |= XFS_LID_DIRTY;
195+}
fs/xfs/xfs_icreate_item.h+52−0
@@ -0,0 +1,52 @@
1+/*
2+ * Copyright (c) 2008-2010, Dave Chinner
3+ * All Rights Reserved.
4+ *
5+ * This program is free software; you can redistribute it and/or
6+ * modify it under the terms of the GNU General Public License as
7+ * published by the Free Software Foundation.
8+ *
9+ * This program is distributed in the hope that it would be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program; if not, write the Free Software Foundation,
16+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+ */
18+#ifndef XFS_ICREATE_ITEM_H
19+#define XFS_ICREATE_ITEM_H 1
20+
21+/*
22+ * on disk log item structure
23+ *
24+ * Log recovery assumes the first two entries are the type and size and they fit
25+ * in 32 bits. Also in host order (ugh) so they have to be 32 bit aligned so
26+ * decoding can be done correctly.
27+ */
28+struct xfs_icreate_log {
29+ __uint16_t icl_type; /* type of log format structure */
30+ __uint16_t icl_size; /* size of log format structure */
31+ __be32 icl_ag; /* ag being allocated in */
32+ __be32 icl_agbno; /* start block of inode range */
33+ __be32 icl_count; /* number of inodes to initialise */
34+ __be32 icl_isize; /* size of inodes */
35+ __be32 icl_length; /* length of extent to initialise */
36+ __be32 icl_gen; /* inode generation number to use */
37+};
38+
39+/* in memory log item structure */
40+struct xfs_icreate_item {
41+ struct xfs_log_item ic_item;
42+ struct xfs_icreate_log ic_format;
43+};
44+
45+extern kmem_zone_t *xfs_icreate_zone; /* inode create item zone */
46+
47+void xfs_icreate_log(struct xfs_trans *tp, xfs_agnumber_t agno,
48+ xfs_agblock_t agbno, unsigned int count,
49+ unsigned int inode_size, xfs_agblock_t length,
50+ unsigned int generation);
51+
52+#endif /* XFS_ICREATE_ITEM_H */
fs/xfs/xfs_inode.c+32−36
@@ -1028,6 +1028,11 @@ xfs_dinode_calc_crc( · 1027 unmodified lines
10281028
10291029 /*
10301030 * Read the disk inode attributes into the in-core inode structure.
1031+ *
1032+ * If we are initialising a new inode and we are not utilising the
1033+ * XFS_MOUNT_IKEEP inode cluster mode, we can simple build the new inode core
1034+ * with a random generation number. If we are keeping inodes around, we need to
1035+ * read the inode cluster to get the existing generation number off disk.
10311036 */
10321037 int
10331038 xfs_iread(
@@ -1047,6 +1052,22 @@ xfs_iread( · 13 unmodified lines
10471052 if (error)
10481053 return error;
10491054
1055+ /* shortcut IO on inode allocation if possible */
1056+ if ((iget_flags & XFS_IGET_CREATE) &&
1057+ !(mp->m_flags & XFS_MOUNT_IKEEP)) {
1058+ /* initialise the on-disk inode core */
1059+ memset(&ip->i_d, 0, sizeof(ip->i_d));
1060+ ip->i_d.di_magic = XFS_DINODE_MAGIC;
1061+ ip->i_d.di_gen = prandom_u32();
1062+ if (xfs_sb_version_hascrc(&mp->m_sb)) {
1063+ ip->i_d.di_version = 3;
1064+ ip->i_d.di_ino = ip->i_ino;
1065+ uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_uuid);
1066+ } else
1067+ ip->i_d.di_version = 2;
1068+ return 0;
1069+ }
1070+
10501071 /*
10511072 * Get pointers to the on-disk inode and the buffer containing it.
10521073 */
@@ -1133,17 +1154,16 @@ xfs_iread( · 80 unmodified lines
11331154 xfs_buf_set_ref(bp, XFS_INO_REF);
11341155
11351156 /*
1136− * Use xfs_trans_brelse() to release the buffer containing the
1137− * on-disk inode, because it was acquired with xfs_trans_read_buf()
1138− * in xfs_imap_to_bp() above. If tp is NULL, this is just a normal
1157+ * Use xfs_trans_brelse() to release the buffer containing the on-disk
1158+ * inode, because it was acquired with xfs_trans_read_buf() in
1159+ * xfs_imap_to_bp() above. If tp is NULL, this is just a normal
11391160 * brelse(). If we're within a transaction, then xfs_trans_brelse()
11401161 * will only release the buffer if it is not dirty within the
11411162 * transaction. It will be OK to release the buffer in this case,
1142− * because inodes on disk are never destroyed and we will be
1143− * locking the new in-core inode before putting it in the hash
1144− * table where other processes can find it. Thus we don't have
1145− * to worry about the inode being changed just because we released
1146− * the buffer.
1163+ * because inodes on disk are never destroyed and we will be locking the
1164+ * new in-core inode before putting it in the cache where other
1165+ * processes can find it. Thus we don't have to worry about the inode
1166+ * being changed just because we released the buffer.
11471167 */
11481168 out_brelse:
11491169 xfs_trans_brelse(tp, bp);
@@ -2028,8 +2048,6 @@ xfs_ifree( · 878 unmodified lines
20282048 int error;
20292049 int delete;
20302050 xfs_ino_t first_ino;
2031− xfs_dinode_t *dip;
2032− xfs_buf_t *ibp;
20332051
20342052 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
20352053 ASSERT(ip->i_d.di_nlink == 0);
@@ -2042,14 +2060,13 @@ xfs_ifree( · 6 unmodified lines
20422060 * Pull the on-disk inode from the AGI unlinked list.
20432061 */
20442062 error = xfs_iunlink_remove(tp, ip);
2045− if (error != 0) {
2063+ if (error)
20462064 return error;
2047− }
20482065
20492066 error = xfs_difree(tp, ip->i_ino, flist, &delete, &first_ino);
2050− if (error != 0) {
2067+ if (error)
20512068 return error;
2052− }
2069+
20532070 ip->i_d.di_mode = 0; /* mark incore inode as free */
20542071 ip->i_d.di_flags = 0;
20552072 ip->i_d.di_dmevmask = 0;
@@ -2061,31 +2078,10 @@ xfs_ifree( · 5 unmodified lines
20612078 * by reincarnations of this inode.
20622079 */
20632080 ip->i_d.di_gen++;
2064−
20652081 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
20662082
2067− error = xfs_imap_to_bp(ip->i_mount, tp, &ip->i_imap, &dip, &ibp,
2068− 0, 0);
2069− if (error)
2070− return error;
2071−
2072− /*
2073− * Clear the on-disk di_mode. This is to prevent xfs_bulkstat
2074− * from picking up this inode when it is reclaimed (its incore state
2075− * initialzed but not flushed to disk yet). The in-core di_mode is
2076− * already cleared and a corresponding transaction logged.
2077− * The hack here just synchronizes the in-core to on-disk
2078− * di_mode value in advance before the actual inode sync to disk.
2079− * This is OK because the inode is already unlinked and would never
2080− * change its di_mode again for this inode generation.
2081− * This is a temporary hack that would require a proper fix
2082− * in the future.
2083− */
2084− dip->di_mode = 0;
2085−
2086− if (delete) {
2083+ if (delete)
20872084 error = xfs_ifree_cluster(ip, tp, first_ino);
2088− }
20892085
20902086 return error;
20912087 }
fs/xfs/xfs_iomap.c+13−0
@@ -283,6 +283,15 @@ xfs_iomap_eof_want_preallocate( · 282 unmodified lines
283283 if (offset + count <= XFS_ISIZE(ip))
284284 return 0;
285285
286+ /*
287+ * If the file is smaller than the minimum prealloc and we are using
288+ * dynamic preallocation, don't do any preallocation at all as it is
289+ * likely this is the only write to the file that is going to be done.
290+ */
291+ if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) &&
292+ XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_writeio_blocks))
293+ return 0;
294+
286295 /*
287296 * If there are any real blocks past eof, then don't
288297 * do any speculative allocation.
@@ -345,6 +354,10 @@ xfs_iomap_eof_prealloc_initial_size( · 56 unmodified lines
345354 if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
346355 return 0;
347356
357+ /* If the file is small, then use the minimum prealloc */
358+ if (XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_dalign))
359+ return 0;
360+
348361 /*
349362 * As we write multiple pages, the offset will always align to the
350363 * start of a page and hence point to a hole at EOF. i.e. if the size is
fs/xfs/xfs_iops.c+2−1
@@ -987,7 +987,8 @@ xfs_fiemap_format( · 986 unmodified lines
987987 if (bmv->bmv_oflags & BMV_OF_PREALLOC)
988988 fiemap_flags |= FIEMAP_EXTENT_UNWRITTEN;
989989 else if (bmv->bmv_oflags & BMV_OF_DELALLOC) {
990− fiemap_flags |= FIEMAP_EXTENT_DELALLOC;
990+ fiemap_flags |= (FIEMAP_EXTENT_DELALLOC |
991+ FIEMAP_EXTENT_UNKNOWN);
991992 physical = 0; /* no block yet */
992993 }
993994 if (bmv->bmv_oflags & BMV_OF_LAST)
fs/xfs/xfs_itable.c+4−1
@@ -43,7 +43,7 @@ xfs_internal_inum( · 42 unmodified lines
4343 {
4444 return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
4545 (xfs_sb_version_hasquota(&mp->m_sb) &&
46− (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino)));
46+ xfs_is_quota_inode(&mp->m_sb, ino)));
4747 }
4848
4949 /*
@@ -383,11 +383,13 @@ xfs_bulkstat( · 333 unmodified lines
383383 * Also start read-ahead now for this chunk.
384384 */
385385 if (r.ir_freecount < XFS_INODES_PER_CHUNK) {
386+ struct blk_plug plug;
386387 /*
387388 * Loop over all clusters in the next chunk.
388389 * Do a readahead if there are any allocated
389390 * inodes in that cluster.
390391 */
392+ blk_start_plug(&plug);
391393 agbno = XFS_AGINO_TO_AGBNO(mp, r.ir_startino);
392394 for (chunkidx = 0;
393395 chunkidx < XFS_INODES_PER_CHUNK;
@@ -399,6 +401,7 @@ xfs_bulkstat( · 5 unmodified lines
399401 agbno, nbcluster,
400402 &xfs_inode_buf_ops);
401403 }
404+ blk_finish_plug(&plug);
402405 irbp->ir_startino = r.ir_startino;
403406 irbp->ir_freecount = r.ir_freecount;
404407 irbp->ir_free = r.ir_free;
fs/xfs/xfs_log.c+18−4
@@ -1963,6 +1963,10 @@ xlog_write_calc_vec_length( · 1962 unmodified lines
19631963 headers++;
19641964
19651965 for (lv = log_vector; lv; lv = lv->lv_next) {
1966+ /* we don't write ordered log vectors */
1967+ if (lv->lv_buf_len == XFS_LOG_VEC_ORDERED)
1968+ continue;
1969+
19661970 headers += lv->lv_niovecs;
19671971
19681972 for (i = 0; i < lv->lv_niovecs; i++) {
@@ -2216,7 +2220,7 @@ xlog_write( · 247 unmodified lines
22162220 index = 0;
22172221 lv = log_vector;
22182222 vecp = lv->lv_iovecp;
2219− while (lv && index < lv->lv_niovecs) {
2223+ while (lv && (!lv->lv_niovecs || index < lv->lv_niovecs)) {
22202224 void *ptr;
22212225 int log_offset;
22222226
@@ -2236,13 +2240,22 @@ xlog_write( · 13 unmodified lines
22362240 * This loop writes out as many regions as can fit in the amount
22372241 * of space which was allocated by xlog_state_get_iclog_space().
22382242 */
2239− while (lv && index < lv->lv_niovecs) {
2240− struct xfs_log_iovec *reg = &vecp[index];
2243+ while (lv && (!lv->lv_niovecs || index < lv->lv_niovecs)) {
2244+ struct xfs_log_iovec *reg;
22412245 struct xlog_op_header *ophdr;
22422246 int start_rec_copy;
22432247 int copy_len;
22442248 int copy_off;
2249+ bool ordered = false;
2250+
2251+ /* ordered log vectors have no regions to write */
2252+ if (lv->lv_buf_len == XFS_LOG_VEC_ORDERED) {
2253+ ASSERT(lv->lv_niovecs == 0);
2254+ ordered = true;
2255+ goto next_lv;
2256+ }
22452257
2258+ reg = &vecp[index];
22462259 ASSERT(reg->i_len % sizeof(__int32_t) == 0);
22472260 ASSERT((unsigned long)ptr % sizeof(__int32_t) == 0);
22482261
@@ -2302,12 +2315,13 @@ xlog_write( · 53 unmodified lines
23022315 break;
23032316
23042317 if (++index == lv->lv_niovecs) {
2318+next_lv:
23052319 lv = lv->lv_next;
23062320 index = 0;
23072321 if (lv)
23082322 vecp = lv->lv_iovecp;
23092323 }
2310− if (record_cnt == 0) {
2324+ if (record_cnt == 0 && ordered == false) {
23112325 if (!lv)
23122326 return 0;
23132327 break;
fs/xfs/xfs_log.h+4−1
@@ -88,7 +88,8 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) · 87 unmodified lines
8888 #define XLOG_REG_TYPE_UNMOUNT 17
8989 #define XLOG_REG_TYPE_COMMIT 18
9090 #define XLOG_REG_TYPE_TRANSHDR 19
91−#define XLOG_REG_TYPE_MAX 19
91+#define XLOG_REG_TYPE_ICREATE 20
92+#define XLOG_REG_TYPE_MAX 20
9293
9394 typedef struct xfs_log_iovec {
9495 void *i_addr; /* beginning address of region */
@@ -105,6 +106,8 @@ struct xfs_log_vec { · 10 unmodified lines
105106 int lv_buf_len; /* size of formatted buffer */
106107 };
107108
109+#define XFS_LOG_VEC_ORDERED (-1)
110+
108111 /*
109112 * Structure used to pass callback function and the function's argument
110113 * to the log manager.
fs/xfs/xfs_log_cil.c+51−24
@@ -127,6 +127,7 @@ xlog_cil_prepare_log_vecs( · 126 unmodified lines
127127 int index;
128128 int len = 0;
129129 uint niovecs;
130+ bool ordered = false;
130131
131132 /* Skip items which aren't dirty in this transaction. */
132133 if (!(lidp->lid_flags & XFS_LID_DIRTY))
@@ -137,14 +138,30 @@ xlog_cil_prepare_log_vecs( · 4 unmodified lines
137138 if (!niovecs)
138139 continue;
139140
141+ /*
142+ * Ordered items need to be tracked but we do not wish to write
143+ * them. We need a logvec to track the object, but we do not
144+ * need an iovec or buffer to be allocated for copying data.
145+ */
146+ if (niovecs == XFS_LOG_VEC_ORDERED) {
147+ ordered = true;
148+ niovecs = 0;
149+ }
150+
140151 new_lv = kmem_zalloc(sizeof(*new_lv) +
141152 niovecs * sizeof(struct xfs_log_iovec),
142153 KM_SLEEP|KM_NOFS);
143154
155+ new_lv->lv_item = lidp->lid_item;
156+ new_lv->lv_niovecs = niovecs;
157+ if (ordered) {
158+ /* track as an ordered logvec */
159+ new_lv->lv_buf_len = XFS_LOG_VEC_ORDERED;
160+ goto next;
161+ }
162+
144163 /* The allocated iovec region lies beyond the log vector. */
145164 new_lv->lv_iovecp = (struct xfs_log_iovec *)&new_lv[1];
146− new_lv->lv_niovecs = niovecs;
147− new_lv->lv_item = lidp->lid_item;
148165
149166 /* build the vector array and calculate it's length */
150167 IOP_FORMAT(new_lv->lv_item, new_lv->lv_iovecp);
@@ -165,6 +182,7 @@ xlog_cil_prepare_log_vecs( · 14 unmodified lines
165182 }
166183 ASSERT(ptr == new_lv->lv_buf + new_lv->lv_buf_len);
167184
185+next:
168186 if (!ret_lv)
169187 ret_lv = new_lv;
170188 else
@@ -191,8 +209,18 @@ xfs_cil_prepare_item( · 20 unmodified lines
191209
192210 if (old) {
193211 /* existing lv on log item, space used is a delta */
194− ASSERT(!list_empty(&lv->lv_item->li_cil));
195− ASSERT(old->lv_buf && old->lv_buf_len && old->lv_niovecs);
212+ ASSERT((old->lv_buf && old->lv_buf_len && old->lv_niovecs) ||
213+ old->lv_buf_len == XFS_LOG_VEC_ORDERED);
214+
215+ /*
216+ * If the new item is ordered, keep the old one that is already
217+ * tracking dirty or ordered regions
218+ */
219+ if (lv->lv_buf_len == XFS_LOG_VEC_ORDERED) {
220+ ASSERT(!lv->lv_buf);
221+ kmem_free(lv);
222+ return;
223+ }
196224
197225 *len += lv->lv_buf_len - old->lv_buf_len;
198226 *diff_iovecs += lv->lv_niovecs - old->lv_niovecs;
@@ -201,10 +229,11 @@ xfs_cil_prepare_item( · 2 unmodified lines
201229 } else {
202230 /* new lv, must pin the log item */
203231 ASSERT(!lv->lv_item->li_lv);
204− ASSERT(list_empty(&lv->lv_item->li_cil));
205232
206− *len += lv->lv_buf_len;
207− *diff_iovecs += lv->lv_niovecs;
233+ if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED) {
234+ *len += lv->lv_buf_len;
235+ *diff_iovecs += lv->lv_niovecs;
236+ }
208237 IOP_PIN(lv->lv_item);
209238
210239 }
@@ -259,18 +288,24 @@ xlog_cil_insert_items( · 48 unmodified lines
259288 * We can do this safely because the context can't checkpoint until we
260289 * are done so it doesn't matter exactly how we update the CIL.
261290 */
262− for (lv = log_vector; lv; lv = lv->lv_next)
263− xfs_cil_prepare_item(log, lv, &len, &diff_iovecs);
264−
265− /* account for space used by new iovec headers */
266− len += diff_iovecs * sizeof(xlog_op_header_t);
267−
268291 spin_lock(&cil->xc_cil_lock);
292+ for (lv = log_vector; lv; ) {
293+ struct xfs_log_vec *next = lv->lv_next;
269294
270− /* move the items to the tail of the CIL */
271− for (lv = log_vector; lv; lv = lv->lv_next)
295+ ASSERT(lv->lv_item->li_lv || list_empty(&lv->lv_item->li_cil));
296+ lv->lv_next = NULL;
297+
298+ /*
299+ * xfs_cil_prepare_item() may free the lv, so move the item on
300+ * the CIL first.
301+ */
272302 list_move_tail(&lv->lv_item->li_cil, &cil->xc_cil);
303+ xfs_cil_prepare_item(log, lv, &len, &diff_iovecs);
304+ lv = next;
305+ }
273306
307+ /* account for space used by new iovec headers */
308+ len += diff_iovecs * sizeof(xlog_op_header_t);
274309 ctx->nvecs += diff_iovecs;
275310
276311 /*
@@ -381,9 +416,7 @@ xlog_cil_push( · 104 unmodified lines
381416 struct xfs_cil_ctx *new_ctx;
382417 struct xlog_in_core *commit_iclog;
383418 struct xlog_ticket *tic;
384− int num_lv;
385419 int num_iovecs;
386− int len;
387420 int error = 0;
388421 struct xfs_trans_header thdr;
389422 struct xfs_log_iovec lhdr;
@@ -428,12 +461,9 @@ xlog_cil_push( · 38 unmodified lines
428461 * side which is currently locked out by the flush lock.
429462 */
430463 lv = NULL;
431− num_lv = 0;
432464 num_iovecs = 0;
433− len = 0;
434465 while (!list_empty(&cil->xc_cil)) {
435466 struct xfs_log_item *item;
436− int i;
437467
438468 item = list_first_entry(&cil->xc_cil,
439469 struct xfs_log_item, li_cil);
@@ -444,11 +474,7 @@ xlog_cil_push( · 4 unmodified lines
444474 lv->lv_next = item->li_lv;
445475 lv = item->li_lv;
446476 item->li_lv = NULL;
447−
448− num_lv++;
449477 num_iovecs += lv->lv_niovecs;
450− for (i = 0; i < lv->lv_niovecs; i++)
451− len += lv->lv_iovecp[i].i_len;
452478 }
453479
454480 /*
@@ -701,6 +727,7 @@ xfs_log_commit_cil( · 246 unmodified lines
701727 if (commit_lsn)
702728 *commit_lsn = log->l_cilp->xc_ctx->sequence;
703729
730+ /* xlog_cil_insert_items() destroys log_vector list */
704731 xlog_cil_insert_items(log, log_vector, tp->t_ticket);
705732
706733 /* check we didn't blow the reservation */
fs/xfs/xfs_log_recover.c+109−5
@@ -45,6 +45,7 @@ · 44 unmodified lines
4545 #include "xfs_cksum.h"
4646 #include "xfs_trace.h"
4747 #include "xfs_icache.h"
48+#include "xfs_icreate_item.h"
4849
4950 /* Need all the magic numbers and buffer ops structures from these headers */
5051 #include "xfs_symlink.h"
@@ -1617,7 +1618,10 @@ xlog_recover_add_to_trans( · 1566 unmodified lines
16171618 * form the cancelled buffer table. Hence they have tobe done last.
16181619 *
16191620 * 3. Inode allocation buffers must be replayed before inode items that
1620− * read the buffer and replay changes into it.
1621+ * read the buffer and replay changes into it. For filesystems using the
1622+ * ICREATE transactions, this means XFS_LI_ICREATE objects need to get
1623+ * treated the same as inode allocation buffers as they create and
1624+ * initialise the buffers directly.
16211625 *
16221626 * 4. Inode unlink buffers must be replayed after inode items are replayed.
16231627 * This ensures that inodes are completely flushed to the inode buffer
@@ -1632,10 +1636,17 @@ xlog_recover_add_to_trans( · 8 unmodified lines
16321636 * from all the other buffers and move them to last.
16331637 *
16341638 * Hence, 4 lists, in order from head to tail:
1635− * - buffer_list for all buffers except cancelled/inode unlink buffers
1636− * - item_list for all non-buffer items
1637− * - inode_buffer_list for inode unlink buffers
1638− * - cancel_list for the cancelled buffers
1639+ * - buffer_list for all buffers except cancelled/inode unlink buffers
1640+ * - item_list for all non-buffer items
1641+ * - inode_buffer_list for inode unlink buffers
1642+ * - cancel_list for the cancelled buffers
1643+ *
1644+ * Note that we add objects to the tail of the lists so that first-to-last
1645+ * ordering is preserved within the lists. Adding objects to the head of the
1646+ * list means when we traverse from the head we walk them in last-to-first
1647+ * order. For cancelled buffers and inode unlink buffers this doesn't matter,
1648+ * but for all other items there may be specific ordering that we need to
1649+ * preserve.
16391650 */
16401651 STATIC int
16411652 xlog_recover_reorder_trans(
@@ -1655,6 +1666,9 @@ xlog_recover_reorder_trans( · 13 unmodified lines
16551666 xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
16561667
16571668 switch (ITEM_TYPE(item)) {
1669+ case XFS_LI_ICREATE:
1670+ list_move_tail(&item->ri_list, &buffer_list);
1671+ break;
16581672 case XFS_LI_BUF:
16591673 if (buf_f->blf_flags & XFS_BLF_CANCEL) {
16601674 trace_xfs_log_recover_item_reorder_head(log,
@@ -2981,6 +2995,93 @@ xlog_recover_efd_pass2( · 1320 unmodified lines
29812995 return 0;
29822996 }
29832997
2998+/*
2999+ * This routine is called when an inode create format structure is found in a
3000+ * committed transaction in the log. It's purpose is to initialise the inodes
3001+ * being allocated on disk. This requires us to get inode cluster buffers that
3002+ * match the range to be intialised, stamped with inode templates and written
3003+ * by delayed write so that subsequent modifications will hit the cached buffer
3004+ * and only need writing out at the end of recovery.
3005+ */
3006+STATIC int
3007+xlog_recover_do_icreate_pass2(
3008+ struct xlog *log,
3009+ struct list_head *buffer_list,
3010+ xlog_recover_item_t *item)
3011+{
3012+ struct xfs_mount *mp = log->l_mp;
3013+ struct xfs_icreate_log *icl;
3014+ xfs_agnumber_t agno;
3015+ xfs_agblock_t agbno;
3016+ unsigned int count;
3017+ unsigned int isize;
3018+ xfs_agblock_t length;
3019+
3020+ icl = (struct xfs_icreate_log *)item->ri_buf[0].i_addr;
3021+ if (icl->icl_type != XFS_LI_ICREATE) {
3022+ xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad type");
3023+ return EINVAL;
3024+ }
3025+
3026+ if (icl->icl_size != 1) {
3027+ xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad icl size");
3028+ return EINVAL;
3029+ }
3030+
3031+ agno = be32_to_cpu(icl->icl_ag);
3032+ if (agno >= mp->m_sb.sb_agcount) {
3033+ xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad agno");
3034+ return EINVAL;
3035+ }
3036+ agbno = be32_to_cpu(icl->icl_agbno);
3037+ if (!agbno || agbno == NULLAGBLOCK || agbno >= mp->m_sb.sb_agblocks) {
3038+ xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad agbno");
3039+ return EINVAL;
3040+ }
3041+ isize = be32_to_cpu(icl->icl_isize);
3042+ if (isize != mp->m_sb.sb_inodesize) {
3043+ xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad isize");
3044+ return EINVAL;
3045+ }
3046+ count = be32_to_cpu(icl->icl_count);
3047+ if (!count) {
3048+ xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad count");
3049+ return EINVAL;
3050+ }
3051+ length = be32_to_cpu(icl->icl_length);
3052+ if (!length || length >= mp->m_sb.sb_agblocks) {
3053+ xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad length");
3054+ return EINVAL;
3055+ }
3056+
3057+ /* existing allocation is fixed value */
3058+ ASSERT(count == XFS_IALLOC_INODES(mp));
3059+ ASSERT(length == XFS_IALLOC_BLOCKS(mp));
3060+ if (count != XFS_IALLOC_INODES(mp) ||
3061+ length != XFS_IALLOC_BLOCKS(mp)) {
3062+ xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad count 2");
3063+ return EINVAL;
3064+ }
3065+
3066+ /*
3067+ * Inode buffers can be freed. Do not replay the inode initialisation as
3068+ * we could be overwriting something written after this inode buffer was
3069+ * cancelled.
3070+ *
3071+ * XXX: we need to iterate all buffers and only init those that are not
3072+ * cancelled. I think that a more fine grained factoring of
3073+ * xfs_ialloc_inode_init may be appropriate here to enable this to be
3074+ * done easily.
3075+ */
3076+ if (xlog_check_buffer_cancelled(log,
3077+ XFS_AGB_TO_DADDR(mp, agno, agbno), length, 0))
3078+ return 0;
3079+
3080+ xfs_ialloc_inode_init(mp, NULL, buffer_list, agno, agbno, length,
3081+ be32_to_cpu(icl->icl_gen));
3082+ return 0;
3083+}
3084+
29843085 /*
29853086 * Free up any resources allocated by the transaction
29863087 *
@@ -3023,6 +3124,7 @@ xlog_recover_commit_pass1( · 36 unmodified lines
30233124 case XFS_LI_EFI:
30243125 case XFS_LI_EFD:
30253126 case XFS_LI_DQUOT:
3127+ case XFS_LI_ICREATE:
30263128 /* nothing to do in pass 1 */
30273129 return 0;
30283130 default:
@@ -3053,6 +3155,8 @@ xlog_recover_commit_pass2( · 24 unmodified lines
30533155 return xlog_recover_efd_pass2(log, item);
30543156 case XFS_LI_DQUOT:
30553157 return xlog_recover_dquot_pass2(log, buffer_list, item);
3158+ case XFS_LI_ICREATE:
3159+ return xlog_recover_do_icreate_pass2(log, buffer_list, item);
30563160 case XFS_LI_QUOTAOFF:
30573161 /* nothing to do in pass2 */
30583162 return 0;
fs/xfs/xfs_mount.c+66−26
@@ -336,6 +336,14 @@ xfs_mount_validate_sb( · 335 unmodified lines
336336 return XFS_ERROR(EWRONGFS);
337337 }
338338
339+ if ((sbp->sb_qflags & (XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD)) &&
340+ (sbp->sb_qflags & (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD |
341+ XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))) {
342+ xfs_notice(mp,
343+"Super block has XFS_OQUOTA bits along with XFS_PQUOTA and/or XFS_GQUOTA bits.\n");
344+ return XFS_ERROR(EFSCORRUPTED);
345+ }
346+
339347 /*
340348 * Version 5 superblock feature mask validation. Reject combinations the
341349 * kernel cannot support up front before checking anything else. For
@@ -561,6 +569,18 @@ out_unwind: · 219 unmodified lines
561569 return error;
562570 }
563571
572+static void
573+xfs_sb_quota_from_disk(struct xfs_sb *sbp)
574+{
575+ if (sbp->sb_qflags & XFS_OQUOTA_ENFD)
576+ sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ?
577+ XFS_PQUOTA_ENFD : XFS_GQUOTA_ENFD;
578+ if (sbp->sb_qflags & XFS_OQUOTA_CHKD)
579+ sbp->sb_qflags |= (sbp->sb_qflags & XFS_PQUOTA_ACCT) ?
580+ XFS_PQUOTA_CHKD : XFS_GQUOTA_CHKD;
581+ sbp->sb_qflags &= ~(XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD);
582+}
583+
564584 void
565585 xfs_sb_from_disk(
566586 struct xfs_sb *to,
@@ -622,6 +642,35 @@ xfs_sb_from_disk( · 55 unmodified lines
622642 to->sb_lsn = be64_to_cpu(from->sb_lsn);
623643 }
624644
645+static inline void
646+xfs_sb_quota_to_disk(
647+ xfs_dsb_t *to,
648+ xfs_sb_t *from,
649+ __int64_t *fields)
650+{
651+ __uint16_t qflags = from->sb_qflags;
652+
653+ if (*fields & XFS_SB_QFLAGS) {
654+ /*
655+ * The in-core version of sb_qflags do not have
656+ * XFS_OQUOTA_* flags, whereas the on-disk version
657+ * does. So, convert incore XFS_{PG}QUOTA_* flags
658+ * to on-disk XFS_OQUOTA_* flags.
659+ */
660+ qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD |
661+ XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD);
662+
663+ if (from->sb_qflags &
664+ (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD))
665+ qflags |= XFS_OQUOTA_ENFD;
666+ if (from->sb_qflags &
667+ (XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD))
668+ qflags |= XFS_OQUOTA_CHKD;
669+ to->sb_qflags = cpu_to_be16(qflags);
670+ *fields &= ~XFS_SB_QFLAGS;
671+ }
672+}
673+
625674 /*
626675 * Copy in core superblock to ondisk one.
627676 *
@@ -643,6 +692,7 @@ xfs_sb_to_disk( · 15 unmodified lines
643692 if (!fields)
644693 return;
645694
695+ xfs_sb_quota_to_disk(to, from, &fields);
646696 while (fields) {
647697 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
648698 first = xfs_sb_info[f].offset;
@@ -835,6 +885,7 @@ reread: · 186 unmodified lines
835885 */
836886 xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp));
837887
888+ xfs_sb_quota_from_disk(&mp->m_sb);
838889 /*
839890 * We must be able to do sector-sized and sector-aligned IO.
840891 */
@@ -987,42 +1038,27 @@ xfs_update_alignment(xfs_mount_t *mp) · 146 unmodified lines
9871038 */
9881039 if ((BBTOB(mp->m_dalign) & mp->m_blockmask) ||
9891040 (BBTOB(mp->m_swidth) & mp->m_blockmask)) {
990− if (mp->m_flags & XFS_MOUNT_RETERR) {
991− xfs_warn(mp, "alignment check failed: "
992− "(sunit/swidth vs. blocksize)");
993− return XFS_ERROR(EINVAL);
994− }
995− mp->m_dalign = mp->m_swidth = 0;
1041+ xfs_warn(mp,
1042+ "alignment check failed: sunit/swidth vs. blocksize(%d)",
1043+ sbp->sb_blocksize);
1044+ return XFS_ERROR(EINVAL);
9961045 } else {
9971046 /*
9981047 * Convert the stripe unit and width to FSBs.
9991048 */
10001049 mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign);
10011050 if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) {
1002− if (mp->m_flags & XFS_MOUNT_RETERR) {
1003− xfs_warn(mp, "alignment check failed: "
1004− "(sunit/swidth vs. ag size)");
1005− return XFS_ERROR(EINVAL);
1006− }
10071051 xfs_warn(mp,
1008− "stripe alignment turned off: sunit(%d)/swidth(%d) "
1009− "incompatible with agsize(%d)",
1010− mp->m_dalign, mp->m_swidth,
1011− sbp->sb_agblocks);
1012−
1013− mp->m_dalign = 0;
1014− mp->m_swidth = 0;
1052+ "alignment check failed: sunit/swidth vs. agsize(%d)",
1053+ sbp->sb_agblocks);
1054+ return XFS_ERROR(EINVAL);
10151055 } else if (mp->m_dalign) {
10161056 mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth);
10171057 } else {
1018− if (mp->m_flags & XFS_MOUNT_RETERR) {
1019− xfs_warn(mp, "alignment check failed: "
1020− "sunit(%d) less than bsize(%d)",
1021− mp->m_dalign,
1022− mp->m_blockmask +1);
1023− return XFS_ERROR(EINVAL);
1024− }
1025− mp->m_swidth = 0;
1058+ xfs_warn(mp,
1059+ "alignment check failed: sunit(%d) less than bsize(%d)",
1060+ mp->m_dalign, sbp->sb_blocksize);
1061+ return XFS_ERROR(EINVAL);
10261062 }
10271063 }
10281064
@@ -1039,6 +1075,10 @@ xfs_update_alignment(xfs_mount_t *mp) · 10 unmodified lines
10391075 sbp->sb_width = mp->m_swidth;
10401076 mp->m_update_flags |= XFS_SB_WIDTH;
10411077 }
1078+ } else {
1079+ xfs_warn(mp,
1080+ "cannot change alignment: superblock does not support data alignment");
1081+ return XFS_ERROR(EINVAL);
10421082 }
10431083 } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
10441084 xfs_sb_version_hasdalign(&mp->m_sb)) {
fs/xfs/xfs_mount.h+0−4
@@ -192,8 +192,6 @@ typedef struct xfs_mount { · 191 unmodified lines
192192 xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */
193193 xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */
194194 uint m_chsize; /* size of next field */
195− struct xfs_chash *m_chash; /* fs private inode per-cluster
196− * hash table */
197195 atomic_t m_active_trans; /* number trans frozen */
198196 #ifdef HAVE_PERCPU_SB
199197 xfs_icsb_cnts_t __percpu *m_sb_cnts; /* per-cpu superblock counters */
@@ -229,8 +227,6 @@ typedef struct xfs_mount { · 29 unmodified lines
229227 operations, typically for
230228 disk errors in metadata */
231229 #define XFS_MOUNT_DISCARD (1ULL << 5) /* discard unused blocks */
232−#define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to
233− user */
234230 #define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment
235231 allocations */
236232 #define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */
fs/xfs/xfs_qm.c+92−83
@@ -70,7 +70,7 @@ xfs_qm_dquot_walk( · 69 unmodified lines
7070 void *data)
7171 {
7272 struct xfs_quotainfo *qi = mp->m_quotainfo;
73− struct radix_tree_root *tree = XFS_DQUOT_TREE(qi, type);
73+ struct radix_tree_root *tree = xfs_dquot_tree(qi, type);
7474 uint32_t next_index;
7575 int last_error = 0;
7676 int skipped;
@@ -189,7 +189,7 @@ xfs_qm_dqpurge( · 112 unmodified lines
189189 xfs_dqfunlock(dqp);
190190 xfs_dqunlock(dqp);
191191
192− radix_tree_delete(XFS_DQUOT_TREE(qi, dqp->q_core.d_flags),
192+ radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
193193 be32_to_cpu(dqp->q_core.d_id));
194194 qi->qi_dquots--;
195195
@@ -299,8 +299,10 @@ xfs_qm_mount_quotas( · 103 unmodified lines
299299 */
300300 if (!XFS_IS_UQUOTA_ON(mp))
301301 mp->m_qflags &= ~XFS_UQUOTA_CHKD;
302− if (!(XFS_IS_GQUOTA_ON(mp) || XFS_IS_PQUOTA_ON(mp)))
303− mp->m_qflags &= ~XFS_OQUOTA_CHKD;
302+ if (!XFS_IS_GQUOTA_ON(mp))
303+ mp->m_qflags &= ~XFS_GQUOTA_CHKD;
304+ if (!XFS_IS_PQUOTA_ON(mp))
305+ mp->m_qflags &= ~XFS_PQUOTA_CHKD;
304306
305307 write_changes:
306308 /*
@@ -489,8 +491,7 @@ xfs_qm_need_dqattach( · 182 unmodified lines
489491 return false;
490492 if (!XFS_NOT_DQATTACHED(mp, ip))
491493 return false;
492− if (ip->i_ino == mp->m_sb.sb_uquotino ||
493− ip->i_ino == mp->m_sb.sb_gquotino)
494+ if (xfs_is_quota_inode(&mp->m_sb, ip->i_ino))
494495 return false;
495496 return true;
496497 }
@@ -606,8 +607,7 @@ xfs_qm_dqdetach( · 109 unmodified lines
606607
607608 trace_xfs_dquot_dqdetach(ip);
608609
609− ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino);
610− ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino);
610+ ASSERT(!xfs_is_quota_inode(&ip->i_mount->m_sb, ip->i_ino));
611611 if (ip->i_udquot) {
612612 xfs_qm_dqrele(ip->i_udquot);
613613 ip->i_udquot = NULL;
@@ -1152,7 +1152,7 @@ xfs_qm_dqusage_adjust( · 538 unmodified lines
11521152 * rootino must have its resources accounted for, not so with the quota
11531153 * inodes.
11541154 */
1155− if (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino) {
1155+ if (xfs_is_quota_inode(&mp->m_sb, ino)) {
11561156 *res = BULKSTAT_RV_NOTHING;
11571157 return XFS_ERROR(EINVAL);
11581158 }
@@ -1262,19 +1262,20 @@ int · 103 unmodified lines
12621262 xfs_qm_quotacheck(
12631263 xfs_mount_t *mp)
12641264 {
1265− int done, count, error, error2;
1266− xfs_ino_t lastino;
1267− size_t structsz;
1268− xfs_inode_t *uip, *gip;
1269− uint flags;
1270− LIST_HEAD (buffer_list);
1265+ int done, count, error, error2;
1266+ xfs_ino_t lastino;
1267+ size_t structsz;
1268+ uint flags;
1269+ LIST_HEAD (buffer_list);
1270+ struct xfs_inode *uip = mp->m_quotainfo->qi_uquotaip;
1271+ struct xfs_inode *gip = mp->m_quotainfo->qi_gquotaip;
12711272
12721273 count = INT_MAX;
12731274 structsz = 1;
12741275 lastino = 0;
12751276 flags = 0;
12761277
1277− ASSERT(mp->m_quotainfo->qi_uquotaip || mp->m_quotainfo->qi_gquotaip);
1278+ ASSERT(uip || gip);
12781279 ASSERT(XFS_IS_QUOTA_RUNNING(mp));
12791280
12801281 xfs_notice(mp, "Quotacheck needed: Please wait.");
@@ -1284,7 +1285,6 @@ xfs_qm_quotacheck( · 3 unmodified lines
12841285 * their counters to zero. We need a clean slate.
12851286 * We don't log our changes till later.
12861287 */
1287− uip = mp->m_quotainfo->qi_uquotaip;
12881288 if (uip) {
12891289 error = xfs_qm_dqiterate(mp, uip, XFS_QMOPT_UQUOTA,
12901290 &buffer_list);
@@ -1293,14 +1293,14 @@ xfs_qm_quotacheck( · 2 unmodified lines
12931293 flags |= XFS_UQUOTA_CHKD;
12941294 }
12951295
1296− gip = mp->m_quotainfo->qi_gquotaip;
12971296 if (gip) {
12981297 error = xfs_qm_dqiterate(mp, gip, XFS_IS_GQUOTA_ON(mp) ?
12991298 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA,
13001299 &buffer_list);
13011300 if (error)
13021301 goto error_return;
1303− flags |= XFS_OQUOTA_CHKD;
1302+ flags |= XFS_IS_GQUOTA_ON(mp) ?
1303+ XFS_GQUOTA_CHKD : XFS_PQUOTA_CHKD;
13041304 }
13051305
13061306 do {
@@ -1395,15 +1395,13 @@ STATIC int · 88 unmodified lines
13951395 xfs_qm_init_quotainos(
13961396 xfs_mount_t *mp)
13971397 {
1398− xfs_inode_t *uip, *gip;
1399− int error;
1400− __int64_t sbflags;
1401− uint flags;
1398+ struct xfs_inode *uip = NULL;
1399+ struct xfs_inode *gip = NULL;
1400+ int error;
1401+ __int64_t sbflags = 0;
1402+ uint flags = 0;
14021403
14031404 ASSERT(mp->m_quotainfo);
1404− uip = gip = NULL;
1405− sbflags = 0;
1406− flags = 0;
14071405
14081406 /*
14091407 * Get the uquota and gquota inodes
@@ -1412,19 +1410,18 @@ xfs_qm_init_quotainos( · 2 unmodified lines
14121410 if (XFS_IS_UQUOTA_ON(mp) &&
14131411 mp->m_sb.sb_uquotino != NULLFSINO) {
14141412 ASSERT(mp->m_sb.sb_uquotino > 0);
1415− if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
1416− 0, 0, &uip)))
1413+ error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
1414+ 0, 0, &uip);
1415+ if (error)
14171416 return XFS_ERROR(error);
14181417 }
14191418 if (XFS_IS_OQUOTA_ON(mp) &&
14201419 mp->m_sb.sb_gquotino != NULLFSINO) {
14211420 ASSERT(mp->m_sb.sb_gquotino > 0);
1422− if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
1423− 0, 0, &gip))) {
1424− if (uip)
1425− IRELE(uip);
1426− return XFS_ERROR(error);
1427− }
1421+ error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
1422+ 0, 0, &gip);
1423+ if (error)
1424+ goto error_rele;
14281425 }
14291426 } else {
14301427 flags |= XFS_QMOPT_SBVERSION;
@@ -1439,10 +1436,11 @@ xfs_qm_init_quotainos( · 8 unmodified lines
14391436 * temporarily switch to read-write to do this.
14401437 */
14411438 if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) {
1442− if ((error = xfs_qm_qino_alloc(mp, &uip,
1439+ error = xfs_qm_qino_alloc(mp, &uip,
14431440 sbflags | XFS_SB_UQUOTINO,
1444− flags | XFS_QMOPT_UQUOTA)))
1445− return XFS_ERROR(error);
1441+ flags | XFS_QMOPT_UQUOTA);
1442+ if (error)
1443+ goto error_rele;
14461444
14471445 flags &= ~XFS_QMOPT_SBVERSION;
14481446 }
@@ -1451,18 +1449,21 @@ xfs_qm_init_quotainos( · 2 unmodified lines
14511449 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA);
14521450 error = xfs_qm_qino_alloc(mp, &gip,
14531451 sbflags | XFS_SB_GQUOTINO, flags);
1454− if (error) {
1455− if (uip)
1456− IRELE(uip);
1457−
1458− return XFS_ERROR(error);
1459− }
1452+ if (error)
1453+ goto error_rele;
14601454 }
14611455
14621456 mp->m_quotainfo->qi_uquotaip = uip;
14631457 mp->m_quotainfo->qi_gquotaip = gip;
14641458
14651459 return 0;
1460+
1461+error_rele:
1462+ if (uip)
1463+ IRELE(uip);
1464+ if (gip)
1465+ IRELE(gip);
1466+ return XFS_ERROR(error);
14661467 }
14671468
14681469 STATIC void
@@ -1473,7 +1474,7 @@ xfs_qm_dqfree_one( · 4 unmodified lines
14731474 struct xfs_quotainfo *qi = mp->m_quotainfo;
14741475
14751476 mutex_lock(&qi->qi_tree_lock);
1476− radix_tree_delete(XFS_DQUOT_TREE(qi, dqp->q_core.d_flags),
1477+ radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
14771478 be32_to_cpu(dqp->q_core.d_id));
14781479
14791480 qi->qi_dquots--;
@@ -1659,7 +1660,8 @@ xfs_qm_vop_dqalloc( · 179 unmodified lines
16591660 struct xfs_dquot **O_gdqpp)
16601661 {
16611662 struct xfs_mount *mp = ip->i_mount;
1662− struct xfs_dquot *uq, *gq;
1663+ struct xfs_dquot *uq = NULL;
1664+ struct xfs_dquot *gq = NULL;
16631665 int error;
16641666 uint lockflags;
16651667
@@ -1684,7 +1686,6 @@ xfs_qm_vop_dqalloc( · 18 unmodified lines
16841686 }
16851687 }
16861688
1687− uq = gq = NULL;
16881689 if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) {
16891690 if (ip->i_d.di_uid != uid) {
16901691 /*
@@ -1697,11 +1698,12 @@ xfs_qm_vop_dqalloc( · 6 unmodified lines
16971698 * holding ilock.
16981699 */
16991700 xfs_iunlock(ip, lockflags);
1700− if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t) uid,
1701+ error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t) uid,
17011702 XFS_DQ_USER,
17021703 XFS_QMOPT_DQALLOC |
17031704 XFS_QMOPT_DOWARN,
1704− &uq))) {
1705+ &uq);
1706+ if (error) {
17051707 ASSERT(error != ENOENT);
17061708 return error;
17071709 }
@@ -1723,15 +1725,14 @@ xfs_qm_vop_dqalloc( · 15 unmodified lines
17231725 if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
17241726 if (ip->i_d.di_gid != gid) {
17251727 xfs_iunlock(ip, lockflags);
1726− if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
1728+ error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
17271729 XFS_DQ_GROUP,
17281730 XFS_QMOPT_DQALLOC |
17291731 XFS_QMOPT_DOWARN,
1730− &gq))) {
1731− if (uq)
1732− xfs_qm_dqrele(uq);
1732+ &gq);
1733+ if (error) {
17331734 ASSERT(error != ENOENT);
1734− return error;
1735+ goto error_rele;
17351736 }
17361737 xfs_dqunlock(gq);
17371738 lockflags = XFS_ILOCK_SHARED;
@@ -1743,15 +1744,14 @@ xfs_qm_vop_dqalloc( · 5 unmodified lines
17431744 } else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
17441745 if (xfs_get_projid(ip) != prid) {
17451746 xfs_iunlock(ip, lockflags);
1746− if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
1747+ error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
17471748 XFS_DQ_PROJ,
17481749 XFS_QMOPT_DQALLOC |
17491750 XFS_QMOPT_DOWARN,
1750− &gq))) {
1751− if (uq)
1752− xfs_qm_dqrele(uq);
1751+ &gq);
1752+ if (error) {
17531753 ASSERT(error != ENOENT);
1754− return (error);
1754+ goto error_rele;
17551755 }
17561756 xfs_dqunlock(gq);
17571757 lockflags = XFS_ILOCK_SHARED;
@@ -1774,6 +1774,11 @@ xfs_qm_vop_dqalloc( · 16 unmodified lines
17741774 else if (gq)
17751775 xfs_qm_dqrele(gq);
17761776 return 0;
1777+
1778+error_rele:
1779+ if (uq)
1780+ xfs_qm_dqrele(uq);
1781+ return error;
17771782 }
17781783
17791784 /*
@@ -1821,29 +1826,31 @@ xfs_qm_vop_chown( · 41 unmodified lines
18211826 */
18221827 int
18231828 xfs_qm_vop_chown_reserve(
1824− xfs_trans_t *tp,
1825− xfs_inode_t *ip,
1826− xfs_dquot_t *udqp,
1827− xfs_dquot_t *gdqp,
1828− uint flags)
1829+ struct xfs_trans *tp,
1830+ struct xfs_inode *ip,
1831+ struct xfs_dquot *udqp,
1832+ struct xfs_dquot *gdqp,
1833+ uint flags)
18291834 {
1830− xfs_mount_t *mp = ip->i_mount;
1831− uint delblks, blkflags, prjflags = 0;
1832− xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq;
1833− int error;
1835+ struct xfs_mount *mp = ip->i_mount;
1836+ uint delblks, blkflags, prjflags = 0;
1837+ struct xfs_dquot *udq_unres = NULL;
1838+ struct xfs_dquot *gdq_unres = NULL;
1839+ struct xfs_dquot *udq_delblks = NULL;
1840+ struct xfs_dquot *gdq_delblks = NULL;
1841+ int error;
18341842
18351843
18361844 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
18371845 ASSERT(XFS_IS_QUOTA_RUNNING(mp));
18381846
18391847 delblks = ip->i_delayed_blks;
1840− delblksudq = delblksgdq = unresudq = unresgdq = NULL;
18411848 blkflags = XFS_IS_REALTIME_INODE(ip) ?
18421849 XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
18431850
18441851 if (XFS_IS_UQUOTA_ON(mp) && udqp &&
18451852 ip->i_d.di_uid != (uid_t)be32_to_cpu(udqp->q_core.d_id)) {
1846− delblksudq = udqp;
1853+ udq_delblks = udqp;
18471854 /*
18481855 * If there are delayed allocation blocks, then we have to
18491856 * unreserve those from the old dquot, and add them to the
@@ -1851,7 +1858,7 @@ xfs_qm_vop_chown_reserve( · 1 unmodified line
18511858 */
18521859 if (delblks) {
18531860 ASSERT(ip->i_udquot);
1854− unresudq = ip->i_udquot;
1861+ udq_unres = ip->i_udquot;
18551862 }
18561863 }
18571864 if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
@@ -1862,18 +1869,19 @@ xfs_qm_vop_chown_reserve( · 4 unmodified lines
18621869 if (prjflags ||
18631870 (XFS_IS_GQUOTA_ON(ip->i_mount) &&
18641871 ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id))) {
1865− delblksgdq = gdqp;
1872+ gdq_delblks = gdqp;
18661873 if (delblks) {
18671874 ASSERT(ip->i_gdquot);
1868− unresgdq = ip->i_gdquot;
1875+ gdq_unres = ip->i_gdquot;
18691876 }
18701877 }
18711878 }
18721879
1873− if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
1874− delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
1875− flags | blkflags | prjflags)))
1876− return (error);
1880+ error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
1881+ udq_delblks, gdq_delblks, ip->i_d.di_nblocks, 1,
1882+ flags | blkflags | prjflags);
1883+ if (error)
1884+ return error;
18771885
18781886 /*
18791887 * Do the delayed blks reservations/unreservations now. Since, these
@@ -1885,14 +1893,15 @@ xfs_qm_vop_chown_reserve( · 5 unmodified lines
18851893 /*
18861894 * Do the reservations first. Unreservation can't fail.
18871895 */
1888− ASSERT(delblksudq || delblksgdq);
1889− ASSERT(unresudq || unresgdq);
1890− if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
1891− delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
1892− flags | blkflags | prjflags)))
1893− return (error);
1896+ ASSERT(udq_delblks || gdq_delblks);
1897+ ASSERT(udq_unres || gdq_unres);
1898+ error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
1899+ udq_delblks, gdq_delblks, (xfs_qcnt_t)delblks, 0,
1900+ flags | blkflags | prjflags);
1901+ if (error)
1902+ return error;
18941903 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
1895− unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
1904+ udq_unres, gdq_unres, -((xfs_qcnt_t)delblks), 0,
18961905 blkflags);
18971906 }
18981907
fs/xfs/xfs_qm.h+58−25
@@ -69,30 +69,62 @@ typedef struct xfs_quotainfo { · 68 unmodified lines
6969 struct shrinker qi_shrinker;
7070 } xfs_quotainfo_t;
7171
72−#define XFS_DQUOT_TREE(qi, type) \
73− ((type & XFS_DQ_USER) ? \
74− &((qi)->qi_uquota_tree) : \
75− &((qi)->qi_gquota_tree))
72+static inline struct radix_tree_root *
73+xfs_dquot_tree(
74+ struct xfs_quotainfo *qi,
75+ int type)
76+{
77+ switch (type) {
78+ case XFS_DQ_USER:
79+ return &qi->qi_uquota_tree;
80+ case XFS_DQ_GROUP:
81+ case XFS_DQ_PROJ:
82+ return &qi->qi_gquota_tree;
83+ default:
84+ ASSERT(0);
85+ }
86+ return NULL;
87+}
7688
89+static inline struct xfs_inode *
90+xfs_dq_to_quota_inode(struct xfs_dquot *dqp)
91+{
92+ switch (dqp->dq_flags & XFS_DQ_ALLTYPES) {
93+ case XFS_DQ_USER:
94+ return dqp->q_mount->m_quotainfo->qi_uquotaip;
95+ case XFS_DQ_GROUP:
96+ case XFS_DQ_PROJ:
97+ return dqp->q_mount->m_quotainfo->qi_gquotaip;
98+ default:
99+ ASSERT(0);
100+ }
101+ return NULL;
102+}
77103
78104 extern int xfs_qm_calc_dquots_per_chunk(struct xfs_mount *mp,
79105 unsigned int nbblks);
80−extern void xfs_trans_mod_dquot(xfs_trans_t *, xfs_dquot_t *, uint, long);
81−extern int xfs_trans_reserve_quota_bydquots(xfs_trans_t *, xfs_mount_t *,
82− xfs_dquot_t *, xfs_dquot_t *, long, long, uint);
83−extern void xfs_trans_dqjoin(xfs_trans_t *, xfs_dquot_t *);
84−extern void xfs_trans_log_dquot(xfs_trans_t *, xfs_dquot_t *);
106+extern void xfs_trans_mod_dquot(struct xfs_trans *,
107+ struct xfs_dquot *, uint, long);
108+extern int xfs_trans_reserve_quota_bydquots(struct xfs_trans *,
109+ struct xfs_mount *, struct xfs_dquot *,
110+ struct xfs_dquot *, long, long, uint);
111+extern void xfs_trans_dqjoin(struct xfs_trans *, struct xfs_dquot *);
112+extern void xfs_trans_log_dquot(struct xfs_trans *, struct xfs_dquot *);
85113
86114 /*
87115 * We keep the usr and grp dquots separately so that locking will be easier
88116 * to do at commit time. All transactions that we know of at this point
89117 * affect no more than two dquots of one type. Hence, the TRANS_MAXDQS value.
90118 */
119+enum {
120+ XFS_QM_TRANS_USR = 0,
121+ XFS_QM_TRANS_GRP,
122+ XFS_QM_TRANS_DQTYPES
123+};
91124 #define XFS_QM_TRANS_MAXDQS 2
92−typedef struct xfs_dquot_acct {
93− xfs_dqtrx_t dqa_usrdquots[XFS_QM_TRANS_MAXDQS];
94− xfs_dqtrx_t dqa_grpdquots[XFS_QM_TRANS_MAXDQS];
95−} xfs_dquot_acct_t;
125+struct xfs_dquot_acct {
126+ struct xfs_dqtrx dqs[XFS_QM_TRANS_DQTYPES][XFS_QM_TRANS_MAXDQS];
127+};
96128
97129 /*
98130 * Users are allowed to have a usage exceeding their softlimit for
@@ -106,22 +138,23 @@ typedef struct xfs_dquot_acct { · 7 unmodified lines
106138 #define XFS_QM_IWARNLIMIT 5
107139 #define XFS_QM_RTBWARNLIMIT 5
108140
109−extern void xfs_qm_destroy_quotainfo(xfs_mount_t *);
110−extern int xfs_qm_quotacheck(xfs_mount_t *);
111−extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t);
141+extern void xfs_qm_destroy_quotainfo(struct xfs_mount *);
142+extern int xfs_qm_quotacheck(struct xfs_mount *);
143+extern int xfs_qm_write_sb_changes(struct xfs_mount *, __int64_t);
112144
113145 /* dquot stuff */
114−extern void xfs_qm_dqpurge_all(xfs_mount_t *, uint);
115−extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
146+extern void xfs_qm_dqpurge_all(struct xfs_mount *, uint);
147+extern void xfs_qm_dqrele_all_inodes(struct xfs_mount *, uint);
116148
117149 /* quota ops */
118−extern int xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint);
119−extern int xfs_qm_scall_getquota(xfs_mount_t *, xfs_dqid_t, uint,
120− fs_disk_quota_t *);
150+extern int xfs_qm_scall_trunc_qfiles(struct xfs_mount *, uint);
151+extern int xfs_qm_scall_getquota(struct xfs_mount *, xfs_dqid_t,
152+ uint, struct fs_disk_quota *);
121153 extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint,
122− fs_disk_quota_t *);
123−extern int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
124−extern int xfs_qm_scall_quotaon(xfs_mount_t *, uint);
125−extern int xfs_qm_scall_quotaoff(xfs_mount_t *, uint);
154+ struct fs_disk_quota *);
155+extern int xfs_qm_scall_getqstat(struct xfs_mount *,
156+ struct fs_quota_stat *);
157+extern int xfs_qm_scall_quotaon(struct xfs_mount *, uint);
158+extern int xfs_qm_scall_quotaoff(struct xfs_mount *, uint);
126159
127160 #endif /* __XFS_QM_H__ */
fs/xfs/xfs_qm_syscalls.c+27−24
@@ -117,11 +117,11 @@ xfs_qm_scall_quotaoff( · 116 unmodified lines
117117 }
118118 if (flags & XFS_GQUOTA_ACCT) {
119119 dqtype |= XFS_QMOPT_GQUOTA;
120− flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
120+ flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD);
121121 inactivate_flags |= XFS_GQUOTA_ACTIVE;
122122 } else if (flags & XFS_PQUOTA_ACCT) {
123123 dqtype |= XFS_QMOPT_PQUOTA;
124− flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
124+ flags |= (XFS_PQUOTA_CHKD | XFS_PQUOTA_ENFD);
125125 inactivate_flags |= XFS_PQUOTA_ACTIVE;
126126 }
127127
@@ -335,14 +335,14 @@ xfs_qm_scall_quotaon( · 207 unmodified lines
335335 * quota acct on ondisk without m_qflags' knowing.
336336 */
337337 if (((flags & XFS_UQUOTA_ACCT) == 0 &&
338− (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
339− (flags & XFS_UQUOTA_ENFD))
340− ||
338+ (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
339+ (flags & XFS_UQUOTA_ENFD)) ||
340+ ((flags & XFS_GQUOTA_ACCT) == 0 &&
341+ (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
342+ (flags & XFS_GQUOTA_ENFD)) ||
341343 ((flags & XFS_PQUOTA_ACCT) == 0 &&
342− (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
343− (flags & XFS_GQUOTA_ACCT) == 0 &&
344− (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
345− (flags & XFS_OQUOTA_ENFD))) {
344+ (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
345+ (flags & XFS_PQUOTA_ENFD))) {
346346 xfs_debug(mp,
347347 "%s: Can't enforce without acct, flags=%x sbflags=%x\n",
348348 __func__, flags, mp->m_sb.sb_qflags);
@@ -407,11 +407,11 @@ xfs_qm_scall_getqstat( · 58 unmodified lines
407407 struct fs_quota_stat *out)
408408 {
409409 struct xfs_quotainfo *q = mp->m_quotainfo;
410− struct xfs_inode *uip, *gip;
411− bool tempuqip, tempgqip;
410+ struct xfs_inode *uip = NULL;
411+ struct xfs_inode *gip = NULL;
412+ bool tempuqip = false;
413+ bool tempgqip = false;
412414
413− uip = gip = NULL;
414− tempuqip = tempgqip = false;
415415 memset(out, 0, sizeof(fs_quota_stat_t));
416416
417417 out->qs_version = FS_QSTAT_VERSION;
@@ -776,9 +776,12 @@ xfs_qm_scall_getquota( · 358 unmodified lines
776776 * gets turned off. No need to confuse the user level code,
777777 * so return zeroes in that case.
778778 */
779− if ((!XFS_IS_UQUOTA_ENFORCED(mp) && dqp->q_core.d_flags == XFS_DQ_USER) ||
780− (!XFS_IS_OQUOTA_ENFORCED(mp) &&
781− (dqp->q_core.d_flags & (XFS_DQ_PROJ | XFS_DQ_GROUP)))) {
779+ if ((!XFS_IS_UQUOTA_ENFORCED(mp) &&
780+ dqp->q_core.d_flags == XFS_DQ_USER) ||
781+ (!XFS_IS_GQUOTA_ENFORCED(mp) &&
782+ dqp->q_core.d_flags == XFS_DQ_GROUP) ||
783+ (!XFS_IS_PQUOTA_ENFORCED(mp) &&
784+ dqp->q_core.d_flags == XFS_DQ_PROJ)) {
782785 dst->d_btimer = 0;
783786 dst->d_itimer = 0;
784787 dst->d_rtbtimer = 0;
@@ -786,8 +789,8 @@ xfs_qm_scall_getquota( · 1 unmodified line
786789
787790 #ifdef DEBUG
788791 if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == FS_USER_QUOTA) ||
789− (XFS_IS_OQUOTA_ENFORCED(mp) &&
790− (dst->d_flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)))) &&
792+ (XFS_IS_GQUOTA_ENFORCED(mp) && dst->d_flags == FS_GROUP_QUOTA) ||
793+ (XFS_IS_PQUOTA_ENFORCED(mp) && dst->d_flags == FS_PROJ_QUOTA)) &&
791794 dst->d_id != 0) {
792795 if ((dst->d_bcount > dst->d_blk_softlimit) &&
793796 (dst->d_blk_softlimit > 0)) {
@@ -833,16 +836,16 @@ xfs_qm_export_flags( · 39 unmodified lines
833836 uflags = 0;
834837 if (flags & XFS_UQUOTA_ACCT)
835838 uflags |= FS_QUOTA_UDQ_ACCT;
836− if (flags & XFS_PQUOTA_ACCT)
837− uflags |= FS_QUOTA_PDQ_ACCT;
838839 if (flags & XFS_GQUOTA_ACCT)
839840 uflags |= FS_QUOTA_GDQ_ACCT;
841+ if (flags & XFS_PQUOTA_ACCT)
842+ uflags |= FS_QUOTA_PDQ_ACCT;
840843 if (flags & XFS_UQUOTA_ENFD)
841844 uflags |= FS_QUOTA_UDQ_ENFD;
842− if (flags & (XFS_OQUOTA_ENFD)) {
843− uflags |= (flags & XFS_GQUOTA_ACCT) ?
844− FS_QUOTA_GDQ_ENFD : FS_QUOTA_PDQ_ENFD;
845− }
845+ if (flags & XFS_GQUOTA_ENFD)
846+ uflags |= FS_QUOTA_GDQ_ENFD;
847+ if (flags & XFS_PQUOTA_ENFD)
848+ uflags |= FS_QUOTA_PDQ_ENFD;
846849 return (uflags);
847850 }
848851
fs/xfs/xfs_quota.h+29−18
@@ -160,31 +160,43 @@ typedef struct xfs_qoff_logformat { · 159 unmodified lines
160160 #define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */
161161 #define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */
162162
163+/*
164+ * Conversion to and from the combined OQUOTA flag (if necessary)
165+ * is done only in xfs_sb_qflags_to_disk() and xfs_sb_qflags_from_disk()
166+ */
167+#define XFS_GQUOTA_ENFD 0x0080 /* group quota limits enforced */
168+#define XFS_GQUOTA_CHKD 0x0100 /* quotacheck run on group quotas */
169+#define XFS_PQUOTA_ENFD 0x0200 /* project quota limits enforced */
170+#define XFS_PQUOTA_CHKD 0x0400 /* quotacheck run on project quotas */
171+
163172 /*
164173 * Quota Accounting/Enforcement flags
165174 */
166175 #define XFS_ALL_QUOTA_ACCT \
167176 (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
168−#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD)
169−#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
177+#define XFS_ALL_QUOTA_ENFD \
178+ (XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD | XFS_PQUOTA_ENFD)
179+#define XFS_ALL_QUOTA_CHKD \
180+ (XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD | XFS_PQUOTA_CHKD)
170181
171182 #define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
172183 #define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
173184 #define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT)
174185 #define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
175186 #define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD)
176−#define XFS_IS_OQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_OQUOTA_ENFD)
187+#define XFS_IS_GQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_GQUOTA_ENFD)
188+#define XFS_IS_PQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_PQUOTA_ENFD)
177189
178190 /*
179191 * Incore only flags for quotaoff - these bits get cleared when quota(s)
180192 * are in the process of getting turned off. These flags are in m_qflags but
181193 * never in sb_qflags.
182194 */
183−#define XFS_UQUOTA_ACTIVE 0x0100 /* uquotas are being turned off */
184−#define XFS_PQUOTA_ACTIVE 0x0200 /* pquotas are being turned off */
185−#define XFS_GQUOTA_ACTIVE 0x0400 /* gquotas are being turned off */
195+#define XFS_UQUOTA_ACTIVE 0x1000 /* uquotas are being turned off */
196+#define XFS_GQUOTA_ACTIVE 0x2000 /* gquotas are being turned off */
197+#define XFS_PQUOTA_ACTIVE 0x4000 /* pquotas are being turned off */
186198 #define XFS_ALL_QUOTA_ACTIVE \
187− (XFS_UQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE)
199+ (XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE)
188200
189201 /*
190202 * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees
@@ -268,24 +280,23 @@ typedef struct xfs_qoff_logformat { · 77 unmodified lines
268280 ((XFS_IS_UQUOTA_ON(mp) && \
269281 (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \
270282 (XFS_IS_GQUOTA_ON(mp) && \
271− ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
272− (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT))) || \
283+ (mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD) == 0) || \
273284 (XFS_IS_PQUOTA_ON(mp) && \
274− ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
275− (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT))))
285+ (mp->m_sb.sb_qflags & XFS_PQUOTA_CHKD) == 0))
276286
277287 #define XFS_MOUNT_QUOTA_SET1 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
278− XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
279− XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
288+ XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
289+ XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD)
280290
281291 #define XFS_MOUNT_QUOTA_SET2 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
282− XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
283− XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
292+ XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
293+ XFS_PQUOTA_ENFD|XFS_PQUOTA_CHKD)
284294
285295 #define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
286− XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
287− XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\
288− XFS_GQUOTA_ACCT)
296+ XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
297+ XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD|\
298+ XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD|\
299+ XFS_PQUOTA_CHKD)
289300
290301
291302 /*
fs/xfs/xfs_quotaops.c+4−2
@@ -75,8 +75,10 @@ xfs_fs_set_xstate( · 74 unmodified lines
7575 flags |= XFS_GQUOTA_ACCT;
7676 if (uflags & FS_QUOTA_UDQ_ENFD)
7777 flags |= XFS_UQUOTA_ENFD;
78− if (uflags & (FS_QUOTA_PDQ_ENFD|FS_QUOTA_GDQ_ENFD))
79− flags |= XFS_OQUOTA_ENFD;
78+ if (uflags & FS_QUOTA_GDQ_ENFD)
79+ flags |= XFS_GQUOTA_ENFD;
80+ if (uflags & FS_QUOTA_PDQ_ENFD)
81+ flags |= XFS_PQUOTA_ENFD;
8082
8183 switch (op) {
8284 case Q_XQUOTAON:
fs/xfs/xfs_sb.h+6−0
@@ -618,6 +618,12 @@ xfs_sb_has_incompat_log_feature( · 617 unmodified lines
618618 return (sbp->sb_features_log_incompat & feature) != 0;
619619 }
620620
621+static inline bool
622+xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino)
623+{
624+ return (ino == sbp->sb_uquotino || ino == sbp->sb_gquotino);
625+}
626+
621627 /*
622628 * end of superblock version macros
623629 */
fs/xfs/xfs_super.c+23−16
@@ -51,6 +51,7 @@ · 50 unmodified lines
5151 #include "xfs_inode_item.h"
5252 #include "xfs_icache.h"
5353 #include "xfs_trace.h"
54+#include "xfs_icreate_item.h"
5455
5556 #include <linux/namei.h>
5657 #include <linux/init.h>
@@ -359,17 +360,17 @@ xfs_parseargs( · 302 unmodified lines
359360 } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
360361 !strcmp(this_char, MNTOPT_PRJQUOTA)) {
361362 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
362− XFS_OQUOTA_ENFD);
363+ XFS_PQUOTA_ENFD);
363364 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
364365 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
365− mp->m_qflags &= ~XFS_OQUOTA_ENFD;
366+ mp->m_qflags &= ~XFS_PQUOTA_ENFD;
366367 } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
367368 !strcmp(this_char, MNTOPT_GRPQUOTA)) {
368369 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
369− XFS_OQUOTA_ENFD);
370+ XFS_GQUOTA_ENFD);
370371 } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
371372 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
372− mp->m_qflags &= ~XFS_OQUOTA_ENFD;
373+ mp->m_qflags &= ~XFS_GQUOTA_ENFD;
373374 } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) {
374375 xfs_warn(mp,
375376 "delaylog is the default now, option is deprecated.");
@@ -439,20 +440,15 @@ xfs_parseargs( · 63 unmodified lines
439440 }
440441
441442 done:
442− if (!(mp->m_flags & XFS_MOUNT_NOALIGN)) {
443+ if (dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
443444 /*
444445 * At this point the superblock has not been read
445446 * in, therefore we do not know the block size.
446447 * Before the mount call ends we will convert
447448 * these to FSBs.
448449 */
449− if (dsunit) {
450− mp->m_dalign = dsunit;
451− mp->m_flags |= XFS_MOUNT_RETERR;
452− }
453−
454− if (dswidth)
455− mp->m_swidth = dswidth;
450+ mp->m_dalign = dsunit;
451+ mp->m_swidth = dswidth;
456452 }
457453
458454 if (mp->m_logbufs != -1 &&
@@ -563,12 +559,12 @@ xfs_showargs( · 104 unmodified lines
563559 /* Either project or group quotas can be active, not both */
564560
565561 if (mp->m_qflags & XFS_PQUOTA_ACCT) {
566− if (mp->m_qflags & XFS_OQUOTA_ENFD)
562+ if (mp->m_qflags & XFS_PQUOTA_ENFD)
567563 seq_puts(m, "," MNTOPT_PRJQUOTA);
568564 else
569565 seq_puts(m, "," MNTOPT_PQUOTANOENF);
570566 } else if (mp->m_qflags & XFS_GQUOTA_ACCT) {
571− if (mp->m_qflags & XFS_OQUOTA_ENFD)
567+ if (mp->m_qflags & XFS_GQUOTA_ENFD)
572568 seq_puts(m, "," MNTOPT_GRPQUOTA);
573569 else
574570 seq_puts(m, "," MNTOPT_GQUOTANOENF);
@@ -1136,8 +1132,8 @@ xfs_fs_statfs( · 561 unmodified lines
11361132 spin_unlock(&mp->m_sb_lock);
11371133
11381134 if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
1139− ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
1140− (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
1135+ ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) ==
1136+ (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))
11411137 xfs_qm_statvfs(ip, statp);
11421138 return 0;
11431139 }
@@ -1481,6 +1477,10 @@ xfs_fs_fill_super( · 337 unmodified lines
14811477 sb->s_time_gran = 1;
14821478 set_posix_acl_flag(sb);
14831479
1480+ /* version 5 superblocks support inode version counters. */
1481+ if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5)
1482+ sb->s_flags |= MS_I_VERSION;
1483+
14841484 error = xfs_mountfs(mp);
14851485 if (error)
14861486 goto out_filestream_unmount;
@@ -1655,9 +1655,15 @@ xfs_init_zones(void) · 168 unmodified lines
16551655 KM_ZONE_SPREAD, NULL);
16561656 if (!xfs_ili_zone)
16571657 goto out_destroy_inode_zone;
1658+ xfs_icreate_zone = kmem_zone_init(sizeof(struct xfs_icreate_item),
1659+ "xfs_icr");
1660+ if (!xfs_icreate_zone)
1661+ goto out_destroy_ili_zone;
16581662
16591663 return 0;
16601664
1665+ out_destroy_ili_zone:
1666+ kmem_zone_destroy(xfs_ili_zone);
16611667 out_destroy_inode_zone:
16621668 kmem_zone_destroy(xfs_inode_zone);
16631669 out_destroy_efi_zone:
@@ -1696,6 +1702,7 @@ xfs_destroy_zones(void) · 32 unmodified lines
16961702 * destroy caches.
16971703 */
16981704 rcu_barrier();
1705+ kmem_zone_destroy(xfs_icreate_zone);
16991706 kmem_zone_destroy(xfs_ili_zone);
17001707 kmem_zone_destroy(xfs_inode_zone);
17011708 kmem_zone_destroy(xfs_efi_zone);
fs/xfs/xfs_symlink.c+48−3
@@ -358,7 +358,8 @@ xfs_symlink( · 357 unmodified lines
358358 int n;
359359 xfs_buf_t *bp;
360360 prid_t prid;
361− struct xfs_dquot *udqp, *gdqp;
361+ struct xfs_dquot *udqp = NULL;
362+ struct xfs_dquot *gdqp = NULL;
362363 uint resblks;
363364
364365 *ipp = NULL;
@@ -585,7 +586,7 @@ xfs_symlink( · 220 unmodified lines
585586 /*
586587 * Free a symlink that has blocks associated with it.
587588 */
588−int
589+STATIC int
589590 xfs_inactive_symlink_rmt(
590591 xfs_inode_t *ip,
591592 xfs_trans_t **tpp)
@@ -606,7 +607,7 @@ xfs_inactive_symlink_rmt( · 14 unmodified lines
606607
607608 tp = *tpp;
608609 mp = ip->i_mount;
609− ASSERT(ip->i_d.di_size > XFS_IFORK_DSIZE(ip));
610+ ASSERT(ip->i_df.if_flags & XFS_IFEXTENTS);
610611 /*
611612 * We're freeing a symlink that has some
612613 * blocks allocated to it. Free the
@@ -720,3 +721,47 @@ xfs_inactive_symlink_rmt( · 107 unmodified lines
720721 error0:
721722 return error;
722723 }
724+
725+/*
726+ * xfs_inactive_symlink - free a symlink
727+ */
728+int
729+xfs_inactive_symlink(
730+ struct xfs_inode *ip,
731+ struct xfs_trans **tp)
732+{
733+ struct xfs_mount *mp = ip->i_mount;
734+ int pathlen;
735+
736+ trace_xfs_inactive_symlink(ip);
737+
738+ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
739+
740+ if (XFS_FORCED_SHUTDOWN(mp))
741+ return XFS_ERROR(EIO);
742+
743+ /*
744+ * Zero length symlinks _can_ exist.
745+ */
746+ pathlen = (int)ip->i_d.di_size;
747+ if (!pathlen)
748+ return 0;
749+
750+ if (pathlen < 0 || pathlen > MAXPATHLEN) {
751+ xfs_alert(mp, "%s: inode (0x%llx) bad symlink length (%d)",
752+ __func__, (unsigned long long)ip->i_ino, pathlen);
753+ ASSERT(0);
754+ return XFS_ERROR(EFSCORRUPTED);
755+ }
756+
757+ if (ip->i_df.if_flags & XFS_IFINLINE) {
758+ if (ip->i_df.if_bytes > 0)
759+ xfs_idata_realloc(ip, -(ip->i_df.if_bytes),
760+ XFS_DATA_FORK);
761+ ASSERT(ip->i_df.if_bytes == 0);
762+ return 0;
763+ }
764+
765+ /* remove the remote symlink */
766+ return xfs_inactive_symlink_rmt(ip, tp);
767+}
fs/xfs/xfs_symlink.h+1−1
@@ -60,7 +60,7 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops; · 59 unmodified lines
6060 int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name,
6161 const char *target_path, umode_t mode, struct xfs_inode **ipp);
6262 int xfs_readlink(struct xfs_inode *ip, char *link);
63−int xfs_inactive_symlink_rmt(struct xfs_inode *ip, struct xfs_trans **tpp);
63+int xfs_inactive_symlink(struct xfs_inode *ip, struct xfs_trans **tpp);
6464
6565 #endif /* __KERNEL__ */
6666 #endif /* __XFS_SYMLINK_H */
fs/xfs/xfs_sysctl.c+13−13
@@ -25,11 +25,11 @@ static struct ctl_table_header *xfs_table_header; · 24 unmodified lines
2525 #ifdef CONFIG_PROC_FS
2626 STATIC int
2727 xfs_stats_clear_proc_handler(
28− ctl_table *ctl,
29− int write,
30− void __user *buffer,
31− size_t *lenp,
32− loff_t *ppos)
28+ struct ctl_table *ctl,
29+ int write,
30+ void __user *buffer,
31+ size_t *lenp,
32+ loff_t *ppos)
3333 {
3434 int c, ret, *valp = ctl->data;
3535 __uint32_t vn_active;
@@ -55,11 +55,11 @@ xfs_stats_clear_proc_handler( · 19 unmodified lines
5555
5656 STATIC int
5757 xfs_panic_mask_proc_handler(
58− ctl_table *ctl,
59− int write,
60− void __user *buffer,
61− size_t *lenp,
62− loff_t *ppos)
58+ struct ctl_table *ctl,
59+ int write,
60+ void __user *buffer,
61+ size_t *lenp,
62+ loff_t *ppos)
6363 {
6464 int ret, *valp = ctl->data;
6565
@@ -74,7 +74,7 @@ xfs_panic_mask_proc_handler( · 8 unmodified lines
7474 }
7575 #endif /* CONFIG_PROC_FS */
7676
77−static ctl_table xfs_table[] = {
77+static struct ctl_table xfs_table[] = {
7878 {
7979 .procname = "irix_sgid_inherit",
8080 .data = &xfs_params.sgid_inherit.val,
@@ -227,7 +227,7 @@ static ctl_table xfs_table[] = { · 146 unmodified lines
227227 {}
228228 };
229229
230−static ctl_table xfs_dir_table[] = {
230+static struct ctl_table xfs_dir_table[] = {
231231 {
232232 .procname = "xfs",
233233 .mode = 0555,
@@ -236,7 +236,7 @@ static ctl_table xfs_dir_table[] = { · 2 unmodified lines
236236 {}
237237 };
238238
239−static ctl_table xfs_root_table[] = {
239+static struct ctl_table xfs_root_table[] = {
240240 {
241241 .procname = "fs",
242242 .mode = 0555,
fs/xfs/xfs_trace.h+5−0
@@ -486,9 +486,12 @@ DEFINE_EVENT(xfs_buf_item_class, name, \ · 485 unmodified lines
486486 TP_PROTO(struct xfs_buf_log_item *bip), \
487487 TP_ARGS(bip))
488488 DEFINE_BUF_ITEM_EVENT(xfs_buf_item_size);
489+DEFINE_BUF_ITEM_EVENT(xfs_buf_item_size_ordered);
489490 DEFINE_BUF_ITEM_EVENT(xfs_buf_item_size_stale);
490491 DEFINE_BUF_ITEM_EVENT(xfs_buf_item_format);
492+DEFINE_BUF_ITEM_EVENT(xfs_buf_item_format_ordered);
491493 DEFINE_BUF_ITEM_EVENT(xfs_buf_item_format_stale);
494+DEFINE_BUF_ITEM_EVENT(xfs_buf_item_ordered);
492495 DEFINE_BUF_ITEM_EVENT(xfs_buf_item_pin);
493496 DEFINE_BUF_ITEM_EVENT(xfs_buf_item_unpin);
494497 DEFINE_BUF_ITEM_EVENT(xfs_buf_item_unpin_stale);
@@ -508,6 +511,7 @@ DEFINE_BUF_ITEM_EVENT(xfs_trans_bjoin); · 13 unmodified lines
508511 DEFINE_BUF_ITEM_EVENT(xfs_trans_bhold);
509512 DEFINE_BUF_ITEM_EVENT(xfs_trans_bhold_release);
510513 DEFINE_BUF_ITEM_EVENT(xfs_trans_binval);
514+DEFINE_BUF_ITEM_EVENT(xfs_trans_buf_ordered);
511515
512516 DECLARE_EVENT_CLASS(xfs_lock_class,
513517 TP_PROTO(struct xfs_inode *ip, unsigned lock_flags,
@@ -571,6 +575,7 @@ DEFINE_INODE_EVENT(xfs_iget_miss); · 57 unmodified lines
571575 DEFINE_INODE_EVENT(xfs_getattr);
572576 DEFINE_INODE_EVENT(xfs_setattr);
573577 DEFINE_INODE_EVENT(xfs_readlink);
578+DEFINE_INODE_EVENT(xfs_inactive_symlink);
574579 DEFINE_INODE_EVENT(xfs_alloc_file_space);
575580 DEFINE_INODE_EVENT(xfs_free_file_space);
576581 DEFINE_INODE_EVENT(xfs_readdir);
fs/xfs/xfs_trans.c+77−41
@@ -234,71 +234,93 @@ xfs_calc_remove_reservation( · 233 unmodified lines
234234 }
235235
236236 /*
237− * For symlink we can modify:
237+ * For create, break it in to the two cases that the transaction
238+ * covers. We start with the modify case - allocation done by modification
239+ * of the state of existing inodes - and the allocation case.
240+ */
241+
242+/*
243+ * For create we can modify:
238244 * the parent directory inode: inode size
239245 * the new inode: inode size
240− * the inode btree entry: 1 block
246+ * the inode btree entry: block size
247+ * the superblock for the nlink flag: sector size
241248 * the directory btree: (max depth + v2) * dir block size
242249 * the directory inode's bmap btree: (max depth + v2) * block size
243− * the blocks for the symlink: 1 kB
244− * Or in the first xact we allocate some inodes giving:
250+ */
251+STATIC uint
252+xfs_calc_create_resv_modify(
253+ struct xfs_mount *mp)
254+{
255+ return xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
256+ xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
257+ (uint)XFS_FSB_TO_B(mp, 1) +
258+ xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1));
259+}
260+
261+/*
262+ * For create we can allocate some inodes giving:
245263 * the agi and agf of the ag getting the new inodes: 2 * sectorsize
264+ * the superblock for the nlink flag: sector size
246265 * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
247266 * the inode btree: max depth * blocksize
248− * the allocation btrees: 2 trees * (2 * max depth - 1) * block size
267+ * the allocation btrees: 2 trees * (max depth - 1) * block size
249268 */
250269 STATIC uint
251−xfs_calc_symlink_reservation(
270+xfs_calc_create_resv_alloc(
271+ struct xfs_mount *mp)
272+{
273+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
274+ mp->m_sb.sb_sectsize +
275+ xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp), XFS_FSB_TO_B(mp, 1)) +
276+ xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
277+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
278+ XFS_FSB_TO_B(mp, 1));
279+}
280+
281+STATIC uint
282+__xfs_calc_create_reservation(
252283 struct xfs_mount *mp)
253284 {
254285 return XFS_DQUOT_LOGRES(mp) +
255− MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
256− xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) +
257− xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
258− XFS_FSB_TO_B(mp, 1)) +
259− xfs_calc_buf_res(1, 1024)),
260− (xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
261− xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp),
262− XFS_FSB_TO_B(mp, 1)) +
263− xfs_calc_buf_res(mp->m_in_maxlevels,
264− XFS_FSB_TO_B(mp, 1)) +
265− xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
266− XFS_FSB_TO_B(mp, 1))));
286+ MAX(xfs_calc_create_resv_alloc(mp),
287+ xfs_calc_create_resv_modify(mp));
267288 }
268289
269290 /*
270− * For create we can modify:
271− * the parent directory inode: inode size
272− * the new inode: inode size
273− * the inode btree entry: block size
274− * the superblock for the nlink flag: sector size
275− * the directory btree: (max depth + v2) * dir block size
276− * the directory inode's bmap btree: (max depth + v2) * block size
277− * Or in the first xact we allocate some inodes giving:
291+ * For icreate we can allocate some inodes giving:
278292 * the agi and agf of the ag getting the new inodes: 2 * sectorsize
279293 * the superblock for the nlink flag: sector size
280− * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
281294 * the inode btree: max depth * blocksize
282295 * the allocation btrees: 2 trees * (max depth - 1) * block size
283296 */
284297 STATIC uint
285−xfs_calc_create_reservation(
298+xfs_calc_icreate_resv_alloc(
286299 struct xfs_mount *mp)
300+{
301+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
302+ mp->m_sb.sb_sectsize +
303+ xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
304+ xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
305+ XFS_FSB_TO_B(mp, 1));
306+}
307+
308+STATIC uint
309+xfs_calc_icreate_reservation(xfs_mount_t *mp)
287310 {
288311 return XFS_DQUOT_LOGRES(mp) +
289− MAX((xfs_calc_buf_res(2, mp->m_sb.sb_inodesize) +
290− xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
291− (uint)XFS_FSB_TO_B(mp, 1) +
292− xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
293− XFS_FSB_TO_B(mp, 1))),
294− (xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
295− mp->m_sb.sb_sectsize +
296− xfs_calc_buf_res(XFS_IALLOC_BLOCKS(mp),
297− XFS_FSB_TO_B(mp, 1)) +
298− xfs_calc_buf_res(mp->m_in_maxlevels,
299− XFS_FSB_TO_B(mp, 1)) +
300− xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
301− XFS_FSB_TO_B(mp, 1))));
312+ MAX(xfs_calc_icreate_resv_alloc(mp),
313+ xfs_calc_create_resv_modify(mp));
314+}
315+
316+STATIC uint
317+xfs_calc_create_reservation(
318+ struct xfs_mount *mp)
319+{
320+ if (xfs_sb_version_hascrc(&mp->m_sb))
321+ return xfs_calc_icreate_reservation(mp);
322+ return __xfs_calc_create_reservation(mp);
323+
302324 }
303325
304326 /*
@@ -311,6 +333,20 @@ xfs_calc_mkdir_reservation( · 6 unmodified lines
311333 return xfs_calc_create_reservation(mp);
312334 }
313335
336+
337+/*
338+ * Making a new symplink is the same as creating a new file, but
339+ * with the added blocks for remote symlink data which can be up to 1kB in
340+ * length (MAXPATHLEN).
341+ */
342+STATIC uint
343+xfs_calc_symlink_reservation(
344+ struct xfs_mount *mp)
345+{
346+ return xfs_calc_create_reservation(mp) +
347+ xfs_calc_buf_res(1, MAXPATHLEN);
348+}
349+
314350 /*
315351 * In freeing an inode we can modify:
316352 * the inode being freed: inode size
fs/xfs/xfs_trans.h+7−9
@@ -48,6 +48,7 @@ typedef struct xfs_trans_header { · 47 unmodified lines
4848 #define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */
4949 #define XFS_LI_DQUOT 0x123d
5050 #define XFS_LI_QUOTAOFF 0x123e
51+#define XFS_LI_ICREATE 0x123f
5152
5253 #define XFS_LI_TYPE_DESC \
5354 { XFS_LI_EFI, "XFS_LI_EFI" }, \
@@ -107,7 +108,8 @@ typedef struct xfs_trans_header { · 53 unmodified lines
107108 #define XFS_TRANS_SWAPEXT 40
108109 #define XFS_TRANS_SB_COUNT 41
109110 #define XFS_TRANS_CHECKPOINT 42
110−#define XFS_TRANS_TYPE_MAX 42
111+#define XFS_TRANS_ICREATE 43
112+#define XFS_TRANS_TYPE_MAX 43
111113 /* new transaction types need to be reflected in xfs_logprint(8) */
112114
113115 #define XFS_TRANS_TYPES \
@@ -210,23 +212,18 @@ struct xfs_log_item_desc { · 96 unmodified lines
210212 /*
211213 * Per-extent log reservation for the allocation btree changes
212214 * involved in freeing or allocating an extent.
213− * 2 trees * (2 blocks/level * max depth - 1) * block size
215+ * 2 trees * (2 blocks/level * max depth - 1)
214216 */
215−#define XFS_ALLOCFREE_LOG_RES(mp,nx) \
216− ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * XFS_AG_MAXLEVELS(mp) - 1)))
217217 #define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \
218218 ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1)))
219219
220220 /*
221221 * Per-directory log reservation for any directory change.
222− * dir blocks: (1 btree block per level + data block + free block) * dblock size
223− * bmap btree: (levels + 2) * max depth * block size
222+ * dir blocks: (1 btree block per level + data block + free block)
223+ * bmap btree: (levels + 2) * max depth
224224 * v2 directory blocks can be fragmented below the dirblksize down to the fsb
225225 * size, so account for that in the DAENTER macros.
226226 */
227−#define XFS_DIROP_LOG_RES(mp) \
228− (XFS_FSB_TO_B(mp, XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK)) + \
229− (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)))
230227 #define XFS_DIROP_LOG_COUNT(mp) \
231228 (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \
232229 XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)
@@ -503,6 +500,7 @@ void xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *); · 270 unmodified lines
503500 void xfs_trans_binval(xfs_trans_t *, struct xfs_buf *);
504501 void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);
505502 void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *);
503+void xfs_trans_ordered_buf(xfs_trans_t *, struct xfs_buf *);
506504 void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
507505 void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
508506 void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int);
fs/xfs/xfs_trans_buf.c+31−3
@@ -397,7 +397,6 @@ shutdown_abort: · 396 unmodified lines
397397 return XFS_ERROR(EIO);
398398 }
399399
400−
401400 /*
402401 * Release the buffer bp which was previously acquired with one of the
403402 * xfs_trans_... buffer allocation routines if the buffer has not
@@ -603,8 +602,14 @@ xfs_trans_log_buf(xfs_trans_t *tp, · 199 unmodified lines
603602
604603 tp->t_flags |= XFS_TRANS_DIRTY;
605604 bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY;
606− bip->bli_flags |= XFS_BLI_LOGGED;
607− xfs_buf_item_log(bip, first, last);
605+
606+ /*
607+ * If we have an ordered buffer we are not logging any dirty range but
608+ * it still needs to be marked dirty and that it has been logged.
609+ */
610+ bip->bli_flags |= XFS_BLI_DIRTY | XFS_BLI_LOGGED;
611+ if (!(bip->bli_flags & XFS_BLI_ORDERED))
612+ xfs_buf_item_log(bip, first, last);
608613 }
609614
610615
@@ -756,6 +761,29 @@ xfs_trans_inode_alloc_buf( · 145 unmodified lines
756761 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
757762 }
758763
764+/*
765+ * Mark the buffer as ordered for this transaction. This means
766+ * that the contents of the buffer are not recorded in the transaction
767+ * but it is tracked in the AIL as though it was. This allows us
768+ * to record logical changes in transactions rather than the physical
769+ * changes we make to the buffer without changing writeback ordering
770+ * constraints of metadata buffers.
771+ */
772+void
773+xfs_trans_ordered_buf(
774+ struct xfs_trans *tp,
775+ struct xfs_buf *bp)
776+{
777+ struct xfs_buf_log_item *bip = bp->b_fspriv;
778+
779+ ASSERT(bp->b_transp == tp);
780+ ASSERT(bip != NULL);
781+ ASSERT(atomic_read(&bip->bli_refcount) > 0);
782+
783+ bip->bli_flags |= XFS_BLI_ORDERED;
784+ trace_xfs_buf_item_ordered(bip);
785+}
786+
759787 /*
760788 * Set the type of the buffer for log recovery so that it can correctly identify
761789 * and hence attach the correct buffer ops to the buffer after replay.
fs/xfs/xfs_trans_dquot.c+37−50
@@ -103,8 +103,6 @@ xfs_trans_dup_dqinfo( · 102 unmodified lines
103103 return;
104104
105105 xfs_trans_alloc_dqinfo(ntp);
106− oqa = otp->t_dqinfo->dqa_usrdquots;
107− nqa = ntp->t_dqinfo->dqa_usrdquots;
108106
109107 /*
110108 * Because the quota blk reservation is carried forward,
@@ -113,7 +111,9 @@ xfs_trans_dup_dqinfo( · 2 unmodified lines
113111 if(otp->t_flags & XFS_TRANS_DQ_DIRTY)
114112 ntp->t_flags |= XFS_TRANS_DQ_DIRTY;
115113
116− for (j = 0; j < 2; j++) {
114+ for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
115+ oqa = otp->t_dqinfo->dqs[j];
116+ nqa = ntp->t_dqinfo->dqs[j];
117117 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
118118 if (oqa[i].qt_dquot == NULL)
119119 break;
@@ -138,8 +138,6 @@ xfs_trans_dup_dqinfo( · 18 unmodified lines
138138 oq->qt_ino_res = oq->qt_ino_res_used;
139139
140140 }
141− oqa = otp->t_dqinfo->dqa_grpdquots;
142− nqa = ntp->t_dqinfo->dqa_grpdquots;
143141 }
144142 }
145143
@@ -157,8 +155,7 @@ xfs_trans_mod_dquot_byino( · 11 unmodified lines
157155
158156 if (!XFS_IS_QUOTA_RUNNING(mp) ||
159157 !XFS_IS_QUOTA_ON(mp) ||
160− ip->i_ino == mp->m_sb.sb_uquotino ||
161− ip->i_ino == mp->m_sb.sb_gquotino)
158+ xfs_is_quota_inode(&mp->m_sb, ip->i_ino))
162159 return;
163160
164161 if (tp->t_dqinfo == NULL)
@@ -170,16 +167,18 @@ xfs_trans_mod_dquot_byino( · 5 unmodified lines
170167 (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
171168 }
172169
173−STATIC xfs_dqtrx_t *
170+STATIC struct xfs_dqtrx *
174171 xfs_trans_get_dqtrx(
175− xfs_trans_t *tp,
176− xfs_dquot_t *dqp)
172+ struct xfs_trans *tp,
173+ struct xfs_dquot *dqp)
177174 {
178− int i;
179− xfs_dqtrx_t *qa;
175+ int i;
176+ struct xfs_dqtrx *qa;
180177
181− qa = XFS_QM_ISUDQ(dqp) ?
182− tp->t_dqinfo->dqa_usrdquots : tp->t_dqinfo->dqa_grpdquots;
178+ if (XFS_QM_ISUDQ(dqp))
179+ qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_USR];
180+ else
181+ qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_GRP];
183182
184183 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
185184 if (qa[i].qt_dquot == NULL ||
@@ -339,12 +338,10 @@ xfs_trans_apply_dquot_deltas( · 153 unmodified lines
339338 return;
340339
341340 ASSERT(tp->t_dqinfo);
342− qa = tp->t_dqinfo->dqa_usrdquots;
343− for (j = 0; j < 2; j++) {
344− if (qa[0].qt_dquot == NULL) {
345− qa = tp->t_dqinfo->dqa_grpdquots;
341+ for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
342+ qa = tp->t_dqinfo->dqs[j];
343+ if (qa[0].qt_dquot == NULL)
346344 continue;
347− }
348345
349346 /*
350347 * Lock all of the dquots and join them to the transaction.
@@ -495,10 +492,6 @@ xfs_trans_apply_dquot_deltas( · 144 unmodified lines
495492 ASSERT(dqp->q_res_rtbcount >=
496493 be64_to_cpu(dqp->q_core.d_rtbcount));
497494 }
498− /*
499− * Do the group quotas next
500− */
501− qa = tp->t_dqinfo->dqa_grpdquots;
502495 }
503496 }
504497
@@ -521,9 +514,9 @@ xfs_trans_unreserve_and_mod_dquots( · 16 unmodified lines
521514 if (!tp->t_dqinfo || !(tp->t_flags & XFS_TRANS_DQ_DIRTY))
522515 return;
523516
524− qa = tp->t_dqinfo->dqa_usrdquots;
517+ for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
518+ qa = tp->t_dqinfo->dqs[j];
525519
526− for (j = 0; j < 2; j++) {
527520 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
528521 qtrx = &qa[i];
529522 /*
@@ -565,7 +558,6 @@ xfs_trans_unreserve_and_mod_dquots( · 35 unmodified lines
565558 xfs_dqunlock(dqp);
566559
567560 }
568− qa = tp->t_dqinfo->dqa_grpdquots;
569561 }
570562 }
571563
@@ -640,8 +632,8 @@ xfs_trans_dqresv( · 68 unmodified lines
640632 if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
641633 dqp->q_core.d_id &&
642634 ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
643− (XFS_IS_OQUOTA_ENFORCED(dqp->q_mount) &&
644− (XFS_QM_ISPDQ(dqp) || XFS_QM_ISGDQ(dqp))))) {
635+ (XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) ||
636+ (XFS_IS_PQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISPDQ(dqp)))) {
645637 if (nblks > 0) {
646638 /*
647639 * dquot is locked already. See if we'd go over the
@@ -748,15 +740,15 @@ error_return: · 100 unmodified lines
748740 */
749741 int
750742 xfs_trans_reserve_quota_bydquots(
751− xfs_trans_t *tp,
752− xfs_mount_t *mp,
753− xfs_dquot_t *udqp,
754− xfs_dquot_t *gdqp,
755− long nblks,
756− long ninos,
757− uint flags)
743+ struct xfs_trans *tp,
744+ struct xfs_mount *mp,
745+ struct xfs_dquot *udqp,
746+ struct xfs_dquot *gdqp,
747+ long nblks,
748+ long ninos,
749+ uint flags)
758750 {
759− int resvd = 0, error;
751+ int error;
760752
761753 if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
762754 return 0;
@@ -771,28 +763,24 @@ xfs_trans_reserve_quota_bydquots( · 8 unmodified lines
771763 (flags & ~XFS_QMOPT_ENOSPC));
772764 if (error)
773765 return error;
774− resvd = 1;
775766 }
776767
777768 if (gdqp) {
778769 error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
779− if (error) {
780− /*
781− * can't do it, so backout previous reservation
782− */
783− if (resvd) {
784− flags |= XFS_QMOPT_FORCE_RES;
785− xfs_trans_dqresv(tp, mp, udqp,
786− -nblks, -ninos, flags);
787− }
788− return error;
789− }
770+ if (error)
771+ goto unwind_usr;
790772 }
791773
792774 /*
793775 * Didn't change anything critical, so, no need to log
794776 */
795777 return 0;
778+
779+unwind_usr:
780+ flags |= XFS_QMOPT_FORCE_RES;
781+ if (udqp)
782+ xfs_trans_dqresv(tp, mp, udqp, -nblks, -ninos, flags);
783+ return error;
796784 }
797785
798786
@@ -816,8 +804,7 @@ xfs_trans_reserve_quota_nblks( · 17 unmodified lines
816804 if (XFS_IS_PQUOTA_ON(mp))
817805 flags |= XFS_QMOPT_ENOSPC;
818806
819− ASSERT(ip->i_ino != mp->m_sb.sb_uquotino);
820− ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);
807+ ASSERT(!xfs_is_quota_inode(&mp->m_sb, ip->i_ino));
821808
822809 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
823810 ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
fs/xfs/xfs_trans_inode.c+11−0
@@ -112,6 +112,17 @@ xfs_trans_log_inode( · 111 unmodified lines
112112 ASSERT(ip->i_itemp != NULL);
113113 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
114114
115+ /*
116+ * First time we log the inode in a transaction, bump the inode change
117+ * counter if it is configured for this to occur.
118+ */
119+ if (!(ip->i_itemp->ili_item.li_desc->lid_flags & XFS_LID_DIRTY) &&
120+ IS_I_VERSION(VFS_I(ip))) {
121+ inode_inc_iversion(VFS_I(ip));
122+ ip->i_d.di_changecount = VFS_I(ip)->i_version;
123+ flags |= XFS_ILOG_CORE;
124+ }
125+
115126 tp->t_flags |= XFS_TRANS_DIRTY;
116127 ip->i_itemp->ili_item.li_desc->lid_flags |= XFS_LID_DIRTY;
117128
fs/xfs/xfs_vnodeops.c+3−12
@@ -322,18 +322,9 @@ xfs_inactive( · 321 unmodified lines
322322 xfs_trans_ijoin(tp, ip, 0);
323323
324324 if (S_ISLNK(ip->i_d.di_mode)) {
325− /*
326− * Zero length symlinks _can_ exist.
327− */
328− if (ip->i_d.di_size > XFS_IFORK_DSIZE(ip)) {
329− error = xfs_inactive_symlink_rmt(ip, &tp);
330− if (error)
331− goto out_cancel;
332− } else if (ip->i_df.if_bytes > 0) {
333− xfs_idata_realloc(ip, -(ip->i_df.if_bytes),
334− XFS_DATA_FORK);
335− ASSERT(ip->i_df.if_bytes == 0);
336− }
325+ error = xfs_inactive_symlink(ip, &tp);
326+ if (error)
327+ goto out_cancel;
337328 } else if (truncate) {
338329 ip->i_d.di_size = 0;
339330 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);