diff options
author | Steven Whitehouse <steve@men-an-tol.chygwyn.com> | 2006-02-15 07:26:19 -0500 |
---|---|---|
committer | Steven Whitehouse <steve@chygwyn.com> | 2006-02-15 07:26:19 -0500 |
commit | 5c4e9e036678fae65c9288e1c00a6f33cd447283 (patch) | |
tree | 656159da5907b1f763ff7d99c56cc368141d3a76 /fs | |
parent | 61a30dcb5866eb7e92796b2988ddb4c94b9f78ac (diff) |
[GFS2] Fix a case where we didn't get unstuffing right
There was a bug in the unstuffing logic which caused a crash
under certain circumstances. This is now fixed.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/gfs2/ops_address.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 39d03f3f2d54..1ccc26426821 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -220,14 +220,14 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) | |||
220 | if (error) | 220 | if (error) |
221 | return error; | 221 | return error; |
222 | 222 | ||
223 | kaddr = kmap(page); | 223 | kaddr = kmap_atomic(page, KM_USER0); |
224 | memcpy((char *)kaddr, | 224 | memcpy((char *)kaddr, |
225 | dibh->b_data + sizeof(struct gfs2_dinode), | 225 | dibh->b_data + sizeof(struct gfs2_dinode), |
226 | ip->i_di.di_size); | 226 | ip->i_di.di_size); |
227 | memset((char *)kaddr + ip->i_di.di_size, | 227 | memset((char *)kaddr + ip->i_di.di_size, |
228 | 0, | 228 | 0, |
229 | PAGE_CACHE_SIZE - ip->i_di.di_size); | 229 | PAGE_CACHE_SIZE - ip->i_di.di_size); |
230 | kunmap(page); | 230 | kunmap_atomic(page, KM_USER0); |
231 | 231 | ||
232 | brelse(dibh); | 232 | brelse(dibh); |
233 | 233 | ||
@@ -240,9 +240,9 @@ static int zero_readpage(struct page *page) | |||
240 | { | 240 | { |
241 | void *kaddr; | 241 | void *kaddr; |
242 | 242 | ||
243 | kaddr = kmap(page); | 243 | kaddr = kmap_atomic(page, KM_USER0); |
244 | memset(kaddr, 0, PAGE_CACHE_SIZE); | 244 | memset(kaddr, 0, PAGE_CACHE_SIZE); |
245 | kunmap(page); | 245 | kunmap_atomic(page, KM_USER0); |
246 | 246 | ||
247 | SetPageUptodate(page); | 247 | SetPageUptodate(page); |
248 | unlock_page(page); | 248 | unlock_page(page); |
@@ -364,14 +364,14 @@ static int gfs2_prepare_write(struct file *file, struct page *page, | |||
364 | if (gfs2_is_stuffed(ip)) { | 364 | if (gfs2_is_stuffed(ip)) { |
365 | if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) { | 365 | if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) { |
366 | error = gfs2_unstuff_dinode(ip, gfs2_unstuffer_page, page); | 366 | error = gfs2_unstuff_dinode(ip, gfs2_unstuffer_page, page); |
367 | if (error) | 367 | if (error == 0) |
368 | goto out; | 368 | goto prepare_write; |
369 | } else if (!PageUptodate(page)) { | 369 | } else if (!PageUptodate(page)) |
370 | error = stuffed_readpage(ip, page); | 370 | error = stuffed_readpage(ip, page); |
371 | goto out; | 371 | goto out; |
372 | } | ||
373 | } | 372 | } |
374 | 373 | ||
374 | prepare_write: | ||
375 | error = block_prepare_write(page, from, to, gfs2_get_block); | 375 | error = block_prepare_write(page, from, to, gfs2_get_block); |
376 | 376 | ||
377 | out: | 377 | out: |