~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/udf/fsync.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * fsync.c
  3  *
  4  * PURPOSE
  5  *  Fsync handling routines for the OSTA-UDF(tm) filesystem.
  6  *
  7  * CONTACTS
  8  *  E-mail regarding any portion of the Linux UDF file system should be
  9  *  directed to the development team mailing list (run by majordomo):
 10  *      linux_udf@hootie.lvld.hp.com
 11  *
 12  * COPYRIGHT
 13  *  This file is distributed under the terms of the GNU General Public
 14  *  License (GPL). Copies of the GPL can be obtained from:
 15  *      ftp://prep.ai.mit.edu/pub/gnu/GPL
 16  *  Each contributing author retains all rights to their own work.
 17  *
 18  *  (C) 1999-2000 Ben Fennema
 19  *  (C) 1999-2000 Stelias Computing Inc
 20  *
 21  * HISTORY
 22  *
 23  *  05/22/99 blf  Created.
 24  */
 25 
 26 #include "udfdecl.h"
 27 
 28 #include <linux/fs.h>
 29 #include <linux/locks.h>
 30 #include <linux/smp_lock.h>
 31 #include <linux/udf_fs.h>
 32 #include "udf_i.h"
 33 
 34 static int sync_extent_block (struct inode * inode, Uint32 block, int wait)
 35 {
 36         struct buffer_head * bh;
 37         
 38         if (!block)
 39                 return 0;
 40         bh = get_hash_table (inode->i_dev, block, inode->i_sb->s_blocksize);
 41         if (!bh)
 42                 return 0;
 43         if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
 44                 /* There can be a parallell read(2) that started read-I/O
 45                    on the buffer so we can't assume that there's been
 46                    an I/O error without first waiting I/O completation. */
 47                 wait_on_buffer(bh);
 48                 if (!buffer_uptodate(bh))
 49                 {
 50                         brelse (bh);
 51                         return -1;
 52                 }
 53         }
 54         if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
 55                 if (wait)
 56                         /* when we return from fsync all the blocks
 57                            must be _just_ stored on disk */
 58                         wait_on_buffer(bh);
 59                 brelse (bh);
 60                 return 0;
 61         }
 62         ll_rw_block (WRITE, 1, &bh);
 63         atomic_dec(&bh->b_count);
 64         return 0;
 65 }
 66 
 67 static int sync_all_extents(struct inode * inode, int wait)
 68 {
 69         lb_addr bloc, eloc;
 70         Uint32 extoffset, lextoffset, elen, offset, block;
 71         int err = 0, etype;
 72         struct buffer_head *bh = NULL;
 73         
 74         if ((etype = inode_bmap(inode, 0, &bloc, &extoffset, &eloc, &elen, &offset, &bh)) != -1)
 75         {
 76                 block = udf_get_lb_pblock(inode->i_sb, bloc, 0);
 77                 err |= sync_extent_block(inode, block, wait);
 78                 lextoffset = extoffset;
 79 
 80                 while ((etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
 81                 {
 82                         if (lextoffset > extoffset)
 83                         {
 84                                 block = udf_get_lb_pblock(inode->i_sb, bloc, 0);
 85                                 err |= sync_extent_block(inode, block, wait);
 86                         }
 87                         lextoffset = extoffset;
 88                 }
 89         }
 90         udf_release_data(bh);
 91         return err;
 92 }
 93 
 94 /*
 95  *      File may be NULL when we are called. Perhaps we shouldn't
 96  *      even pass file to fsync ?
 97  */
 98 
 99 int udf_sync_file(struct file * file, struct dentry *dentry, int datasync)
100 {
101         int wait, err = 0;
102         struct inode *inode = dentry->d_inode;
103 
104         lock_kernel();
105         if (S_ISLNK(inode->i_mode) && !(inode->i_blocks)) 
106         {
107                 /*
108                  * Don't sync fast links! or ICB_FLAG_AD_IN_ICB
109                  */
110                 goto skip;
111         }
112 
113         err = generic_buffer_fdatasync(inode, 0, ~0UL);
114 
115         for (wait=0; wait<=1; wait++)
116         {
117                 err |= sync_all_extents (inode, wait);
118         }
119 skip:
120         err |= udf_sync_inode (inode);
121         unlock_kernel();
122         return err ? -EIO : 0;
123 }
124 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.