Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 version 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/mm.h>
 16 #include <linux/pagemap.h>
 17 #include <linux/writeback.h>
 18 #include <linux/swap.h>
 19 #include <linux/delay.h>
 20 #include <linux/bio.h>
 21 #include <linux/gfs2_ondisk.h>
 22 #include <linux/lm_interface.h>
 23 
 24 #include "gfs2.h"
 25 #include "incore.h"
 26 #include "glock.h"
 27 #include "glops.h"
 28 #include "inode.h"
 29 #include "log.h"
 30 #include "lops.h"
 31 #include "meta_io.h"
 32 #include "rgrp.h"
 33 #include "trans.h"
 34 #include "util.h"
 35 #include "ops_address.h"
 36 
 37 static int aspace_get_block(struct inode *inode, sector_t lblock,
 38                             struct buffer_head *bh_result, int create)
 39 {
 40         gfs2_assert_warn(inode->i_sb->s_fs_info, 0);
 41         return -EOPNOTSUPP;
 42 }
 43 
 44 static int gfs2_aspace_writepage(struct page *page,
 45                                  struct writeback_control *wbc)
 46 {
 47         return block_write_full_page(page, aspace_get_block, wbc);
 48 }
 49 
 50 static const struct address_space_operations aspace_aops = {
 51         .writepage = gfs2_aspace_writepage,
 52         .releasepage = gfs2_releasepage,
 53         .sync_page = block_sync_page,
 54 };
 55 
 56 /**
 57  * gfs2_aspace_get - Create and initialize a struct inode structure
 58  * @sdp: the filesystem the aspace is in
 59  *
 60  * Right now a struct inode is just a struct inode.  Maybe Linux
 61  * will supply a more lightweight address space construct (that works)
 62  * in the future.
 63  *
 64  * Make sure pages/buffers in this aspace aren't in high memory.
 65  *
 66  * Returns: the aspace
 67  */
 68 
 69 struct inode *gfs2_aspace_get(struct gfs2_sbd *sdp)
 70 {
 71         struct inode *aspace;
 72 
 73         aspace = new_inode(sdp->sd_vfs);
 74         if (aspace) {
 75                 mapping_set_gfp_mask(aspace->i_mapping, GFP_NOFS);
 76                 aspace->i_mapping->a_ops = &aspace_aops;
 77                 aspace->i_size = ~0ULL;
 78                 aspace->i_private = NULL;
 79                 insert_inode_hash(aspace);
 80         }
 81         return aspace;
 82 }
 83 
 84 void gfs2_aspace_put(struct inode *aspace)
 85 {
 86         remove_inode_hash(aspace);
 87         iput(aspace);
 88 }
 89 
 90 /**
 91  * gfs2_meta_inval - Invalidate all buffers associated with a glock
 92  * @gl: the glock
 93  *
 94  */
 95 
 96 void gfs2_meta_inval(struct gfs2_glock *gl)
 97 {
 98         struct gfs2_sbd *sdp = gl->gl_sbd;
 99         struct inode *aspace = gl->gl_aspace;
100         struct address_space *mapping = gl->gl_aspace->i_mapping;
101 
102         gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count));
103 
104         atomic_inc(&aspace->i_writecount);
105         truncate_inode_pages(mapping, 0);
106         atomic_dec(&aspace->i_writecount);
107 
108         gfs2_assert_withdraw(sdp, !mapping->nrpages);
109 }
110 
111 /**
112  * gfs2_meta_sync - Sync all buffers associated with a glock
113  * @gl: The glock
114  *
115  */
116 
117 void gfs2_meta_sync(struct gfs2_glock *gl)
118 {
119         struct address_space *mapping = gl->gl_aspace->i_mapping;
120         int error;
121 
122         filemap_fdatawrite(mapping);
123         error = filemap_fdatawait(mapping);
124 
125         if (error)
126                 gfs2_io_error(gl->gl_sbd);
127 }
128 
129 /**
130  * getbuf - Get a buffer with a given address space
131  * @gl: the glock
132  * @blkno: the block number (filesystem scope)
133  * @create: 1 if the buffer should be created
134  *
135  * Returns: the buffer
136  */
137 
138 static struct buffer_head *getbuf(struct gfs2_glock *gl, u64 blkno, int create)
139 {
140         struct address_space *mapping = gl->gl_aspace->i_mapping;
141         struct gfs2_sbd *sdp = gl->gl_sbd;
142         struct page *page;
143         struct buffer_head *bh;
144         unsigned int shift;
145         unsigned long index;
146         unsigned int bufnum;
147 
148         shift = PAGE_CACHE_SHIFT - sdp->sd_sb.sb_bsize_shift;
149         index = blkno >> shift;             /* convert block to page */
150         bufnum = blkno - (index << shift);  /* block buf index within page */
151 
152         if (create) {
153                 for (;;) {
154                         page = grab_cache_page(mapping, index);
155                         if (page)
156                                 break;
157                         yield();
158                 }
159         } else {
160                 page = find_lock_page(mapping, index);
161                 if (!page)
162                         return NULL;
163         }
164 
165         if (!page_has_buffers(page))
166                 create_empty_buffers(page, sdp->sd_sb.sb_bsize, 0);
167 
168         /* Locate header for our buffer within our page */
169         for (bh = page_buffers(page); bufnum--; bh = bh->b_this_page)
170                 /* Do nothing */;
171         get_bh(bh);
172 
173         if (!buffer_mapped(bh))
174                 map_bh(bh, sdp->sd_vfs, blkno);
175 
176         unlock_page(page);
177         mark_page_accessed(page);
178         page_cache_release(page);
179 
180         return bh;
181 }
182 
183 static void meta_prep_new(struct buffer_head *bh)
184 {
185         struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data;
186 
187         lock_buffer(bh);
188         clear_buffer_dirty(bh);
189         set_buffer_uptodate(bh);
190         unlock_buffer(bh);
191 
192         mh->mh_magic = cpu_to_be32(GFS2_MAGIC);
193 }
194 
195 /**
196  * gfs2_meta_new - Get a block
197  * @gl: The glock associated with this block
198  * @blkno: The block number
199  *
200  * Returns: The buffer
201  */
202 
203 struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno)
204 {
205         struct buffer_head *bh;
206         bh = getbuf(gl, blkno, CREATE);
207         meta_prep_new(bh);
208         return bh;
209 }
210 
211 /**
212  * gfs2_meta_read - Read a block from disk
213  * @gl: The glock covering the block
214  * @blkno: The block number
215  * @flags: flags
216  * @bhp: the place where the buffer is returned (NULL on failure)
217  *
218  * Returns: errno
219  */
220 
221 int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
222                    struct buffer_head **bhp)
223 {
224         *bhp = getbuf(gl, blkno, CREATE);
225         if (!buffer_uptodate(*bhp)) {
226                 ll_rw_block(READ_META, 1, bhp);
227                 if (flags & DIO_WAIT) {
228                         int error = gfs2_meta_wait(gl->gl_sbd, *bhp);
229                         if (error) {
230                                 brelse(*bhp);
231                                 return error;
232                         }
233                 }
234         }
235 
236         return 0;
237 }
238 
239 /**
240  * gfs2_meta_wait - Reread a block from disk
241  * @sdp: the filesystem
242  * @bh: The block to wait for
243  *
244  * Returns: errno
245  */
246 
247 int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
248 {
249         if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
250                 return -EIO;
251 
252         wait_on_buffer(bh);
253 
254         if (!buffer_uptodate(bh)) {
255                 struct gfs2_trans *tr = current->journal_info;
256                 if (tr && tr->tr_touched)
257                         gfs2_io_error_bh(sdp, bh);
258                 return -EIO;
259         }
260         if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
261                 return -EIO;
262 
263         return 0;
264 }
265 
266 /**
267  * gfs2_attach_bufdata - attach a struct gfs2_bufdata structure to a buffer
268  * @gl: the glock the buffer belongs to
269  * @bh: The buffer to be attached to
270  * @meta: Flag to indicate whether its metadata or not
271  */
272 
273 void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh,
274                          int meta)
275 {
276         struct gfs2_bufdata *bd;
277 
278         if (meta)
279                 lock_page(bh->b_page);
280 
281         if (bh->b_private) {
282                 if (meta)
283                         unlock_page(bh->b_page);
284                 return;
285         }
286 
287         bd = kmem_cache_zalloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL);
288         bd->bd_bh = bh;
289         bd->bd_gl = gl;
290 
291         INIT_LIST_HEAD(&bd->bd_list_tr);
292         if (meta)
293                 lops_init_le(&bd->bd_le, &gfs2_buf_lops);
294         else
295                 lops_init_le(&bd->bd_le, &gfs2_databuf_lops);
296         bh->b_private = bd;
297 
298         if (meta)
299                 unlock_page(bh->b_page);
300 }
301 
302 void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int meta)
303 {
304         struct gfs2_sbd *sdp = GFS2_SB(bh->b_page->mapping->host);
305         struct gfs2_bufdata *bd = bh->b_private;
306         if (test_clear_buffer_pinned(bh)) {
307                 list_del_init(&bd->bd_le.le_list);
308                 if (meta) {
309                         gfs2_assert_warn(sdp, sdp->sd_log_num_buf);
310                         sdp->sd_log_num_buf--;
311                         tr->tr_num_buf_rm++;
312                 } else {
313                         gfs2_assert_warn(sdp, sdp->sd_log_num_databuf);
314                         sdp->sd_log_num_databuf--;
315                         tr->tr_num_databuf_rm++;
316                 }
317                 tr->tr_touched = 1;
318                 brelse(bh);
319         }
320         if (bd) {
321                 if (bd->bd_ail) {
322                         gfs2_remove_from_ail(bd);
323                         bh->b_private = NULL;
324                         bd->bd_bh = NULL;
325                         bd->bd_blkno = bh->b_blocknr;
326                         gfs2_trans_add_revoke(sdp, bd);
327                 }
328         }
329         clear_buffer_dirty(bh);
330         clear_buffer_uptodate(bh);
331 }
332 
333 /**
334  * gfs2_meta_wipe - make inode's buffers so they aren't dirty/pinned anymore
335  * @ip: the inode who owns the buffers
336  * @bstart: the first buffer in the run
337  * @blen: the number of buffers in the run
338  *
339  */
340 
341 void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen)
342 {
343         struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
344         struct buffer_head *bh;
345 
346         while (blen) {
347                 bh = getbuf(ip->i_gl, bstart, NO_CREATE);
348                 if (bh) {
349                         lock_buffer(bh);
350                         gfs2_log_lock(sdp);
351                         gfs2_remove_from_journal(bh, current->journal_info, 1);
352                         gfs2_log_unlock(sdp);
353                         unlock_buffer(bh);
354                         brelse(bh);
355                 }
356 
357                 bstart++;
358                 blen--;
359         }
360 }
361 
362 /**
363  * gfs2_meta_indirect_buffer - Get a metadata buffer
364  * @ip: The GFS2 inode
365  * @height: The level of this buf in the metadata (indir addr) tree (if any)
366  * @num: The block number (device relative) of the buffer
367  * @new: Non-zero if we may create a new buffer
368  * @bhp: the buffer is returned here
369  *
370  * Returns: errno
371  */
372 
373 int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
374                               int new, struct buffer_head **bhp)
375 {
376         struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
377         struct gfs2_glock *gl = ip->i_gl;
378         struct buffer_head *bh;
379         int ret = 0;
380 
381         if (new) {
382                 BUG_ON(height == 0);
383                 bh = gfs2_meta_new(gl, num);
384                 gfs2_trans_add_bh(ip->i_gl, bh, 1);
385                 gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
386                 gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
387         } else {
388                 u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI;
389                 ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh);
390                 if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) {
391                         brelse(bh);
392                         ret = -EIO;
393                 }
394         }
395         *bhp = bh;
396         return ret;
397 }
398 
399 /**
400  * gfs2_meta_ra - start readahead on an extent of a file
401  * @gl: the glock the blocks belong to
402  * @dblock: the starting disk block
403  * @extlen: the number of blocks in the extent
404  *
405  * returns: the first buffer in the extent
406  */
407 
408 struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen)
409 {
410         struct gfs2_sbd *sdp = gl->gl_sbd;
411         struct buffer_head *first_bh, *bh;
412         u32 max_ra = gfs2_tune_get(sdp, gt_max_readahead) >>
413                           sdp->sd_sb.sb_bsize_shift;
414 
415         BUG_ON(!extlen);
416 
417         if (max_ra < 1)
418                 max_ra = 1;
419         if (extlen > max_ra)
420                 extlen = max_ra;
421 
422         first_bh = getbuf(gl, dblock, CREATE);
423 
424         if (buffer_uptodate(first_bh))
425                 goto out;
426         if (!buffer_locked(first_bh))
427                 ll_rw_block(READ_META, 1, &first_bh);
428 
429         dblock++;
430         extlen--;
431 
432         while (extlen) {
433                 bh = getbuf(gl, dblock, CREATE);
434 
435                 if (!buffer_uptodate(bh) && !buffer_locked(bh))
436                         ll_rw_block(READA, 1, &bh);
437                 brelse(bh);
438                 dblock++;
439                 extlen--;
440                 if (!buffer_locked(first_bh) && buffer_uptodate(first_bh))
441                         goto out;
442         }
443 
444         wait_on_buffer(first_bh);
445 out:
446         return first_bh;
447 }
448 
449 
  This page was automatically generated by the LXR engine.