5 * Fsync handling routines for the OSTA-UDF(tm) filesystem.
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
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.
18 * (C) 1999-2000 Ben Fennema
19 * (C) 1999-2000 Stelias Computing Inc
23 * 05/22/99 blf Created.
29 #include <linux/locks.h>
30 #include <linux/smp_lock.h>
31 #include <linux/udf_fs.h>
34 static int sync_extent_block (struct inode
* inode
, Uint32 block
, int wait
)
36 struct buffer_head
* bh
;
40 bh
= get_hash_table (inode
->i_dev
, block
, inode
->i_sb
->s_blocksize
);
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. */
48 if (!buffer_uptodate(bh
))
54 if (wait
|| !buffer_uptodate(bh
) || !buffer_dirty(bh
)) {
56 /* when we return from fsync all the blocks
57 must be _just_ stored on disk */
62 ll_rw_block (WRITE
, 1, &bh
);
63 atomic_dec(&bh
->b_count
);
67 static int sync_all_extents(struct inode
* inode
, int wait
)
70 Uint32 extoffset
, lextoffset
, elen
, offset
, block
;
72 struct buffer_head
*bh
= NULL
;
74 if ((etype
= inode_bmap(inode
, 0, &bloc
, &extoffset
, &eloc
, &elen
, &offset
, &bh
)) != -1)
76 block
= udf_get_lb_pblock(inode
->i_sb
, bloc
, 0);
77 err
|= sync_extent_block(inode
, block
, wait
);
78 lextoffset
= extoffset
;
80 while ((etype
= udf_next_aext(inode
, &bloc
, &extoffset
, &eloc
, &elen
, &bh
, 1)) != -1)
82 if (lextoffset
> extoffset
)
84 block
= udf_get_lb_pblock(inode
->i_sb
, bloc
, 0);
85 err
|= sync_extent_block(inode
, block
, wait
);
87 lextoffset
= extoffset
;
95 * File may be NULL when we are called. Perhaps we shouldn't
96 * even pass file to fsync ?
99 int udf_sync_file(struct file
* file
, struct dentry
*dentry
, int datasync
)
102 struct inode
*inode
= dentry
->d_inode
;
105 if (S_ISLNK(inode
->i_mode
) && !(inode
->i_blocks
))
108 * Don't sync fast links! or ICB_FLAG_AD_IN_ICB
113 err
= generic_buffer_fdatasync(inode
, 0, ~0UL);
115 for (wait
=0; wait
<=1; wait
++)
117 err
|= sync_all_extents (inode
, wait
);
120 err
|= udf_sync_inode (inode
);
122 return err
? -EIO
: 0;