|
@@ -82,6 +82,49 @@ static int ocfs2_do_extend_dir(struct super_block *sb,
|
|
struct ocfs2_alloc_context *meta_ac,
|
|
struct ocfs2_alloc_context *meta_ac,
|
|
struct buffer_head **new_bh);
|
|
struct buffer_head **new_bh);
|
|
|
|
|
|
|
|
+static struct buffer_head *ocfs2_bread(struct inode *inode,
|
|
|
|
+ int block, int *err, int reada)
|
|
|
|
+{
|
|
|
|
+ struct buffer_head *bh = NULL;
|
|
|
|
+ int tmperr;
|
|
|
|
+ u64 p_blkno;
|
|
|
|
+ int readflags = OCFS2_BH_CACHED;
|
|
|
|
+
|
|
|
|
+ if (reada)
|
|
|
|
+ readflags |= OCFS2_BH_READAHEAD;
|
|
|
|
+
|
|
|
|
+ if (((u64)block << inode->i_sb->s_blocksize_bits) >=
|
|
|
|
+ i_size_read(inode)) {
|
|
|
|
+ BUG_ON(!reada);
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ down_read(&OCFS2_I(inode)->ip_alloc_sem);
|
|
|
|
+ tmperr = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL,
|
|
|
|
+ NULL);
|
|
|
|
+ up_read(&OCFS2_I(inode)->ip_alloc_sem);
|
|
|
|
+ if (tmperr < 0) {
|
|
|
|
+ mlog_errno(tmperr);
|
|
|
|
+ goto fail;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ tmperr = ocfs2_read_blocks(inode, p_blkno, 1, &bh, readflags);
|
|
|
|
+ if (tmperr < 0)
|
|
|
|
+ goto fail;
|
|
|
|
+
|
|
|
|
+ tmperr = 0;
|
|
|
|
+
|
|
|
|
+ *err = 0;
|
|
|
|
+ return bh;
|
|
|
|
+
|
|
|
|
+fail:
|
|
|
|
+ brelse(bh);
|
|
|
|
+ bh = NULL;
|
|
|
|
+
|
|
|
|
+ *err = -EIO;
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* bh passed here can be an inode block or a dir data block, depending
|
|
* bh passed here can be an inode block or a dir data block, depending
|
|
* on the inode inline data flag.
|
|
* on the inode inline data flag.
|