Skip to content

Commit 110b938

Browse files
committed
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
* 'for-linus' of git://oss.sgi.com/xfs/xfs: xfs: Ensure inode allocation buffers are fully replayed xfs: enable background pushing of the CIL xfs: forced unmounts need to push the CIL xfs: Introduce delayed logging core code xfs: Delayed logging design documentation xfs: Improve scalability of busy extent tracking xfs: make the log ticket ID available outside the log infrastructure xfs: clean up log ticket overrun debug output xfs: Clean up XFS_BLI_* flag namespace xfs: modify buffer item reference counting xfs: allow log ticket allocation to take allocation flags xfs: Don't reuse the same transaction ID for duplicated transactions.
2 parents 4961ab9 + 88e8837 commit 110b938

27 files changed

+2382
-513
lines changed

Documentation/filesystems/xfs-delayed-logging-design.txt

Lines changed: 816 additions & 0 deletions
Large diffs are not rendered by default.

fs/xfs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ xfs-y += xfs_alloc.o \
7777
xfs_itable.o \
7878
xfs_dfrag.o \
7979
xfs_log.o \
80+
xfs_log_cil.o \
8081
xfs_log_recover.o \
8182
xfs_mount.o \
8283
xfs_mru_cache.o \

fs/xfs/linux-2.6/xfs_buf.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
#include "xfs_sb.h"
3939
#include "xfs_inum.h"
40+
#include "xfs_log.h"
4041
#include "xfs_ag.h"
4142
#include "xfs_dmapi.h"
4243
#include "xfs_mount.h"
@@ -850,13 +851,21 @@ xfs_buf_lock_value(
850851
* Note that this in no way locks the underlying pages, so it is only
851852
* useful for synchronizing concurrent use of buffer objects, not for
852853
* synchronizing independent access to the underlying pages.
854+
*
855+
* If we come across a stale, pinned, locked buffer, we know that we
856+
* are being asked to lock a buffer that has been reallocated. Because
857+
* it is pinned, we know that the log has not been pushed to disk and
858+
* hence it will still be locked. Rather than sleeping until someone
859+
* else pushes the log, push it ourselves before trying to get the lock.
853860
*/
854861
void
855862
xfs_buf_lock(
856863
xfs_buf_t *bp)
857864
{
858865
trace_xfs_buf_lock(bp, _RET_IP_);
859866

867+
if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE))
868+
xfs_log_force(bp->b_mount, 0);
860869
if (atomic_read(&bp->b_io_remaining))
861870
blk_run_address_space(bp->b_target->bt_mapping);
862871
down(&bp->b_sema);

fs/xfs/linux-2.6/xfs_quotaops.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "xfs_dmapi.h"
2020
#include "xfs_sb.h"
2121
#include "xfs_inum.h"
22+
#include "xfs_log.h"
2223
#include "xfs_ag.h"
2324
#include "xfs_mount.h"
2425
#include "xfs_quota.h"

fs/xfs/linux-2.6/xfs_super.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ mempool_t *xfs_ioend_pool;
119119
#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */
120120
#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */
121121
#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */
122+
#define MNTOPT_DELAYLOG "delaylog" /* Delayed loging enabled */
123+
#define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed loging disabled */
122124

