]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/xfs/xfs_log.c
Driver core: accept all valid action-strings in uevent-trigger
[linux-2.6-omap-h63xx.git] / fs / xfs / xfs_log.c
index e730328636c31283c46cd2ce1fac1ccd18c4bf72..9d4c4fbeb3ee2cf4618dd756f2e256760b8f158b 100644 (file)
@@ -617,7 +617,8 @@ xfs_log_unmount_write(xfs_mount_t *mp)
                reg[0].i_len  = sizeof(magic);
                XLOG_VEC_SET_TYPE(&reg[0], XLOG_REG_TYPE_UNMOUNT);
 
-               error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0, 0);
+               error = xfs_log_reserve(mp, 600, 1, &tic,
+                                       XFS_LOG, 0, XLOG_UNMOUNT_REC_TYPE);
                if (!error) {
                        /* remove inited flag */
                        ((xlog_ticket_t *)tic)->t_flags = 0;
@@ -655,8 +656,11 @@ xfs_log_unmount_write(xfs_mount_t *mp)
                } else {
                        LOG_UNLOCK(log, s);
                }
-               if (tic)
+               if (tic) {
+                       xlog_trace_loggrant(log, tic, "unmount rec");
+                       xlog_ungrant_log_space(log, tic);
                        xlog_state_put_ticket(log, tic);
+               }
        } else {
                /*
                 * We're already in forced_shutdown mode, couldn't
@@ -813,10 +817,8 @@ xfs_log_need_covered(xfs_mount_t *mp)
        SPLDECL(s);
        int             needed = 0, gen;
        xlog_t          *log = mp->m_log;
-       bhv_vfs_t       *vfsp = XFS_MTOVFS(mp);
 
-       if (vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) ||
-           (vfsp->vfs_flag & VFS_RDONLY))
+       if (!xfs_fs_writable(mp))
                return 0;
 
        s = LOG_LOCK(log);
@@ -963,14 +965,16 @@ xlog_iodone(xfs_buf_t *bp)
        } else if (iclog->ic_state & XLOG_STATE_IOERROR) {
                aborted = XFS_LI_ABORTED;
        }
+
+       /* log I/O is always issued ASYNC */
+       ASSERT(XFS_BUF_ISASYNC(bp));
        xlog_state_done_syncing(iclog, aborted);
-       if (!(XFS_BUF_ISASYNC(bp))) {
-               /*
-                * Corresponding psema() will be done in bwrite().  If we don't
-                * vsema() here, panic.
-                */
-               XFS_BUF_V_IODONESEMA(bp);
-       }
+       /*
+        * do not reference the buffer (bp) here as we could race
+        * with it being freed after writing the unmount record to the
+        * log.
+        */
+
 }      /* xlog_iodone */
 
 /*
@@ -1195,11 +1199,18 @@ xlog_alloc_log(xfs_mount_t      *mp,
                *iclogp = (xlog_in_core_t *)
                          kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP);
                iclog = *iclogp;
-               iclog->hic_data = (xlog_in_core_2_t *)
-                         kmem_zalloc(iclogsize, KM_SLEEP);
-
                iclog->ic_prev = prev_iclog;
                prev_iclog = iclog;
+
+               bp = xfs_buf_get_noaddr(log->l_iclog_size, mp->m_logdev_targp);
+               if (!XFS_BUF_CPSEMA(bp))
+                       ASSERT(0);
+               XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
+               XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb);
+               XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
+               iclog->ic_bp = bp;
+               iclog->hic_data = bp->b_addr;
+
                log->l_iclog_bak[i] = (xfs_caddr_t)&(iclog->ic_header);
 
                head = &iclog->ic_header;
@@ -1212,11 +1223,6 @@ xlog_alloc_log(xfs_mount_t       *mp,
                INT_SET(head->h_fmt, ARCH_CONVERT, XLOG_FMT);
                memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t));
 
-               bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
-               XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
-               XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb);
-               XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
-               iclog->ic_bp = bp;
 
                iclog->ic_size = XFS_BUF_SIZE(bp) - log->l_iclog_hsize;
                iclog->ic_state = XLOG_STATE_ACTIVE;
@@ -1413,7 +1419,7 @@ xlog_sync(xlog_t          *log,
        ops = iclog->ic_header.h_num_logops;
        INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops);
 
-       bp          = iclog->ic_bp;
+       bp = iclog->ic_bp;
        ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1);
        XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
        XFS_BUF_SET_ADDR(bp, BLOCK_LSN(INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)));
@@ -1428,17 +1434,16 @@ xlog_sync(xlog_t                *log,
        } else {
                iclog->ic_bwritecnt = 1;
        }
-       XFS_BUF_SET_PTR(bp, (xfs_caddr_t) &(iclog->ic_header), count);
+       XFS_BUF_SET_COUNT(bp, count);
        XFS_BUF_SET_FSPRIVATE(bp, iclog);       /* save for later */
+       XFS_BUF_ZEROFLAGS(bp);
        XFS_BUF_BUSY(bp);
        XFS_BUF_ASYNC(bp);
        /*
         * Do an ordered write for the log block.
-        *
-        * It may not be needed to flush the first split block in the log wrap
-        * case, but do it anyways to be safe -AK
+        * Its unnecessary to flush the first split block in the log wrap case.
         */
-       if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
+       if (!split && (log->l_mp->m_flags & XFS_MOUNT_BARRIER))
                XFS_BUF_ORDERED(bp);
 
        ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
@@ -1460,7 +1465,7 @@ xlog_sync(xlog_t          *log,
                return error;
        }
        if (split) {
-               bp              = iclog->ic_log->l_xbuf;
+               bp = iclog->ic_log->l_xbuf;
                ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) ==
                                                        (unsigned long)1);
                XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
@@ -1468,6 +1473,7 @@ xlog_sync(xlog_t          *log,
                XFS_BUF_SET_PTR(bp, (xfs_caddr_t)((__psint_t)&(iclog->ic_header)+
                                            (__psint_t)count), split);
                XFS_BUF_SET_FSPRIVATE(bp, iclog);
+               XFS_BUF_ZEROFLAGS(bp);
                XFS_BUF_BUSY(bp);
                XFS_BUF_ASYNC(bp);
                if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
@@ -1524,7 +1530,6 @@ xlog_dealloc_log(xlog_t *log)
                }
 #endif
                next_iclog = iclog->ic_next;
-               kmem_free(iclog->hic_data, log->l_iclog_size);
                kmem_free(iclog, sizeof(xlog_in_core_t));
                iclog = next_iclog;
        }
@@ -2212,9 +2217,13 @@ xlog_state_do_callback(
 
                        iclog = iclog->ic_next;
                } while (first_iclog != iclog);
-               if (repeats && (repeats % 10) == 0) {
+
+               if (repeats > 5000) {
+                       flushcnt += repeats;
+                       repeats = 0;
                        xfs_fs_cmn_err(CE_WARN, log->l_mp,
-                               "xlog_state_do_callback: looping %d", repeats);
+                               "%s: possible infinite loop (%d iterations)",
+                               __FUNCTION__, flushcnt);
                }
        } while (!ioerrors && loopdidcallbacks);
 
@@ -2246,6 +2255,7 @@ xlog_state_do_callback(
        }
 #endif
 
+       flushcnt = 0;
        if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) {
                flushcnt = log->l_flushcnt;
                log->l_flushcnt = 0;