# Kernel 2.6.27 - XFS Fix

## ToeiRei

The new kernel is out now and there is a problem with the xfs barrier handling which you might notify by watching your syslog / dmesg. The message is "xlog_iodone: Barriers are no longer supported"

```
Oct  9 07:50:44 pavilion Filesystem "sda9": xlog_iodone: Barriers are no longer supported by device. Disabling barriers
```

Barriers are for ensuring that the data is written in the correct order.

In the new 2.6.27 kernel, barriers are disabled as soon as a log buffer in xlog_iodone does not find the XBF_ORDERED flag. This sounds simple, but leads to problems as this is also the case on a split log write in case of a log wraparound. The disabled barriers can easily lead to directory corruption on unclean shutdowns and some problems with deleting directories.

Patch:

```
Index: 2.6.x-xfs-quilt/fs/xfs/linux-2.6/xfs_buf.c

===================================================================

--- 2.6.x-xfs-quilt.orig/fs/xfs/linux-2.6/xfs_buf.c     2008-09-19 

13:47:36.000000000 +1000

+++ 2.6.x-xfs-quilt/fs/xfs/linux-2.6/xfs_buf.c  2008-10-10 15:07:51.316145158 

+1100

@@ -1001,12 +1001,13 @@ xfs_buf_iodone_work(

         * We can get an EOPNOTSUPP to ordered writes.  Here we clear the

         * ordered flag and reissue them.  Because we can't tell the higher

         * layers directly that they should not issue ordered I/O anymore, they

-        * need to check if the ordered flag was cleared during I/O completion.

+        * need to check if the _XFS_BARRIER_FAILED flag was set during I/O 

completion.

         */

        if ((bp->b_error == EOPNOTSUPP) &&

            (bp->b_flags & (XBF_ORDERED|XBF_ASYNC)) == (XBF_ORDERED|XBF_ASYNC)) 

{

                XB_TRACE(bp, "ordered_retry", bp->b_iodone);

                bp->b_flags &= ~XBF_ORDERED;

+               bp->b_flags |= _XFS_BARRIER_FAILED;

                xfs_buf_iorequest(bp);

        } else if (bp->b_iodone)

                (*(bp->b_iodone))(bp);

Index: 2.6.x-xfs-quilt/fs/xfs/linux-2.6/xfs_buf.h

===================================================================

--- 2.6.x-xfs-quilt.orig/fs/xfs/linux-2.6/xfs_buf.h     2008-09-19 

13:47:36.000000000 +1000

+++ 2.6.x-xfs-quilt/fs/xfs/linux-2.6/xfs_buf.h  2008-10-10 11:54:23.269373217 

+1100

@@ -85,6 +85,14 @@ typedef enum {

         * modifications being lost.

         */

        _XBF_PAGE_LOCKED = (1 << 22),

+

+       /*

+        * If we try a barrier write, but it fails we have to communicate

+        * this to the upper layers.  Unfortunately b_error gets overwritten

+        * when the buffer is re-issued so we have to add another flag to

+        * keep this information.

+        */

+       _XFS_BARRIER_FAILED = (1 << 23),

 } xfs_buf_flags_t;

 

 typedef enum {

Index: 2.6.x-xfs-quilt/fs/xfs/xfs_log.c

===================================================================

--- 2.6.x-xfs-quilt.orig/fs/xfs/xfs_log.c       2008-09-22 11:54:19.000000000 

+1000

+++ 2.6.x-xfs-quilt/fs/xfs/xfs_log.c    2008-10-10 15:09:56.967725107 +1100

@@ -1033,11 +1033,12 @@ xlog_iodone(xfs_buf_t *bp)

        l = iclog->ic_log;

 

        /*

-        * If the ordered flag has been removed by a lower

-        * layer, it means the underlyin device no longer supports

+        * If the _XFS_BARRIER_FAILED flag was set by a lower

+        * layer, it means the underlying device no longer supports

         * barrier I/O. Warn loudly and turn off barriers.

         */

-       if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ISORDERED(bp)) {

+       if (bp->b_flags & _XFS_BARRIER_FAILED) {

+               bp->b_flags &= ~_XFS_BARRIER_FAILED;

                l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER;

                xfs_fs_cmn_err(CE_WARN, l->l_mp,

                                "xlog_iodone: Barriers are no longer supported"
```

Reference: http://oss.sgi.com/archives/xfs/2008-10/msg00183.html

Rei

----------

