[patch 1/1] gfs2: get_sb_dev() fix
[linux-2.6] / fs / gfs2 / page.c
1 /*
2  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3  * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
4  *
5  * This copyrighted material is made available to anyone wishing to use,
6  * modify, copy, or redistribute it subject to the terms and conditions
7  * of the GNU General Public License v.2.
8  */
9
10 #include <linux/sched.h>
11 #include <linux/slab.h>
12 #include <linux/spinlock.h>
13 #include <linux/completion.h>
14 #include <linux/buffer_head.h>
15 #include <linux/pagemap.h>
16 #include <linux/mm.h>
17 #include <linux/gfs2_ondisk.h>
18
19 #include "gfs2.h"
20 #include "lm_interface.h"
21 #include "incore.h"
22 #include "bmap.h"
23 #include "inode.h"
24 #include "page.h"
25 #include "trans.h"
26 #include "ops_address.h"
27 #include "util.h"
28
29 /**
30  * gfs2_pte_inval - Sync and invalidate all PTEs associated with a glock
31  * @gl: the glock
32  *
33  */
34
35 void gfs2_pte_inval(struct gfs2_glock *gl)
36 {
37         struct gfs2_inode *ip;
38         struct inode *inode;
39
40         ip = gl->gl_object;
41         inode = &ip->i_inode;
42         if (!ip || !S_ISREG(ip->i_di.di_mode))
43                 return;
44
45         if (!test_bit(GIF_PAGED, &ip->i_flags))
46                 return;
47
48         unmap_shared_mapping_range(inode->i_mapping, 0, 0);
49
50         if (test_bit(GIF_SW_PAGED, &ip->i_flags))
51                 set_bit(GLF_DIRTY, &gl->gl_flags);
52
53         clear_bit(GIF_SW_PAGED, &ip->i_flags);
54 }
55
56 /**
57  * gfs2_page_inval - Invalidate all pages associated with a glock
58  * @gl: the glock
59  *
60  */
61
62 void gfs2_page_inval(struct gfs2_glock *gl)
63 {
64         struct gfs2_inode *ip;
65         struct inode *inode;
66
67         ip = gl->gl_object;
68         inode = &ip->i_inode;
69         if (!ip || !S_ISREG(ip->i_di.di_mode))
70                 return;
71
72         truncate_inode_pages(inode->i_mapping, 0);
73         gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !inode->i_mapping->nrpages);
74         clear_bit(GIF_PAGED, &ip->i_flags);
75 }
76
77 /**
78  * gfs2_page_sync - Sync the data pages (not metadata) associated with a glock
79  * @gl: the glock
80  * @flags: DIO_START | DIO_WAIT
81  *
82  * Syncs data (not metadata) for a regular file.
83  * No-op for all other types.
84  */
85
86 void gfs2_page_sync(struct gfs2_glock *gl, int flags)
87 {
88         struct gfs2_inode *ip;
89         struct inode *inode;
90         struct address_space *mapping;
91         int error = 0;
92
93         ip = gl->gl_object;
94         inode = &ip->i_inode;
95         if (!ip || !S_ISREG(ip->i_di.di_mode))
96                 return;
97
98         mapping = inode->i_mapping;
99
100         if (flags & DIO_START)
101                 filemap_fdatawrite(mapping);
102         if (!error && (flags & DIO_WAIT))
103                 error = filemap_fdatawait(mapping);
104
105         /* Put back any errors cleared by filemap_fdatawait()
106            so they can be caught by someone who can pass them
107            up to user space. */
108
109         if (error == -ENOSPC)
110                 set_bit(AS_ENOSPC, &mapping->flags);
111         else if (error)
112                 set_bit(AS_EIO, &mapping->flags);
113
114 }
115
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
126 int 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
178  *
179  * This is partly borrowed from ext3.
180  */
181 int gfs2_block_truncate_page(struct address_space *mapping)
182 {
183         struct inode *inode = mapping->host;
184         struct gfs2_inode *ip = GFS2_I(inode);
185         struct gfs2_sbd *sdp = GFS2_SB(inode);
186         loff_t from = inode->i_size;
187         unsigned long index = from >> PAGE_CACHE_SHIFT;
188         unsigned offset = from & (PAGE_CACHE_SIZE-1);
189         unsigned blocksize, iblock, length, pos;
190         struct buffer_head *bh;
191         struct page *page;
192         void *kaddr;
193         int err;
194
195         page = grab_cache_page(mapping, index);
196         if (!page)
197                 return 0;
198
199         blocksize = inode->i_sb->s_blocksize;
200         length = blocksize - (offset & (blocksize - 1));
201         iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
202
203         if (!page_has_buffers(page))
204                 create_empty_buffers(page, blocksize, 0);
205
206         /* Find the buffer that contains "offset" */
207         bh = page_buffers(page);
208         pos = blocksize;
209         while (offset >= pos) {
210                 bh = bh->b_this_page;
211                 iblock++;
212                 pos += blocksize;
213         }
214
215         err = 0;
216
217         if (!buffer_mapped(bh)) {
218                 gfs2_get_block(inode, iblock, bh, 0);
219                 /* unmapped? It's a hole - nothing to do */
220                 if (!buffer_mapped(bh))
221                         goto unlock;
222         }
223
224         /* Ok, it's mapped. Make sure it's up-to-date */
225         if (PageUptodate(page))
226                 set_buffer_uptodate(bh);
227
228         if (!buffer_uptodate(bh)) {
229                 err = -EIO;
230                 ll_rw_block(READ, 1, &bh);
231                 wait_on_buffer(bh);
232                 /* Uhhuh. Read error. Complain and punt. */
233                 if (!buffer_uptodate(bh))
234                         goto unlock;
235         }
236
237         if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
238                 gfs2_trans_add_bh(ip->i_gl, bh, 0);
239
240         kaddr = kmap_atomic(page, KM_USER0);
241         memset(kaddr + offset, 0, length);
242         flush_dcache_page(page);
243         kunmap_atomic(kaddr, KM_USER0);
244
245 unlock:
246         unlock_page(page);
247         page_cache_release(page);
248         return err;
249 }
250
251 void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page,
252                             unsigned int from, unsigned int to)
253 {
254         struct buffer_head *head = page_buffers(page);
255         unsigned int bsize = head->b_size;
256         struct buffer_head *bh;
257         unsigned int start, end;
258
259         for (bh = head, start = 0;
260              bh != head || !start;
261              bh = bh->b_this_page, start = end) {
262                 end = start + bsize;
263                 if (end <= from || start >= to)
264                         continue;
265                 gfs2_trans_add_bh(ip->i_gl, bh, 0);
266         }
267 }
268