123125
/*
124126
* Table driven mount option parser.
@@ -374,6 +376,13 @@ xfs_parseargs(
374376
mp->m_flags |= XFS_MOUNT_DMAPI;
375377
} else if (!strcmp(this_char, MNTOPT_DMI)) {
376378
mp->m_flags |= XFS_MOUNT_DMAPI;
379+
} else if (!strcmp(this_char, MNTOPT_DELAYLOG)) {
380+
mp->m_flags |= XFS_MOUNT_DELAYLOG;
381+
cmn_err(CE_WARN,
382+
"Enabling EXPERIMENTAL delayed logging feature "
383+
"- use at your own risk.\n");
384+
} else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) {
385+
mp->m_flags &= ~XFS_MOUNT_DELAYLOG;
377386
} else if (!strcmp(this_char, "ihashsize")) {
378387
cmn_err(CE_WARN,
379388
"XFS: ihashsize no longer used, option is deprecated.");
@@ -535,6 +544,7 @@ xfs_showargs(
535544
{ XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM },
536545
{ XFS_MOUNT_DMAPI, "," MNTOPT_DMAPI },
537546
{ XFS_MOUNT_GRPID, "," MNTOPT_GRPID },
547+
{ XFS_MOUNT_DELAYLOG, "," MNTOPT_DELAYLOG },
538548
{ 0, NULL }
539549
};
540550
static struct proc_xfs_info xfs_info_unset[] = {
@@ -1755,7 +1765,7 @@ xfs_init_zones(void)
17551765
* but it is much faster.
17561766
*/
17571767
xfs_buf_item_zone = kmem_zone_init((sizeof(xfs_buf_log_item_t) +
1758-
(((XFS_MAX_BLOCKSIZE / XFS_BLI_CHUNK) /
1768+
(((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) /
17591769
NBWORD) * sizeof(int))), "xfs_buf_item");
17601770
if (!xfs_buf_item_zone)
17611771
goto out_destroy_trans_zone;

fs/xfs/linux-2.6/xfs_trace.h

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,83 +1059,112 @@ TRACE_EVENT(xfs_bunmap,
10591059

10601060
);
10611061

1062+
#define XFS_BUSY_SYNC \
1063+
{ 0, "async" }, \
1064+
{ 1, "sync" }
1065+
10621066
TRACE_EVENT(xfs_alloc_busy,
1063-
TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno,
1064-
xfs_extlen_t len, int slot),
1065-
TP_ARGS(mp, agno, agbno, len, slot),
1067+
TP_PROTO(struct xfs_trans *trans, xfs_agnumber_t agno,
1068+
xfs_agblock_t agbno, xfs_extlen_t len, int sync),
1069+
TP_ARGS(trans, agno, agbno, len, sync),
10661070
TP_STRUCT__entry(
10671071
__field(dev_t, dev)
1072+
__field(struct xfs_trans *, tp)
1073+
__field(int, tid)
10681074
__field(xfs_agnumber_t, agno)
10691075
__field(xfs_agblock_t, agbno)
10701076
__field(xfs_extlen_t, len)
1071-
__field(int, slot)
1077+
__field(int, sync)
10721078
),
10731079
TP_fast_assign(
1074-
__entry->dev = mp->m_super->s_dev;
1080+
__entry->dev = trans->t_mountp->m_super->s_dev;
1081+
__entry->tp = trans;
1082+
__entry->tid = trans->t_ticket->t_tid;
10751083
__entry->agno = agno;
10761084
__entry->agbno = agbno;
10771085
__entry->len = len;
1078-
__entry->slot = slot;
1086+
__entry->sync = sync;
10791087
),
1080-
TP_printk("dev %d:%d agno %u agbno %u len %u slot %d",
1088+
TP_printk("dev %d:%d trans 0x%p tid 0x%x agno %u agbno %u len %u %s",
10811089
MAJOR(__entry->dev), MINOR(__entry->dev),
1090+
__entry->tp,
1091+
__entry->tid,
10821092
__entry->agno,
10831093
__entry->agbno,
10841094
__entry->len,
1085-
__entry->slot)
1095+
__print_symbolic(__entry->sync, XFS_BUSY_SYNC))
10861096

10871097
);
10881098

1089-
#define XFS_BUSY_STATES \
1090-
{ 0, "found" }, \
1091-
{ 1, "missing" }
1092-
10931099
TRACE_EVENT(xfs_alloc_unbusy,
10941100
TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno,
1095-
int slot, int found),
1096-
TP_ARGS(mp, agno, slot, found),
1101+
xfs_agblock_t agbno, xfs_extlen_t len),
1102+
TP_ARGS(mp, agno, agbno, len),
10971103
TP_STRUCT__entry(
10981104
__field(dev_t, dev)
10991105
__field(xfs_agnumber_t, agno)
1100-
__field(int, slot)
1101-
__field(int, found)
1106+
__field(xfs_agblock_t, agbno)
1107+
__field(xfs_extlen_t, len)
11021108
),
11031109
TP_fast_assign(
11041110
__entry->dev = mp->m_super->s_dev;
11051111
__entry->agno = agno;
1106-
__entry->slot = slot;
1107-
__entry->found = found;
1112+
__entry->agbno = agbno;
1113+
__entry->len = len;
11081114
),
1109-
TP_printk("dev %d:%d agno %u slot %d %s",
1115+
TP_printk("dev %d:%d agno %u agbno %u len %u",
11101116
MAJOR(__entry->dev), MINOR(__entry->dev),
11111117
__entry->agno,
1112-
__entry->slot,
1113-
__print_symbolic(__entry->found, XFS_BUSY_STATES))
1118+
__entry->agbno,
1119+
__entry->len)
11141120
);
11151121

