summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/bmap.c67
-rw-r--r--fs/gfs2/bmap.h7
-rw-r--r--fs/gfs2/dir.c2
-rw-r--r--fs/gfs2/ops_address.c3
-rw-r--r--fs/gfs2/ops_vm.c2
-rw-r--r--fs/gfs2/page.c60
-rw-r--r--fs/gfs2/page.h2
7 files changed, 66 insertions, 77 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 98fa07c2b710..72b19c5d7807 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -48,6 +48,65 @@ struct strip_mine {
};
/**
+ * gfs2_unstuffer_page - unstuff a stuffed inode into a block cached by a page
+ * @ip: the inode
+ * @dibh: the dinode buffer
+ * @block: the block number that was allocated
+ * @private: any locked page held by the caller process
+ *
+ * Returns: errno
+ */
+
+static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
+ uint64_t block, struct page *page)
+{
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+ struct inode *inode = &ip->i_inode;
+ struct buffer_head *bh;
+ int release = 0;
+
+ if (!page || page->index) {
+ page = grab_cache_page(inode->i_mapping, 0);
+ if (!page)
+ return -ENOMEM;
+ release = 1;
+ }
+
+ if (!PageUptodate(page)) {
+ void *kaddr = kmap(page);
+
+ memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode),
+ ip->i_di.di_size);
+ memset(kaddr + ip->i_di.di_size, 0,
+ PAGE_CACHE_SIZE - ip->i_di.di_size);
+ kunmap(page);
+
+ SetPageUptodate(page);
+ }
+
+ if (!page_has_buffers(page))
+ create_empty_buffers(page, 1 << inode->i_blkbits,
+ (1 << BH_Uptodate));
+
+ bh = page_buffers(page);
+
+ if (!buffer_mapped(bh))
+ map_bh(bh, inode->i_sb, block);
+
+ set_buffer_uptodate(bh);
+ if ((sdp->sd_args.ar_data == GFS2_DATA_ORDERED) || gfs2_is_jdata(ip))
+ gfs2_trans_add_bh(ip->i_gl, bh, 0);
+ mark_buffer_dirty(bh);
+
+ if (release) {
+ unlock_page(page);
+ page_cache_release(page);
+ }
+
+ return 0;
+}
+
+/**
* gfs2_unstuff_dinode - Unstuff a dinode when the data has grown too big
* @ip: The GFS2 inode to unstuff
* @unstuffer: the routine that handles unstuffing a non-zero length file
@@ -59,8 +118,7 @@ struct strip_mine {
* Returns: errno
*/
-int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer,
- void *private)
+int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page)
{
struct buffer_head *bh, *dibh;
uint64_t block = 0;
@@ -90,7 +148,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer,
} else {
block = gfs2_alloc_data(ip);
- error = unstuffer(ip, dibh, block, private);
+ error = gfs2_unstuffer_page(ip, dibh, block, page);
if (error)
goto out_brelse;
}
@@ -786,8 +844,7 @@ static int do_grow(struct gfs2_inode *ip, uint64_t size)
if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
if (gfs2_is_stuffed(ip)) {
- error = gfs2_unstuff_dinode(ip, gfs2_unstuffer_page,
- NULL);
+ error = gfs2_unstuff_dinode(ip, NULL);
if (error)
goto out_end_trans;
}
diff --git a/fs/gfs2/bmap.h b/fs/gfs2/bmap.h
index 06ccb2d808ad..1a265412f7ee 100644
--- a/fs/gfs2/bmap.h
+++ b/fs/gfs2/bmap.h
@@ -10,12 +10,7 @@
#ifndef __BMAP_DOT_H__
#define __BMAP_DOT_H__
-typedef int (*gfs2_unstuffer_t) (struct gfs2_inode * ip,
- struct buffer_head * dibh, uint64_t block,
- void *private);
-int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer,
- void *private);
-
+int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page);
int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary);
int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen);
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index f62223b9e53d..563b99e419b6 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -173,7 +173,7 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
return -EINVAL;
if (gfs2_is_stuffed(ip)) {
- error = gfs2_unstuff_dinode(ip, NULL, NULL);
+ error = gfs2_unstuff_dinode(ip, NULL);
if (error)
return error;
}
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index d33f6aa79731..93e00a8af8cf 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -395,8 +395,7 @@ static int gfs2_prepare_write(struct file *file, struct page *page,
if (gfs2_is_stuffed(ip)) {
if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
- error = gfs2_unstuff_dinode(ip, gfs2_unstuffer_page,
- page);
+ error = gfs2_unstuff_dinode(ip, page);
if (error == 0)
goto prepare_write;
} else if (!PageUptodate(page))
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c
index 08709f19ea98..910722d4c483 100644
--- a/fs/gfs2/ops_vm.c
+++ b/fs/gfs2/ops_vm.c
@@ -104,7 +104,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
goto out_ipres;
if (gfs2_is_stuffed(ip)) {
- error = gfs2_unstuff_dinode(ip, gfs2_unstuffer_page, NULL);
+ error = gfs2_unstuff_dinode(ip, NULL);
if (error)
goto out_trans;
}
diff --git a/fs/gfs2/page.c b/fs/gfs2/page.c
index b93caf294b9f..0d6befed1ae5 100644
--- a/fs/gfs2/page.c
+++ b/fs/gfs2/page.c
@@ -114,66 +114,6 @@ void gfs2_page_sync(struct gfs2_glock *gl, int flags)
}
/**
- * gfs2_unstuffer_page - unstuff a stuffed inode into a block cached by a page
- * @ip: the inode
- * @dibh: the dinode buffer
- * @block: the block number that was allocated
- * @private: any locked page held by the caller process
- *
- * Returns: errno
- */
-
-int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
- uint64_t block, void *private)
-{
- struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
- struct inode *inode = &ip->i_inode;
- struct page *page = (struct page *)private;
- struct buffer_head *bh;
- int release = 0;
-
- if (!page || page->index) {
- page = grab_cache_page(inode->i_mapping, 0);
- if (!page)
- return -ENOMEM;
- release = 1;
- }
-
- if (!PageUptodate(page)) {
- void *kaddr = kmap(page);
-
- memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode),
- ip->i_di.di_size);
- memset(kaddr + ip->i_di.di_size, 0,
- PAGE_CACHE_SIZE - ip->i_di.di_size);
- kunmap(page);
-
- SetPageUptodate(page);
- }
-
- if (!page_has_buffers(page))
- create_empty_buffers(page, 1 << inode->i_blkbits,
- (1 << BH_Uptodate));
-
- bh = page_buffers(page);
-
- if (!buffer_mapped(bh))
- map_bh(bh, inode->i_sb, block);
-
- set_buffer_uptodate(bh);
- if ((sdp->sd_args.ar_data == GFS2_DATA_ORDERED) || gfs2_is_jdata(ip))
- gfs2_trans_add_bh(ip->i_gl, bh, 0);
- mark_buffer_dirty(bh);
-
- if (release) {
- unlock_page(page);
- page_cache_release(page);
- }
-
- return 0;
-}
-
-/**
* gfs2_block_truncate_page - Deal with zeroing out data for truncate
*
* This is partly borrowed from ext3.
diff --git a/fs/gfs2/page.h b/fs/gfs2/page.h
index 2c853a90ac04..67a4f4b79aa6 100644
--- a/fs/gfs2/page.h
+++ b/fs/gfs2/page.h
@@ -14,8 +14,6 @@ void gfs2_pte_inval(struct gfs2_glock *gl);
void gfs2_page_inval(struct gfs2_glock *gl);
void gfs2_page_sync(struct gfs2_glock *gl, int flags);
-int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
- uint64_t block, void *private);
int gfs2_block_truncate_page(struct address_space *mapping);
void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page,
unsigned int from, unsigned int to);