Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 67733
b: refs/heads/master
c: 6798d35
h: refs/heads/master
i:
  67731: ace65a4
v: v3
  • Loading branch information
Mark Fasheh committed Oct 12, 2007
1 parent bab8910 commit 5c1b4df
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 15b1e36bdb487d67ef924a37b0967453143be53a
refs/heads/master: 6798d35a31c413bbb3f83bbaa844bd2598168ccc
80 changes: 76 additions & 4 deletions trunk/fs/ocfs2/aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,70 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
return err;
}

static int ocfs2_read_inline_data(struct inode *inode, struct page *page,
struct buffer_head *di_bh)
{
void *kaddr;
unsigned int size;
struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;

if (!(le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL)) {
ocfs2_error(inode->i_sb, "Inode %llu lost inline data flag",
(unsigned long long)OCFS2_I(inode)->ip_blkno);
return -EROFS;
}

size = i_size_read(inode);

if (size > PAGE_CACHE_SIZE ||
size > ocfs2_max_inline_data(inode->i_sb)) {
ocfs2_error(inode->i_sb,
"Inode %llu has with inline data has bad size: %u",
(unsigned long long)OCFS2_I(inode)->ip_blkno, size);
return -EROFS;
}

kaddr = kmap_atomic(page, KM_USER0);
if (size)
memcpy(kaddr, di->id2.i_data.id_data, size);
/* Clear the remaining part of the page */
memset(kaddr + size, 0, PAGE_CACHE_SIZE - size);
flush_dcache_page(page);
kunmap_atomic(kaddr, KM_USER0);

SetPageUptodate(page);

return 0;
}

static int ocfs2_readpage_inline(struct inode *inode, struct page *page)
{
int ret;
struct buffer_head *di_bh = NULL;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);

BUG_ON(!PageLocked(page));
BUG_ON(!OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL);

ret = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, &di_bh,
OCFS2_BH_CACHED, inode);
if (ret) {
mlog_errno(ret);
goto out;
}

ret = ocfs2_read_inline_data(inode, page, di_bh);
out:
unlock_page(page);

brelse(di_bh);
return ret;
}

static int ocfs2_readpage(struct file *file, struct page *page)
{
struct inode *inode = page->mapping->host;
struct ocfs2_inode_info *oi = OCFS2_I(inode);
loff_t start = (loff_t)page->index << PAGE_CACHE_SHIFT;
int ret, unlock = 1;

Expand All @@ -222,7 +283,7 @@ static int ocfs2_readpage(struct file *file, struct page *page)
goto out;
}

if (down_read_trylock(&OCFS2_I(inode)->ip_alloc_sem) == 0) {
if (down_read_trylock(&oi->ip_alloc_sem) == 0) {
ret = AOP_TRUNCATED_PAGE;
goto out_meta_unlock;
}
Expand Down Expand Up @@ -252,7 +313,10 @@ static int ocfs2_readpage(struct file *file, struct page *page)
goto out_alloc;
}

ret = block_read_full_page(page, ocfs2_get_block);
if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL)
ret = ocfs2_readpage_inline(inode, page);
else
ret = block_read_full_page(page, ocfs2_get_block);
unlock = 0;

ocfs2_data_unlock(inode, 0);
Expand Down Expand Up @@ -397,7 +461,9 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block)
down_read(&OCFS2_I(inode)->ip_alloc_sem);
}

err = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL, NULL);
if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL))
err = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL,
NULL);

if (!INODE_JOURNAL(inode)) {
up_read(&OCFS2_I(inode)->ip_alloc_sem);
Expand All @@ -411,7 +477,6 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block)
goto bail;
}


bail:
status = err ? 0 : p_blkno;

Expand Down Expand Up @@ -566,6 +631,13 @@ static ssize_t ocfs2_direct_IO(int rw,

mlog_entry_void();

/*
* Fallback to buffered I/O if we see an inode without
* extents.
*/
if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
return 0;

if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) {
/*
* We get PR data locks even for O_DIRECT. This
Expand Down
6 changes: 6 additions & 0 deletions trunk/fs/ocfs2/extent_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,12 @@ int ocfs2_get_clusters(struct inode *inode, u32 v_cluster,
struct ocfs2_extent_rec *rec;
u32 coff;

if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
ret = -ERANGE;
mlog_errno(ret);
goto out;
}

ret = ocfs2_extent_map_lookup(inode, v_cluster, p_cluster,
num_clusters, extent_flags);
if (ret == 0)
Expand Down

0 comments on commit 5c1b4df

Please sign in to comment.