linux/fs/ocfs2/buffer_head_io.c
<<
>>
Prefs
   1/* -*- mode: c; c-basic-offset: 8; -*-
   2 * vim: noexpandtab sw=8 ts=8 sts=0:
   3 *
   4 * io.c
   5 *
   6 * Buffer cache handling
   7 *
   8 * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
   9 *
  10 * This program is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU General Public
  12 * License as published by the Free Software Foundation; either
  13 * version 2 of the License, or (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18 * General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public
  21 * License along with this program; if not, write to the
  22 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  23 * Boston, MA 021110-1307, USA.
  24 */
  25
  26#include <linux/fs.h>
  27#include <linux/types.h>
  28#include <linux/slab.h>
  29#include <linux/highmem.h>
  30
  31#include <cluster/masklog.h>
  32
  33#include "ocfs2.h"
  34
  35#include "alloc.h"
  36#include "inode.h"
  37#include "journal.h"
  38#include "uptodate.h"
  39
  40#include "buffer_head_io.h"
  41
  42int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
  43                      struct inode *inode)
  44{
  45        int ret = 0;
  46
  47        mlog_entry("(bh->b_blocknr = %llu, inode=%p)\n",
  48                   (unsigned long long)bh->b_blocknr, inode);
  49
  50        BUG_ON(bh->b_blocknr < OCFS2_SUPER_BLOCK_BLKNO);
  51        BUG_ON(buffer_jbd(bh));
  52
  53        /* No need to check for a soft readonly file system here. non
  54         * journalled writes are only ever done on system files which
  55         * can get modified during recovery even if read-only. */
  56        if (ocfs2_is_hard_readonly(osb)) {
  57                ret = -EROFS;
  58                goto out;
  59        }
  60
  61        mutex_lock(&OCFS2_I(inode)->ip_io_mutex);
  62
  63        lock_buffer(bh);
  64        set_buffer_uptodate(bh);
  65
  66        /* remove from dirty list before I/O. */
  67        clear_buffer_dirty(bh);
  68
  69        get_bh(bh); /* for end_buffer_write_sync() */                   
  70        bh->b_end_io = end_buffer_write_sync;
  71        submit_bh(WRITE, bh);
  72
  73        wait_on_buffer(bh);
  74
  75        if (buffer_uptodate(bh)) {
  76                ocfs2_set_buffer_uptodate(inode, bh);
  77        } else {
  78                /* We don't need to remove the clustered uptodate
  79                 * information for this bh as it's not marked locally
  80                 * uptodate. */
  81                ret = -EIO;
  82                put_bh(bh);
  83        }
  84
  85        mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
  86out:
  87        mlog_exit(ret);
  88        return ret;
  89}
  90
  91int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
  92                      struct buffer_head *bhs[], int flags,
  93                      struct inode *inode)
  94{
  95        int status = 0;
  96        struct super_block *sb;
  97        int i, ignore_cache = 0;
  98        struct buffer_head *bh;
  99
 100        mlog_entry("(block=(%llu), nr=(%d), flags=%d, inode=%p)\n",
 101                   (unsigned long long)block, nr, flags, inode);
 102
 103        BUG_ON((flags & OCFS2_BH_READAHEAD) &&
 104               (!inode || !(flags & OCFS2_BH_CACHED)));
 105
 106        if (osb == NULL || osb->sb == NULL || bhs == NULL) {
 107                status = -EINVAL;
 108                mlog_errno(status);
 109                goto bail;
 110        }
 111
 112        if (nr < 0) {
 113                mlog(ML_ERROR, "asked to read %d blocks!\n", nr);
 114                status = -EINVAL;
 115                mlog_errno(status);
 116                goto bail;
 117        }
 118
 119        if (nr == 0) {
 120                mlog(ML_BH_IO, "No buffers will be read!\n");
 121                status = 0;
 122                goto bail;
 123        }
 124
 125        sb = osb->sb;
 126
 127        if (flags & OCFS2_BH_CACHED && !inode)
 128                flags &= ~OCFS2_BH_CACHED;
 129
 130        if (inode)
 131                mutex_lock(&OCFS2_I(inode)->ip_io_mutex);
 132        for (i = 0 ; i < nr ; i++) {
 133                if (bhs[i] == NULL) {
 134                        bhs[i] = sb_getblk(sb, block++);
 135                        if (bhs[i] == NULL) {
 136                                if (inode)
 137                                        mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
 138                                status = -EIO;
 139                                mlog_errno(status);
 140                                goto bail;
 141                        }
 142                }
 143                bh = bhs[i];
 144                ignore_cache = 0;
 145
 146                /* There are three read-ahead cases here which we need to
 147                 * be concerned with. All three assume a buffer has
 148                 * previously been submitted with OCFS2_BH_READAHEAD
 149                 * and it hasn't yet completed I/O.
 150                 *
 151                 * 1) The current request is sync to disk. This rarely
 152                 *    happens these days, and never when performance
 153                 *    matters - the code can just wait on the buffer
 154                 *    lock and re-submit.
 155                 *
 156                 * 2) The current request is cached, but not
 157                 *    readahead. ocfs2_buffer_uptodate() will return
 158                 *    false anyway, so we'll wind up waiting on the
 159                 *    buffer lock to do I/O. We re-check the request
 160                 *    with after getting the lock to avoid a re-submit.
 161                 *
 162                 * 3) The current request is readahead (and so must
 163                 *    also be a caching one). We short circuit if the
 164                 *    buffer is locked (under I/O) and if it's in the
 165                 *    uptodate cache. The re-check from #2 catches the
 166                 *    case that the previous read-ahead completes just
 167                 *    before our is-it-in-flight check.
 168                 */
 169
 170                if (flags & OCFS2_BH_CACHED &&
 171                    !ocfs2_buffer_uptodate(inode, bh)) {
 172                        mlog(ML_UPTODATE,
 173                             "bh (%llu), inode %llu not uptodate\n",
 174                             (unsigned long long)bh->b_blocknr,
 175                             (unsigned long long)OCFS2_I(inode)->ip_blkno);
 176                        ignore_cache = 1;
 177                }
 178
 179                /* XXX: Can we ever get this and *not* have the cached
 180                 * flag set? */
 181                if (buffer_jbd(bh)) {
 182                        if (!(flags & OCFS2_BH_CACHED) || ignore_cache)
 183                                mlog(ML_BH_IO, "trying to sync read a jbd "
 184                                               "managed bh (blocknr = %llu)\n",
 185                                     (unsigned long long)bh->b_blocknr);
 186                        continue;
 187                }
 188
 189                if (!(flags & OCFS2_BH_CACHED) || ignore_cache) {
 190                        if (buffer_dirty(bh)) {
 191                                /* This should probably be a BUG, or
 192                                 * at least return an error. */
 193                                mlog(ML_BH_IO, "asking me to sync read a dirty "
 194                                               "buffer! (blocknr = %llu)\n",
 195                                     (unsigned long long)bh->b_blocknr);
 196                                continue;
 197                        }
 198
 199                        /* A read-ahead request was made - if the
 200                         * buffer is already under read-ahead from a
 201                         * previously submitted request than we are
 202                         * done here. */
 203                        if ((flags & OCFS2_BH_READAHEAD)
 204                            && ocfs2_buffer_read_ahead(inode, bh))
 205                                continue;
 206
 207                        lock_buffer(bh);
 208                        if (buffer_jbd(bh)) {
 209#ifdef CATCH_BH_JBD_RACES
 210                                mlog(ML_ERROR, "block %llu had the JBD bit set "
 211                                               "while I was in lock_buffer!",
 212                                     (unsigned long long)bh->b_blocknr);
 213                                BUG();
 214#else
 215                                unlock_buffer(bh);
 216                                continue;
 217#endif
 218                        }
 219
 220                        /* Re-check ocfs2_buffer_uptodate() as a
 221                         * previously read-ahead buffer may have
 222                         * completed I/O while we were waiting for the
 223                         * buffer lock. */
 224                        if ((flags & OCFS2_BH_CACHED)
 225                            && !(flags & OCFS2_BH_READAHEAD)
 226                            && ocfs2_buffer_uptodate(inode, bh)) {
 227                                unlock_buffer(bh);
 228                                continue;
 229                        }
 230
 231                        clear_buffer_uptodate(bh);
 232                        get_bh(bh); /* for end_buffer_read_sync() */
 233                        bh->b_end_io = end_buffer_read_sync;
 234                        submit_bh(READ, bh);
 235                        continue;
 236                }
 237        }
 238
 239        status = 0;
 240
 241        for (i = (nr - 1); i >= 0; i--) {
 242                bh = bhs[i];
 243
 244                if (!(flags & OCFS2_BH_READAHEAD)) {
 245                        /* We know this can't have changed as we hold the
 246                         * inode sem. Avoid doing any work on the bh if the
 247                         * journal has it. */
 248                        if (!buffer_jbd(bh))
 249                                wait_on_buffer(bh);
 250
 251                        if (!buffer_uptodate(bh)) {
 252                                /* Status won't be cleared from here on out,
 253                                 * so we can safely record this and loop back
 254                                 * to cleanup the other buffers. Don't need to
 255                                 * remove the clustered uptodate information
 256                                 * for this bh as it's not marked locally
 257                                 * uptodate. */
 258                                status = -EIO;
 259                                put_bh(bh);
 260                                bhs[i] = NULL;
 261                                continue;
 262                        }
 263                }
 264
 265                /* Always set the buffer in the cache, even if it was
 266                 * a forced read, or read-ahead which hasn't yet
 267                 * completed. */
 268                if (inode)
 269                        ocfs2_set_buffer_uptodate(inode, bh);
 270        }
 271        if (inode)
 272                mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
 273
 274        mlog(ML_BH_IO, "block=(%llu), nr=(%d), cached=%s, flags=0x%x\n", 
 275             (unsigned long long)block, nr,
 276             (!(flags & OCFS2_BH_CACHED) || ignore_cache) ? "no" : "yes", flags);
 277
 278bail:
 279
 280        mlog_exit(status);
 281        return status;
 282}
 283
 284/* Check whether the blkno is the super block or one of the backups. */
 285static void ocfs2_check_super_or_backup(struct super_block *sb,
 286                                        sector_t blkno)
 287{
 288        int i;
 289        u64 backup_blkno;
 290
 291        if (blkno == OCFS2_SUPER_BLOCK_BLKNO)
 292                return;
 293
 294        for (i = 0; i < OCFS2_MAX_BACKUP_SUPERBLOCKS; i++) {
 295                backup_blkno = ocfs2_backup_super_blkno(sb, i);
 296                if (backup_blkno == blkno)
 297                        return;
 298        }
 299
 300        BUG();
 301}
 302
 303/*
 304 * Write super block and backups doesn't need to collaborate with journal,
 305 * so we don't need to lock ip_io_mutex and inode doesn't need to bea passed
 306 * into this function.
 307 */
 308int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
 309                                struct buffer_head *bh)
 310{
 311        int ret = 0;
 312
 313        mlog_entry_void();
 314
 315        BUG_ON(buffer_jbd(bh));
 316        ocfs2_check_super_or_backup(osb->sb, bh->b_blocknr);
 317
 318        if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) {
 319                ret = -EROFS;
 320                goto out;
 321        }
 322
 323        lock_buffer(bh);
 324        set_buffer_uptodate(bh);
 325
 326        /* remove from dirty list before I/O. */
 327        clear_buffer_dirty(bh);
 328
 329        get_bh(bh); /* for end_buffer_write_sync() */
 330        bh->b_end_io = end_buffer_write_sync;
 331        submit_bh(WRITE, bh);
 332
 333        wait_on_buffer(bh);
 334
 335        if (!buffer_uptodate(bh)) {
 336                ret = -EIO;
 337                put_bh(bh);
 338        }
 339
 340out:
 341        mlog_exit(ret);
 342        return ret;
 343}
 344
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.