diff options
-rw-r--r-- | fs/xfs/xfs_log.c | 79 | ||||
-rw-r--r-- | fs/xfs/xfs_log.h | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_log_cil.c | 17 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 15 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.c | 395 |
6 files changed, 26 insertions, 486 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 34817adf4b9e..e2cc3568c299 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -760,38 +760,6 @@ xfs_log_item_init( | |||
760 | INIT_LIST_HEAD(&item->li_cil); | 760 | INIT_LIST_HEAD(&item->li_cil); |
761 | } | 761 | } |
762 | 762 | ||
763 | /* | ||
764 | * Write region vectors to log. The write happens using the space reservation | ||
765 | * of the ticket (tic). It is not a requirement that all writes for a given | ||
766 | * transaction occur with one call to xfs_log_write(). However, it is important | ||
767 | * to note that the transaction reservation code makes an assumption about the | ||
768 | * number of log headers a transaction requires that may be violated if you | ||
769 | * don't pass all the transaction vectors in one call.... | ||
770 | */ | ||
771 | int | ||
772 | xfs_log_write( | ||
773 | struct xfs_mount *mp, | ||
774 | struct xfs_log_iovec reg[], | ||
775 | int nentries, | ||
776 | struct xlog_ticket *tic, | ||
777 | xfs_lsn_t *start_lsn) | ||
778 | { | ||
779 | struct log *log = mp->m_log; | ||
780 | int error; | ||
781 | struct xfs_log_vec vec = { | ||
782 | .lv_niovecs = nentries, | ||
783 | .lv_iovecp = reg, | ||
784 | }; | ||
785 | |||
786 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
787 | return XFS_ERROR(EIO); | ||
788 | |||
789 | error = xlog_write(log, &vec, tic, start_lsn, NULL, 0); | ||
790 | if (error) | ||
791 | xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); | ||
792 | return error; | ||
793 | } | ||
794 | |||
795 | void | 763 | void |
796 | xfs_log_move_tail(xfs_mount_t *mp, | 764 | xfs_log_move_tail(xfs_mount_t *mp, |
797 | xfs_lsn_t tail_lsn) | 765 | xfs_lsn_t tail_lsn) |
@@ -1685,7 +1653,7 @@ xlog_print_tic_res( | |||
1685 | }; | 1653 | }; |
1686 | 1654 | ||
1687 | xfs_warn(mp, | 1655 | xfs_warn(mp, |
1688 | "xfs_log_write: reservation summary:\n" | 1656 | "xlog_write: reservation summary:\n" |
1689 | " trans type = %s (%u)\n" | 1657 | " trans type = %s (%u)\n" |
1690 | " unit res = %d bytes\n" | 1658 | " unit res = %d bytes\n" |
1691 | " current res = %d bytes\n" | 1659 | " current res = %d bytes\n" |
@@ -1714,7 +1682,7 @@ xlog_print_tic_res( | |||
1714 | } | 1682 | } |
1715 | 1683 | ||
1716 | xfs_alert_tag(mp, XFS_PTAG_LOGRES, | 1684 | xfs_alert_tag(mp, XFS_PTAG_LOGRES, |
1717 | "xfs_log_write: reservation ran out. Need to up reservation"); | 1685 | "xlog_write: reservation ran out. Need to up reservation"); |
1718 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | 1686 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
1719 | } | 1687 | } |
1720 | 1688 | ||
@@ -1968,23 +1936,21 @@ xlog_write( | |||
1968 | *start_lsn = 0; | 1936 | *start_lsn = 0; |
1969 | 1937 | ||
1970 | len = xlog_write_calc_vec_length(ticket, log_vector); | 1938 | len = xlog_write_calc_vec_length(ticket, log_vector); |
1971 | if (log->l_cilp) { | ||
1972 | /* | ||
1973 | * Region headers and bytes are already accounted for. | ||
1974 | * We only need to take into account start records and | ||
1975 | * split regions in this function. | ||
1976 | */ | ||
1977 | if (ticket->t_flags & XLOG_TIC_INITED) | ||
1978 | ticket->t_curr_res -= sizeof(xlog_op_header_t); | ||
1979 | 1939 | ||
1980 | /* | 1940 | /* |
1981 | * Commit record headers need to be accounted for. These | 1941 | * Region headers and bytes are already accounted for. |
1982 | * come in as separate writes so are easy to detect. | 1942 | * We only need to take into account start records and |
1983 | */ | 1943 | * split regions in this function. |
1984 | if (flags & (XLOG_COMMIT_TRANS | XLOG_UNMOUNT_TRANS)) | 1944 | */ |
1985 | ticket->t_curr_res -= sizeof(xlog_op_header_t); | 1945 | if (ticket->t_flags & XLOG_TIC_INITED) |
1986 | } else | 1946 | ticket->t_curr_res -= sizeof(xlog_op_header_t); |
1987 | ticket->t_curr_res -= len; | 1947 | |
1948 | /* | ||
1949 | * Commit record headers need to be accounted for. These | ||
1950 | * come in as separate writes so are easy to detect. | ||
1951 | */ | ||
1952 | if (flags & (XLOG_COMMIT_TRANS | XLOG_UNMOUNT_TRANS)) | ||
1953 | ticket->t_curr_res -= sizeof(xlog_op_header_t); | ||
1988 | 1954 | ||
1989 | if (ticket->t_curr_res < 0) | 1955 | if (ticket->t_curr_res < 0) |
1990 | xlog_print_tic_res(log->l_mp, ticket); | 1956 | xlog_print_tic_res(log->l_mp, ticket); |
@@ -2931,8 +2897,7 @@ _xfs_log_force( | |||
2931 | 2897 | ||
2932 | XFS_STATS_INC(xs_log_force); | 2898 | XFS_STATS_INC(xs_log_force); |
2933 | 2899 | ||
2934 | if (log->l_cilp) | 2900 | xlog_cil_force(log); |
2935 | xlog_cil_force(log); | ||
2936 | 2901 | ||
2937 | spin_lock(&log->l_icloglock); | 2902 | spin_lock(&log->l_icloglock); |
2938 | 2903 | ||
@@ -3081,11 +3046,9 @@ _xfs_log_force_lsn( | |||
3081 | 3046 | ||
3082 | XFS_STATS_INC(xs_log_force); | 3047 | XFS_STATS_INC(xs_log_force); |
3083 | 3048 | ||
3084 | if (log->l_cilp) { | 3049 | lsn = xlog_cil_force_lsn(log, lsn); |
3085 | lsn = xlog_cil_force_lsn(log, lsn); | 3050 | if (lsn == NULLCOMMITLSN) |
3086 | if (lsn == NULLCOMMITLSN) | 3051 | return 0; |
3087 | return 0; | ||
3088 | } | ||
3089 | 3052 | ||
3090 | try_again: | 3053 | try_again: |
3091 | spin_lock(&log->l_icloglock); | 3054 | spin_lock(&log->l_icloglock); |
@@ -3653,7 +3616,7 @@ xfs_log_force_umount( | |||
3653 | * completed transactions are flushed to disk with the xfs_log_force() | 3616 | * completed transactions are flushed to disk with the xfs_log_force() |
3654 | * call below. | 3617 | * call below. |
3655 | */ | 3618 | */ |
3656 | if (!logerror && (mp->m_flags & XFS_MOUNT_DELAYLOG)) | 3619 | if (!logerror) |
3657 | xlog_cil_force(log); | 3620 | xlog_cil_force(log); |
3658 | 3621 | ||
3659 | /* | 3622 | /* |
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index 3f7bf451c034..23e6ae18fb41 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h | |||
@@ -174,11 +174,6 @@ int xfs_log_reserve(struct xfs_mount *mp, | |||
174 | __uint8_t clientid, | 174 | __uint8_t clientid, |
175 | uint flags, | 175 | uint flags, |
176 | uint t_type); | 176 | uint t_type); |
177 | int xfs_log_write(struct xfs_mount *mp, | ||
178 | xfs_log_iovec_t region[], | ||
179 | int nentries, | ||
180 | struct xlog_ticket *ticket, | ||
181 | xfs_lsn_t *start_lsn); | ||
182 | int xfs_log_unmount_write(struct xfs_mount *mp); | 177 | int xfs_log_unmount_write(struct xfs_mount *mp); |
183 | void xfs_log_unmount(struct xfs_mount *mp); | 178 | void xfs_log_unmount(struct xfs_mount *mp); |
184 | int xfs_log_force_umount(struct xfs_mount *mp, int logerror); | 179 | int xfs_log_force_umount(struct xfs_mount *mp, int logerror); |
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index c7755d5a5fbe..eb207a92e1b1 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
@@ -32,10 +32,7 @@ | |||
32 | #include "xfs_discard.h" | 32 | #include "xfs_discard.h" |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Perform initial CIL structure initialisation. If the CIL is not | 35 | * Perform initial CIL structure initialisation. |
36 | * enabled in this filesystem, ensure the log->l_cilp is null so | ||
37 | * we can check this conditional to determine if we are doing delayed | ||
38 | * logging or not. | ||
39 | */ | 36 | */ |
40 | int | 37 | int |
41 | xlog_cil_init( | 38 | xlog_cil_init( |
@@ -44,10 +41,6 @@ xlog_cil_init( | |||
44 | struct xfs_cil *cil; | 41 | struct xfs_cil *cil; |
45 | struct xfs_cil_ctx *ctx; | 42 | struct xfs_cil_ctx *ctx; |
46 | 43 | ||
47 | log->l_cilp = NULL; | ||
48 | if (!(log->l_mp->m_flags & XFS_MOUNT_DELAYLOG)) | ||
49 | return 0; | ||
50 | |||
51 | cil = kmem_zalloc(sizeof(*cil), KM_SLEEP|KM_MAYFAIL); | 44 | cil = kmem_zalloc(sizeof(*cil), KM_SLEEP|KM_MAYFAIL); |
52 | if (!cil) | 45 | if (!cil) |
53 | return ENOMEM; | 46 | return ENOMEM; |
@@ -80,9 +73,6 @@ void | |||
80 | xlog_cil_destroy( | 73 | xlog_cil_destroy( |
81 | struct log *log) | 74 | struct log *log) |
82 | { | 75 | { |
83 | if (!log->l_cilp) | ||
84 | return; | ||
85 | |||
86 | if (log->l_cilp->xc_ctx) { | 76 | if (log->l_cilp->xc_ctx) { |
87 | if (log->l_cilp->xc_ctx->ticket) | 77 | if (log->l_cilp->xc_ctx->ticket) |
88 | xfs_log_ticket_put(log->l_cilp->xc_ctx->ticket); | 78 | xfs_log_ticket_put(log->l_cilp->xc_ctx->ticket); |
@@ -137,9 +127,6 @@ void | |||
137 | xlog_cil_init_post_recovery( | 127 | xlog_cil_init_post_recovery( |
138 | struct log *log) | 128 | struct log *log) |
139 | { | 129 | { |
140 | if (!log->l_cilp) | ||
141 | return; | ||
142 | |||
143 | log->l_cilp->xc_ctx->ticket = xlog_cil_ticket_alloc(log); | 130 | log->l_cilp->xc_ctx->ticket = xlog_cil_ticket_alloc(log); |
144 | log->l_cilp->xc_ctx->sequence = 1; | 131 | log->l_cilp->xc_ctx->sequence = 1; |
145 | log->l_cilp->xc_ctx->commit_lsn = xlog_assign_lsn(log->l_curr_cycle, | 132 | log->l_cilp->xc_ctx->commit_lsn = xlog_assign_lsn(log->l_curr_cycle, |
@@ -786,8 +773,6 @@ xfs_log_item_in_current_chkpt( | |||
786 | { | 773 | { |
787 | struct xfs_cil_ctx *ctx; | 774 | struct xfs_cil_ctx *ctx; |
788 | 775 | ||
789 | if (!(lip->li_mountp->m_flags & XFS_MOUNT_DELAYLOG)) | ||
790 | return false; | ||
791 | if (list_empty(&lip->li_cil)) | 776 | if (list_empty(&lip->li_cil)) |
792 | return false; | 777 | return false; |
793 | 778 | ||
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index bb24dac42a25..19f69e232509 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -219,7 +219,6 @@ typedef struct xfs_mount { | |||
219 | #define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops | 219 | #define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops |
220 | must be synchronous except | 220 | must be synchronous except |
221 | for space allocations */ | 221 | for space allocations */ |
222 | #define XFS_MOUNT_DELAYLOG (1ULL << 1) /* delayed logging is enabled */ | ||
223 | #define XFS_MOUNT_WAS_CLEAN (1ULL << 3) | 222 | #define XFS_MOUNT_WAS_CLEAN (1ULL << 3) |
224 | #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem | 223 | #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem |
225 | operations, typically for | 224 | operations, typically for |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 3eca58f51ae9..0e76348d958a 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -199,7 +199,6 @@ xfs_parseargs( | |||
199 | mp->m_flags |= XFS_MOUNT_BARRIER; | 199 | mp->m_flags |= XFS_MOUNT_BARRIER; |
200 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; | 200 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; |
201 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; | 201 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
202 | mp->m_flags |= XFS_MOUNT_DELAYLOG; | ||
203 | 202 | ||
204 | /* | 203 | /* |
205 | * These can be overridden by the mount option parsing. | 204 | * These can be overridden by the mount option parsing. |
@@ -353,11 +352,11 @@ xfs_parseargs( | |||
353 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); | 352 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); |
354 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; | 353 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; |
355 | } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) { | 354 | } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) { |
356 | mp->m_flags |= XFS_MOUNT_DELAYLOG; | 355 | xfs_warn(mp, |
356 | "delaylog is the default now, option is deprecated."); | ||
357 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { | 357 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { |
358 | mp->m_flags &= ~XFS_MOUNT_DELAYLOG; | ||
359 | xfs_warn(mp, | 358 | xfs_warn(mp, |
360 | "nodelaylog is deprecated and will be removed in Linux 3.3"); | 359 | "nodelaylog support has been removed, option is deprecated."); |
361 | } else if (!strcmp(this_char, MNTOPT_DISCARD)) { | 360 | } else if (!strcmp(this_char, MNTOPT_DISCARD)) { |
362 | mp->m_flags |= XFS_MOUNT_DISCARD; | 361 | mp->m_flags |= XFS_MOUNT_DISCARD; |
363 | } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { | 362 | } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { |
@@ -395,13 +394,6 @@ xfs_parseargs( | |||
395 | return EINVAL; | 394 | return EINVAL; |
396 | } | 395 | } |
397 | 396 | ||
398 | if ((mp->m_flags & XFS_MOUNT_DISCARD) && | ||
399 | !(mp->m_flags & XFS_MOUNT_DELAYLOG)) { | ||
400 | xfs_warn(mp, | ||
401 | "the discard option is incompatible with the nodelaylog option"); | ||
402 | return EINVAL; | ||
403 | } | ||
404 | |||
405 | #ifndef CONFIG_XFS_QUOTA | 397 | #ifndef CONFIG_XFS_QUOTA |
406 | if (XFS_IS_QUOTA_RUNNING(mp)) { | 398 | if (XFS_IS_QUOTA_RUNNING(mp)) { |
407 | xfs_warn(mp, "quota support not available in this kernel."); | 399 | xfs_warn(mp, "quota support not available in this kernel."); |
@@ -501,7 +493,6 @@ xfs_showargs( | |||
501 | { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 }, | 493 | { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 }, |
502 | { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, | 494 | { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, |
503 | { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, | 495 | { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, |
504 | { XFS_MOUNT_DELAYLOG, "," MNTOPT_DELAYLOG }, | ||
505 | { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, | 496 | { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, |
506 | { 0, NULL } | 497 | { 0, NULL } |
507 | }; | 498 | }; |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 1f35b2feca97..d511332ec841 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -1210,219 +1210,6 @@ xfs_trans_free_items( | |||
1210 | } | 1210 | } |
1211 | } | 1211 | } |
1212 | 1212 | ||
1213 | /* | ||
1214 | * Unlock the items associated with a transaction. | ||
1215 | * | ||
1216 | * Items which were not logged should be freed. Those which were logged must | ||
1217 | * still be tracked so they can be unpinned when the transaction commits. | ||
1218 | */ | ||
1219 | STATIC void | ||
1220 | xfs_trans_unlock_items( | ||
1221 | struct xfs_trans *tp, | ||
1222 | xfs_lsn_t commit_lsn) | ||
1223 | { | ||
1224 | struct xfs_log_item_desc *lidp, *next; | ||
1225 | |||
1226 | list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) { | ||
1227 | struct xfs_log_item *lip = lidp->lid_item; | ||
1228 | |||
1229 | lip->li_desc = NULL; | ||
1230 | |||
1231 | if (commit_lsn != NULLCOMMITLSN) | ||
1232 | IOP_COMMITTING(lip, commit_lsn); | ||
1233 | IOP_UNLOCK(lip); | ||
1234 | |||
1235 | /* | ||
1236 | * Free the descriptor if the item is not dirty | ||
1237 | * within this transaction. | ||
1238 | */ | ||
1239 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) | ||
1240 | xfs_trans_free_item_desc(lidp); | ||
1241 | } | ||
1242 | } | ||
1243 | |||
1244 | /* | ||
1245 | * Total up the number of log iovecs needed to commit this | ||
1246 | * transaction. The transaction itself needs one for the | ||
1247 | * transaction header. Ask each dirty item in turn how many | ||
1248 | * it needs to get the total. | ||
1249 | */ | ||
1250 | static uint | ||
1251 | xfs_trans_count_vecs( | ||
1252 | struct xfs_trans *tp) | ||
1253 | { | ||
1254 | int nvecs; | ||
1255 | struct xfs_log_item_desc *lidp; | ||
1256 | |||
1257 | nvecs = 1; | ||
1258 | |||
1259 | /* In the non-debug case we need to start bailing out if we | ||
1260 | * didn't find a log_item here, return zero and let trans_commit | ||
1261 | * deal with it. | ||
1262 | */ | ||
1263 | if (list_empty(&tp->t_items)) { | ||
1264 | ASSERT(0); | ||
1265 | return 0; | ||
1266 | } | ||
1267 | |||
1268 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { | ||
1269 | /* | ||
1270 | * Skip items which aren't dirty in this transaction. | ||
1271 | */ | ||
1272 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) | ||
1273 | continue; | ||
1274 | lidp->lid_size = IOP_SIZE(lidp->lid_item); | ||
1275 | nvecs += lidp->lid_size; | ||
1276 | } | ||
1277 | |||
1278 | return nvecs; | ||
1279 | } | ||
1280 | |||
1281 | /* | ||
1282 | * Fill in the vector with pointers to data to be logged | ||
1283 | * by this transaction. The transaction header takes | ||
1284 | * the first vector, and then each dirty item takes the | ||
1285 | * number of vectors it indicated it needed in xfs_trans_count_vecs(). | ||
1286 | * | ||
1287 | * As each item fills in the entries it needs, also pin the item | ||
1288 | * so that it cannot be flushed out until the log write completes. | ||
1289 | */ | ||
1290 | static void | ||
1291 | xfs_trans_fill_vecs( | ||
1292 | struct xfs_trans *tp, | ||
1293 | struct xfs_log_iovec *log_vector) | ||
1294 | { | ||
1295 | struct xfs_log_item_desc *lidp; | ||
1296 | struct xfs_log_iovec *vecp; | ||
1297 | uint nitems; | ||
1298 | |||
1299 | /* | ||
1300 | * Skip over the entry for the transaction header, we'll | ||
1301 | * fill that in at the end. | ||
1302 | */ | ||
1303 | vecp = log_vector + 1; | ||
1304 | |||
1305 | nitems = 0; | ||
1306 | ASSERT(!list_empty(&tp->t_items)); | ||
1307 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { | ||
1308 | /* Skip items which aren't dirty in this transaction. */ | ||
1309 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) | ||
1310 | continue; | ||
1311 | |||
1312 | /* | ||
1313 | * The item may be marked dirty but not log anything. This can | ||
1314 | * be used to get called when a transaction is committed. | ||
1315 | */ | ||
1316 | if (lidp->lid_size) | ||
1317 | nitems++; | ||
1318 | IOP_FORMAT(lidp->lid_item, vecp); | ||
1319 | vecp += lidp->lid_size; | ||
1320 | IOP_PIN(lidp->lid_item); | ||
1321 | } | ||
1322 | |||
1323 | /* | ||
1324 | * Now that we've counted the number of items in this transaction, fill | ||
1325 | * in the transaction header. Note that the transaction header does not | ||
1326 | * have a log item. | ||
1327 | */ | ||
1328 | tp->t_header.th_magic = XFS_TRANS_HEADER_MAGIC; | ||
1329 | tp->t_header.th_type = tp->t_type; | ||
1330 | tp->t_header.th_num_items = nitems; | ||
1331 | log_vector->i_addr = (xfs_caddr_t)&tp->t_header; | ||
1332 | log_vector->i_len = sizeof(xfs_trans_header_t); | ||
1333 | log_vector->i_type = XLOG_REG_TYPE_TRANSHDR; | ||
1334 | } | ||
1335 | |||
1336 | /* | ||
1337 | * The committed item processing consists of calling the committed routine of | ||
1338 | * each logged item, updating the item's position in the AIL if necessary, and | ||
1339 | * unpinning each item. If the committed routine returns -1, then do nothing | ||
1340 | * further with the item because it may have been freed. | ||
1341 | * | ||
1342 | * Since items are unlocked when they are copied to the incore log, it is | ||
1343 | * possible for two transactions to be completing and manipulating the same | ||
1344 | * item simultaneously. The AIL lock will protect the lsn field of each item. | ||
1345 | * The value of this field can never go backwards. | ||
1346 | * | ||
1347 | * We unpin the items after repositioning them in the AIL, because otherwise | ||
1348 | * they could be immediately flushed and we'd have to race with the flusher | ||
1349 | * trying to pull the item from the AIL as we add it. | ||
1350 | */ | ||
1351 | static void | ||
1352 | xfs_trans_item_committed( | ||
1353 | struct xfs_log_item *lip, | ||
1354 | xfs_lsn_t commit_lsn, | ||
1355 | int aborted) | ||
1356 | { | ||
1357 | xfs_lsn_t item_lsn; | ||
1358 | struct xfs_ail *ailp; | ||
1359 | |||
1360 | if (aborted) | ||
1361 | lip->li_flags |= XFS_LI_ABORTED; | ||
1362 | item_lsn = IOP_COMMITTED(lip, commit_lsn); | ||
1363 | |||
1364 | /* item_lsn of -1 means the item needs no further processing */ | ||
1365 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) | ||
1366 | return; | ||
1367 | |||
1368 | /* | ||
1369 | * If the returned lsn is greater than what it contained before, update | ||
1370 | * the location of the item in the AIL. If it is not, then do nothing. | ||
1371 | * Items can never move backwards in the AIL. | ||
1372 | * | ||
1373 | * While the new lsn should usually be greater, it is possible that a | ||
1374 | * later transaction completing simultaneously with an earlier one | ||
1375 | * using the same item could complete first with a higher lsn. This | ||
1376 | * would cause the earlier transaction to fail the test below. | ||
1377 | */ | ||
1378 | ailp = lip->li_ailp; | ||
1379 | spin_lock(&ailp->xa_lock); | ||
1380 | if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) { | ||
1381 | /* | ||
1382 | * This will set the item's lsn to item_lsn and update the | ||
1383 | * position of the item in the AIL. | ||
1384 | * | ||
1385 | * xfs_trans_ail_update() drops the AIL lock. | ||
1386 | */ | ||
1387 | xfs_trans_ail_update(ailp, lip, item_lsn); | ||
1388 | } else { | ||
1389 | spin_unlock(&ailp->xa_lock); | ||
1390 | } | ||
1391 | |||
1392 | /* | ||
1393 | * Now that we've repositioned the item in the AIL, unpin it so it can | ||
1394 | * be flushed. Pass information about buffer stale state down from the | ||
1395 | * log item flags, if anyone else stales the buffer we do not want to | ||
1396 | * pay any attention to it. | ||
1397 | */ | ||
1398 | IOP_UNPIN(lip, 0); | ||
1399 | } | ||
1400 | |||
1401 | /* | ||
1402 | * This is typically called by the LM when a transaction has been fully | ||
1403 | * committed to disk. It needs to unpin the items which have | ||
1404 | * been logged by the transaction and update their positions | ||
1405 | * in the AIL if necessary. | ||
1406 | * | ||
1407 | * This also gets called when the transactions didn't get written out | ||
1408 | * because of an I/O error. Abortflag & XFS_LI_ABORTED is set then. | ||
1409 | */ | ||
1410 | STATIC void | ||
1411 | xfs_trans_committed( | ||
1412 | void *arg, | ||
1413 | int abortflag) | ||
1414 | { | ||
1415 | struct xfs_trans *tp = arg; | ||
1416 | struct xfs_log_item_desc *lidp, *next; | ||
1417 | |||
1418 | list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) { | ||
1419 | xfs_trans_item_committed(lidp->lid_item, tp->t_lsn, abortflag); | ||
1420 | xfs_trans_free_item_desc(lidp); | ||
1421 | } | ||
1422 | |||
1423 | xfs_trans_free(tp); | ||
1424 | } | ||
1425 | |||
1426 | static inline void | 1213 | static inline void |
1427 | xfs_log_item_batch_insert( | 1214 | xfs_log_item_batch_insert( |
1428 | struct xfs_ail *ailp, | 1215 | struct xfs_ail *ailp, |
@@ -1538,182 +1325,6 @@ xfs_trans_committed_bulk( | |||
1538 | } | 1325 | } |
1539 | 1326 | ||
1540 | /* | 1327 | /* |
1541 | * Called from the trans_commit code when we notice that the filesystem is in | ||
1542 | * the middle of a forced shutdown. | ||
1543 | * | ||
1544 | * When we are called here, we have already pinned all the items in the | ||
1545 | * transaction. However, neither IOP_COMMITTING or IOP_UNLOCK has been called | ||
1546 | * so we can simply walk the items in the transaction, unpin them with an abort | ||
1547 | * flag and then free the items. Note that unpinning the items can result in | ||
1548 | * them being freed immediately, so we need to use a safe list traversal method | ||
1549 | * here. | ||
1550 | */ | ||
1551 | STATIC void | ||
1552 | xfs_trans_uncommit( | ||
1553 | struct xfs_trans *tp, | ||
1554 | uint flags) | ||
1555 | { | ||
1556 | struct xfs_log_item_desc *lidp, *n; | ||
1557 | |||
1558 | list_for_each_entry_safe(lidp, n, &tp->t_items, lid_trans) { | ||
1559 | if (lidp->lid_flags & XFS_LID_DIRTY) | ||
1560 | IOP_UNPIN(lidp->lid_item, 1); | ||
1561 | } | ||
1562 | |||
1563 | xfs_trans_unreserve_and_mod_sb(tp); | ||
1564 | xfs_trans_unreserve_and_mod_dquots(tp); | ||
1565 | |||
1566 | xfs_trans_free_items(tp, NULLCOMMITLSN, flags); | ||
1567 | xfs_trans_free(tp); | ||
1568 | } | ||
1569 | |||
1570 | /* | ||
1571 | * Format the transaction direct to the iclog. This isolates the physical | ||
1572 | * transaction commit operation from the logical operation and hence allows | ||
1573 | * other methods to be introduced without affecting the existing commit path. | ||
1574 | */ | ||
1575 | static int | ||
1576 | xfs_trans_commit_iclog( | ||
1577 | struct xfs_mount *mp, | ||
1578 | struct xfs_trans *tp, | ||
1579 | xfs_lsn_t *commit_lsn, | ||
1580 | int flags) | ||
1581 | { | ||
1582 | int shutdown; | ||
1583 | int error; | ||
1584 | int log_flags = 0; | ||
1585 | struct xlog_in_core *commit_iclog; | ||
1586 | #define XFS_TRANS_LOGVEC_COUNT 16 | ||
1587 | struct xfs_log_iovec log_vector_fast[XFS_TRANS_LOGVEC_COUNT]; | ||
1588 | struct xfs_log_iovec *log_vector; | ||
1589 | uint nvec; | ||
1590 | |||
1591 | |||
1592 | /* | ||
1593 | * Ask each log item how many log_vector entries it will | ||
1594 | * need so we can figure out how many to allocate. | ||
1595 | * Try to avoid the kmem_alloc() call in the common case | ||
1596 | * by using a vector from the stack when it fits. | ||
1597 | */ | ||
1598 | nvec = xfs_trans_count_vecs(tp); | ||
1599 | if (nvec == 0) { | ||
1600 | return ENOMEM; /* triggers a shutdown! */ | ||
1601 | } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) { | ||
1602 | log_vector = log_vector_fast; | ||
1603 | } else { | ||
1604 | log_vector = (xfs_log_iovec_t *)kmem_alloc(nvec * | ||
1605 | sizeof(xfs_log_iovec_t), | ||
1606 | KM_SLEEP); | ||
1607 | } | ||
1608 | |||
1609 | /* | ||
1610 | * Fill in the log_vector and pin the logged items, and | ||
1611 | * then write the transaction to the log. | ||
1612 | */ | ||
1613 | xfs_trans_fill_vecs(tp, log_vector); | ||
1614 | |||
1615 | if (flags & XFS_TRANS_RELEASE_LOG_RES) | ||
1616 | log_flags = XFS_LOG_REL_PERM_RESERV; | ||
1617 | |||
1618 | error = xfs_log_write(mp, log_vector, nvec, tp->t_ticket, &(tp->t_lsn)); | ||
1619 | |||
1620 | /* | ||
1621 | * The transaction is committed incore here, and can go out to disk | ||
1622 | * at any time after this call. However, all the items associated | ||
1623 | * with the transaction are still locked and pinned in memory. | ||
1624 | */ | ||
1625 | *commit_lsn = xfs_log_done(mp, tp->t_ticket, &commit_iclog, log_flags); | ||
1626 | |||
1627 | tp->t_commit_lsn = *commit_lsn; | ||
1628 | trace_xfs_trans_commit_lsn(tp); | ||
1629 | |||
1630 | if (nvec > XFS_TRANS_LOGVEC_COUNT) | ||
1631 | kmem_free(log_vector); | ||
1632 | |||
1633 | /* | ||
1634 | * If we got a log write error. Unpin the logitems that we | ||
1635 | * had pinned, clean up, free trans structure, and return error. | ||
1636 | */ | ||
1637 | if (error || *commit_lsn == -1) { | ||
1638 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); | ||
1639 | xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT); | ||
1640 | return XFS_ERROR(EIO); | ||
1641 | } | ||
1642 | |||
1643 | /* | ||
1644 | * Once the transaction has committed, unused | ||
1645 | * reservations need to be released and changes to | ||
1646 | * the superblock need to be reflected in the in-core | ||
1647 | * version. Do that now. | ||
1648 | */ | ||
1649 | xfs_trans_unreserve_and_mod_sb(tp); | ||
1650 | |||
1651 | /* | ||
1652 | * Tell the LM to call the transaction completion routine | ||
1653 | * when the log write with LSN commit_lsn completes (e.g. | ||
1654 | * when the transaction commit really hits the on-disk log). | ||
1655 | * After this call we cannot reference tp, because the call | ||
1656 | * can happen at any time and the call will free the transaction | ||
1657 | * structure pointed to by tp. The only case where we call | ||
1658 | * the completion routine (xfs_trans_committed) directly is | ||
1659 | * if the log is turned off on a debug kernel or we're | ||
1660 | * running in simulation mode (the log is explicitly turned | ||
1661 | * off). | ||
1662 | */ | ||
1663 | tp->t_logcb.cb_func = xfs_trans_committed; | ||
1664 | tp->t_logcb.cb_arg = tp; | ||
1665 | |||
1666 | /* | ||
1667 | * We need to pass the iclog buffer which was used for the | ||
1668 | * transaction commit record into this function, and attach | ||
1669 | * the callback to it. The callback must be attached before | ||
1670 | * the items are unlocked to avoid racing with other threads | ||
1671 | * waiting for an item to unlock. | ||
1672 | */ | ||
1673 | shutdown = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb)); | ||
1674 | |||
1675 | /* | ||
1676 | * Mark this thread as no longer being in a transaction | ||
1677 | */ | ||
1678 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); | ||
1679 | |||
1680 | /* | ||
1681 | * Once all the items of the transaction have been copied | ||
1682 | * to the in core log and the callback is attached, the | ||
1683 | * items can be unlocked. | ||
1684 | * | ||
1685 | * This will free descriptors pointing to items which were | ||
1686 | * not logged since there is nothing more to do with them. | ||
1687 | * For items which were logged, we will keep pointers to them | ||
1688 | * so they can be unpinned after the transaction commits to disk. | ||
1689 | * This will also stamp each modified meta-data item with | ||
1690 | * the commit lsn of this transaction for dependency tracking | ||
1691 | * purposes. | ||
1692 | */ | ||
1693 | xfs_trans_unlock_items(tp, *commit_lsn); | ||
1694 | |||
1695 | /* | ||
1696 | * If we detected a log error earlier, finish committing | ||
1697 | * the transaction now (unpin log items, etc). | ||
1698 | * | ||
1699 | * Order is critical here, to avoid using the transaction | ||
1700 | * pointer after its been freed (by xfs_trans_committed | ||
1701 | * either here now, or as a callback). We cannot do this | ||
1702 | * step inside xfs_log_notify as was done earlier because | ||
1703 | * of this issue. | ||
1704 | */ | ||
1705 | if (shutdown) | ||
1706 | xfs_trans_committed(tp, XFS_LI_ABORTED); | ||
1707 | |||
1708 | /* | ||
1709 | * Now that the xfs_trans_committed callback has been attached, | ||
1710 | * and the items are released we can finally allow the iclog to | ||
1711 | * go to disk. | ||
1712 | */ | ||
1713 | return xfs_log_release_iclog(mp, commit_iclog); | ||
1714 | } | ||
1715 | |||
1716 | /* | ||
1717 | * Walk the log items and allocate log vector structures for | 1328 | * Walk the log items and allocate log vector structures for |
1718 | * each item large enough to fit all the vectors they require. | 1329 | * each item large enough to fit all the vectors they require. |
1719 | * Note that this format differs from the old log vector format in | 1330 | * Note that this format differs from the old log vector format in |
@@ -1845,11 +1456,7 @@ xfs_trans_commit( | |||
1845 | xfs_trans_apply_sb_deltas(tp); | 1456 | xfs_trans_apply_sb_deltas(tp); |
1846 | xfs_trans_apply_dquot_deltas(tp); | 1457 | xfs_trans_apply_dquot_deltas(tp); |
1847 | 1458 | ||
1848 | if (mp->m_flags & XFS_MOUNT_DELAYLOG) | 1459 | error = xfs_trans_commit_cil(mp, tp, &commit_lsn, flags); |
1849 | error = xfs_trans_commit_cil(mp, tp, &commit_lsn, flags); | ||
1850 | else | ||
1851 | error = xfs_trans_commit_iclog(mp, tp, &commit_lsn, flags); | ||
1852 | |||
1853 | if (error == ENOMEM) { | 1460 | if (error == ENOMEM) { |
1854 | xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); | 1461 | xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); |
1855 | error = XFS_ERROR(EIO); | 1462 | error = XFS_ERROR(EIO); |