1122+
#define XFS_BUSY_STATES \
1123+
{ 0, "missing" }, \
1124+
{ 1, "found" }
1125+
11161126
TRACE_EVENT(xfs_alloc_busysearch,
1117-
TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno,
1118-
xfs_extlen_t len, xfs_lsn_t lsn),
1119-
TP_ARGS(mp, agno, agbno, len, lsn),
1127+
TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno,
1128+
xfs_agblock_t agbno, xfs_extlen_t len, int found),
1129+
TP_ARGS(mp, agno, agbno, len, found),
11201130
TP_STRUCT__entry(
11211131
__field(dev_t, dev)
11221132
__field(xfs_agnumber_t, agno)
11231133
__field(xfs_agblock_t, agbno)
11241134
__field(xfs_extlen_t, len)
1125-
__field(xfs_lsn_t, lsn)
1135+
__field(int, found)
11261136
),
11271137
TP_fast_assign(
11281138
__entry->dev = mp->m_super->s_dev;
11291139
__entry->agno = agno;
11301140
__entry->agbno = agbno;
11311141
__entry->len = len;
1132-
__entry->lsn = lsn;
1142+
__entry->found = found;
11331143
),
1134-
TP_printk("dev %d:%d agno %u agbno %u len %u force lsn 0x%llx",
1144+
TP_printk("dev %d:%d agno %u agbno %u len %u %s",
11351145
MAJOR(__entry->dev), MINOR(__entry->dev),
11361146
__entry->agno,
11371147
__entry->agbno,
11381148
__entry->len,
1149+
__print_symbolic(__entry->found, XFS_BUSY_STATES))
1150+
);
1151+
1152+
TRACE_EVENT(xfs_trans_commit_lsn,
1153+
TP_PROTO(struct xfs_trans *trans),
1154+
TP_ARGS(trans),
1155+
TP_STRUCT__entry(
1156+
__field(dev_t, dev)
1157+
__field(struct xfs_trans *, tp)
1158+
__field(xfs_lsn_t, lsn)
1159+
),
1160+
TP_fast_assign(
1161+
__entry->dev = trans->t_mountp->m_super->s_dev;
1162+
__entry->tp = trans;
1163+
__entry->lsn = trans->t_commit_lsn;
1164+
),
1165+
TP_printk("dev %d:%d trans 0x%p commit_lsn 0x%llx",
1166+
MAJOR(__entry->dev), MINOR(__entry->dev),
1167+
__entry->tp,
11391168
__entry->lsn)
11401169
);
11411170

fs/xfs/quota/xfs_dquot.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,9 @@ xfs_qm_init_dquot_blk(
344344
for (i = 0; i < q->qi_dqperchunk; i++, d++, curid++)
345345
xfs_qm_dqinit_core(curid, type, d);
346346
xfs_trans_dquot_buf(tp, bp,
347-
(type & XFS_DQ_USER ? XFS_BLI_UDQUOT_BUF :
348-
((type & XFS_DQ_PROJ) ? XFS_BLI_PDQUOT_BUF :
349-
XFS_BLI_GDQUOT_BUF)));
347+
(type & XFS_DQ_USER ? XFS_BLF_UDQUOT_BUF :
348+
((type & XFS_DQ_PROJ) ? XFS_BLF_PDQUOT_BUF :
349+
XFS_BLF_GDQUOT_BUF)));
350350
xfs_trans_log_buf(tp, bp, 0, BBTOB(q->qi_dqchunklen) - 1);
351351
}
352352

fs/xfs/xfs_ag.h

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,20 @@ typedef struct xfs_agfl {
175175
} xfs_agfl_t;
176176

177177
/*
178-
* Busy block/extent entry. Used in perag to mark blocks that have been freed
179-
* but whose transactions aren't committed to disk yet.
178+
* Busy block/extent entry. Indexed by a rbtree in perag to mark blocks that
179+
* have been freed but whose transactions aren't committed to disk yet.
180+
*
181+
* Note that we use the transaction ID to record the transaction, not the
182+
* transaction structure itself. See xfs_alloc_busy_insert() for details.
180183
*/
181-
typedef struct xfs_perag_busy {
182-
xfs_agblock_t busy_start;
183-
xfs_extlen_t busy_length;
184-
struct xfs_trans *busy_tp; /* transaction that did the free */
185-
} xfs_perag_busy_t;
184+
struct xfs_busy_extent {
185+
struct rb_node rb_node; /* ag by-bno indexed search tree */
186+
struct list_head list; /* transaction busy extent list */
187+
xfs_agnumber_t agno;
188+
xfs_agblock_t bno;
189+
xfs_extlen_t length;
190+
xlog_tid_t tid; /* transaction that created this */
191+
};
186192

187193
/*
188194
* Per-ag incore structure, copies of information in agf and agi,
@@ -216,7 +222,8 @@ typedef struct xfs_perag {
216222
xfs_agino_t pagl_leftrec;
217223
xfs_agino_t pagl_rightrec;
218224
#ifdef __KERNEL__
219-
spinlock_t pagb_lock; /* lock for pagb_list */
225+
spinlock_t pagb_lock; /* lock for pagb_tree */
226+
struct rb_root pagb_tree; /* ordered tree of busy extents */
220227

221228
atomic_t pagf_fstrms; /* # of filestreams active in this AG */
222229

@@ -226,7 +233,6 @@ typedef struct xfs_perag {
226233
int pag_ici_reclaimable; /* reclaimable inodes */
227234
#endif
228235
int pagb_count; /* pagb slots in use */
229-
xfs_perag_busy_t pagb_list[XFS_PAGB_NUM_SLOTS]; /* unstable blocks */
230236
} xfs_perag_t;
231237

232238
/*

0 commit comments

Comments
 (0)