if (!sbh || block_device_ejected(sb))
                return error;
-       if (buffer_write_io_error(sbh)) {
-               /*
-                * Oh, dear.  A previous attempt to write the
-                * superblock failed.  This could happen because the
-                * USB device was yanked out.  Or it could happen to
-                * be a transient write error and maybe the block will
-                * be remapped.  Nothing we can do but to retry the
-                * write and hope for the best.
-                */
-               ext4_msg(sb, KERN_ERR, "previous I/O error to "
-                      "superblock detected");
-               clear_buffer_write_io_error(sbh);
-               set_buffer_uptodate(sbh);
-       }
        /*
         * If the file system is mounted read-only, don't update the
         * superblock write time.  This avoids updating the superblock
                                &EXT4_SB(sb)->s_freeinodes_counter));
        BUFFER_TRACE(sbh, "marking dirty");
        ext4_superblock_csum_set(sb);
+       lock_buffer(sbh);
+       if (buffer_write_io_error(sbh)) {
+               /*
+                * Oh, dear.  A previous attempt to write the
+                * superblock failed.  This could happen because the
+                * USB device was yanked out.  Or it could happen to
+                * be a transient write error and maybe the block will
+                * be remapped.  Nothing we can do but to retry the
+                * write and hope for the best.
+                */
+               ext4_msg(sb, KERN_ERR, "previous I/O error to "
+                      "superblock detected");
+               clear_buffer_write_io_error(sbh);
+               set_buffer_uptodate(sbh);
+       }
        mark_buffer_dirty(sbh);
+       unlock_buffer(sbh);
        if (sync) {
                error = __sync_dirty_buffer(sbh,
                        test_opt(sb, BARRIER) ? WRITE_FUA : WRITE_SYNC);