static int do_readahead(journal_t *journal, unsigned int start) { int err; unsigned int max, nbufs, next; unsigned long long blocknr; struct buffer_head *bh; struct buffer_head * bufs[MAXBUF]; /* Do up to 128K of readahead */ max = start + (128 * 1024 / journal->j_blocksize); if (max > journal->j_maxlen) max = journal->j_maxlen; /* Do the readahead itself. We'll submit MAXBUF buffer_heads at * a time to the block device IO layer. */ nbufs = 0; for (next = start; next < max; next++) { err = jbd2_journal_bmap(journal, next, &blocknr); if (err) { printk(KERN_ERR "JBD2: bad block at offset %u\n", next); goto failed; } bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); if (!bh) { err = -ENOMEM; goto failed; } if (!buffer_uptodate(bh) && !buffer_locked(bh)) { bufs[nbufs++] = bh; if (nbufs == MAXBUF) { ll_rw_block(READ, nbufs, bufs); journal_brelse_array(bufs, nbufs); nbufs = 0; } } else brelse(bh); } if (nbufs) ll_rw_block(READ, nbufs, bufs); err = 0; failed: if (nbufs) journal_brelse_array(bufs, nbufs); return err; }
static int jread(struct buffer_head **bhp, journal_t *journal, unsigned int offset) { int err; unsigned long long blocknr; struct buffer_head *bh; *bhp = NULL; if (offset >= journal->j_maxlen) { printk(KERN_ERR "JBD: corrupted journal superblock\n"); return -EIO; } err = jbd2_journal_bmap(journal, offset, &blocknr); if (err) { printk (KERN_ERR "JBD: bad block at offset %u\n", offset); return err; } bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); if (!bh) return -ENOMEM; if(buffer_uptodate(bh)){ if (!trylock_buffer(bh)){ lock_buffer(bh); printk("debug:concurrent exist \n"); } unlock_buffer(bh); } if (!buffer_uptodate(bh)) { /* If this is a brand new buffer, start readahead. Otherwise, we assume we are already reading it. */ if (!buffer_req(bh)) do_readahead(journal, offset); wait_on_buffer(bh); } if (!buffer_uptodate(bh)) { printk (KERN_ERR "JBD: Failed to read block at offset %u\n", offset); brelse(bh); return -EIO; } *bhp = bh; return 0; }
static int jread(struct buffer_head **bhp, journal_t *journal, unsigned int offset) { int err; unsigned long long blocknr; struct buffer_head *bh; *bhp = NULL; if (offset >= journal->j_maxlen) { printk(KERN_ERR "JBD2: corrupted journal superblock\n"); return -EIO; } err = jbd2_journal_bmap(journal, offset, &blocknr); if (err) { printk(KERN_ERR "JBD2: bad block at offset %u\n", offset); return err; } bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); if (!bh) return -ENOMEM; if (!buffer_uptodate(bh)) { if (!buffer_req(bh)) do_readahead(journal, offset); wait_on_buffer(bh); } if (!buffer_uptodate(bh)) { printk(KERN_ERR "JBD2: Failed to read block at offset %u\n", offset); brelse(bh); return -EIO; } *bhp = bh; return 0; }