aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-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 {
48}; 48};
49 49
50/** 50/**
51 * gfs2_unstuffer_page - unstuff a stuffed inode into a block cached by a page
52 * @ip: the inode
53 * @dibh: the dinode buffer
54 * @block: the block number that was allocated
55 * @private: any locked page held by the caller process
56 *
57 * Returns: errno
58 */
59
60static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
61 uint64_t block, struct page *page)
62{
63 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
64 struct inode *inode = &ip->i_inode;
65 struct buffer_head *bh;
66 int release = 0;
67
68 if (!page || page->index) {
69 page = grab_cache_page(inode->i_mapping, 0);
70 if (!page)
71 return -ENOMEM;
72 release = 1;
73 }
74
75 if (!PageUptodate(page)) {
76 void *kaddr = kmap(page);
77
78 memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode),
79 ip->i_di.di_size);
80 memset(kaddr + ip->i_di.di_size, 0,
81 PAGE_CACHE_SIZE - ip->i_di.di_size);
82 kunmap(page);
83
84 SetPageUptodate(page);
85 }
86
87 if (!page_has_buffers(page))
88 create_empty_buffers(page, 1 << inode->i_blkbits,
89 (1 << BH_Uptodate));
90
91 bh = page_buffers(page);
92
93 if (!buffer_mapped(bh))
94 map_bh(bh, inode->i_sb, block);
95
96 set_buffer_uptodate(bh);
97 if ((sdp->sd_args.ar_data == GFS2_DATA_ORDERED) || gfs2_is_jdata(ip))
98 gfs2_trans_add_bh(ip->i_gl, bh, 0);
99 mark_buffer_dirty(bh);
100
101 if (release) {
102 unlock_page(page);
103 page_cache_release(page);
104 }
105
106 return 0;
107}
108
109/**
51 * gfs2_unstuff_dinode - Unstuff a dinode when the data has grown too big 110 * gfs2_unstuff_dinode - Unstuff a dinode when the data has grown too big
52 * @ip: The GFS2 inode to unstuff 111 * @ip: The GFS2 inode to unstuff
53 * @unstuffer: the routine that handles unstuffing a non-zero length file 112 * @unstuffer: the routine that handles unstuffing a non-zero length file
@@ -59,8 +118,7 @@ struct strip_mine {
59 * Returns: errno 118 * Returns: errno
60 */ 119 */
61 120
62int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer, 121int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page)
63 void *private)
64{ 122{
65 struct buffer_head *bh, *dibh; 123 struct buffer_head *bh, *dibh;
66 uint64_t block = 0; 124 uint64_t block = 0;
@@ -90,7 +148,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer,
90 } else { 148 } else {
91 block = gfs2_alloc_data(ip); 149 block = gfs2_alloc_data(ip);
92 150
93 error = unstuffer(ip, dibh, block, private); 151 error = gfs2_unstuffer_page(ip, dibh, block, page);
94 if (error) 152 if (error)
95 goto out_brelse; 153 goto out_brelse;
96 } 154 }
@@ -786,8 +844,7 @@ static int do_grow(struct gfs2_inode *ip, uint64_t size)
786 844
787 if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) { 845 if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
788 if (gfs2_is_stuffed(ip)) { 846 if (gfs2_is_stuffed(ip)) {
789 error = gfs2_unstuff_dinode(ip, gfs2_unstuffer_page, 847 error = gfs2_unstuff_dinode(ip, NULL);
790 NULL);
791 if (error) 848 if (error)
792 goto out_end_trans; 849 goto out_end_trans;
793 } 850 }
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 @@
10#ifndef __BMAP_DOT_H__ 10#ifndef __BMAP_DOT_H__
11#define __BMAP_DOT_H__ 11#define __BMAP_DOT_H__
12 12
13typedef int (*gfs2_unstuffer_t) (struct gfs2_inode * ip, 13int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page);
14 struct buffer_head * dibh, uint64_t block,
15 void *private);
16int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer,
17 void *private);
18
19int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary); 14int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary);
20int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen); 15int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen);
21 16
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,
173 return -EINVAL; 173 return -EINVAL;
174 174
175 if (gfs2_is_stuffed(ip)) { 175 if (gfs2_is_stuffed(ip)) {
176 error = gfs2_unstuff_dinode(ip, NULL, NULL); 176 error = gfs2_unstuff_dinode(ip, NULL);
177 if (error) 177 if (error)
178 return error; 178 return error;
179 } 179 }
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,
395 395
396 if (gfs2_is_stuffed(ip)) { 396 if (gfs2_is_stuffed(ip)) {
397 if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) { 397 if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
398 error = gfs2_unstuff_dinode(ip, gfs2_unstuffer_page, 398 error = gfs2_unstuff_dinode(ip, page);
399 page);
400 if (error == 0) 399 if (error == 0)
401 goto prepare_write; 400 goto prepare_write;
402 } else if (!PageUptodate(page)) 401 } 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)
104 goto out_ipres; 104 goto out_ipres;
105 105
106 if (gfs2_is_stuffed(ip)) { 106 if (gfs2_is_stuffed(ip)) {
107 error = gfs2_unstuff_dinode(ip, gfs2_unstuffer_page, NULL); 107 error = gfs2_unstuff_dinode(ip, NULL);
108 if (error) 108 if (error)
109 goto out_trans; 109 goto out_trans;
110 } 110 }
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)
114} 114}
115 115
116/** 116/**
117 * gfs2_unstuffer_page - unstuff a stuffed inode into a block cached by a page
118 * @ip: the inode
119 * @dibh: the dinode buffer
120 * @block: the block number that was allocated
121 * @private: any locked page held by the caller process
122 *
123 * Returns: errno
124 */
125
126int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
127 uint64_t block, void *private)
128{
129 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
130 struct inode *inode = &ip->i_inode;
131 struct page *page = (struct page *)private;
132 struct buffer_head *bh;
133 int release = 0;
134
135 if (!page || page->index) {
136 page = grab_cache_page(inode->i_mapping, 0);
137 if (!page)
138 return -ENOMEM;
139 release = 1;
140 }
141
142 if (!PageUptodate(page)) {
143 void *kaddr = kmap(page);
144
145 memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode),
146 ip->i_di.di_size);
147 memset(kaddr + ip->i_di.di_size, 0,
148 PAGE_CACHE_SIZE - ip->i_di.di_size);
149 kunmap(page);
150
151 SetPageUptodate(page);
152 }
153
154 if (!page_has_buffers(page))
155 create_empty_buffers(page, 1 << inode->i_blkbits,
156 (1 << BH_Uptodate));
157
158 bh = page_buffers(page);
159
160 if (!buffer_mapped(bh))
161 map_bh(bh, inode->i_sb, block);
162
163 set_buffer_uptodate(bh);
164 if ((sdp->sd_args.ar_data == GFS2_DATA_ORDERED) || gfs2_is_jdata(ip))
165 gfs2_trans_add_bh(ip->i_gl, bh, 0);
166 mark_buffer_dirty(bh);
167
168 if (release) {
169 unlock_page(page);
170 page_cache_release(page);
171 }
172
173 return 0;
174}
175
176/**
177 * gfs2_block_truncate_page - Deal with zeroing out data for truncate 117 * gfs2_block_truncate_page - Deal with zeroing out data for truncate
178 * 118 *
179 * This is partly borrowed from ext3. 119 * 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);
14void gfs2_page_inval(struct gfs2_glock *gl); 14void gfs2_page_inval(struct gfs2_glock *gl);
15void gfs2_page_sync(struct gfs2_glock *gl, int flags); 15void gfs2_page_sync(struct gfs2_glock *gl, int flags);
16 16
17int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
18 uint64_t block, void *private);
19int gfs2_block_truncate_page(struct address_space *mapping); 17int gfs2_block_truncate_page(struct address_space *mapping);
20void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, 18void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page,
21 unsigned int from, unsigned int to); 19 unsigned int from, unsigned int to);