2 * linux/fs/ext2/fsync.c
4 * Copyright (C) 1993 Stephen Tweedie (sct@dcs.ed.ac.uk)
6 * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
7 * Laboratoire MASI - Institut Blaise Pascal
8 * Universite Pierre et Marie Curie (Paris VI)
10 * linux/fs/minix/truncate.c Copyright (C) 1991, 1992 Linus Torvalds
12 * ext2fs fsync primitive
14 * Big-endian to little-endian byte-swapping/bitmaps by
15 * David S. Miller (davem@caip.rutgers.edu), 1995
17 * Removed unnecessary code duplication for little endian machines
18 * and excessive __inline__s.
21 * Major simplications and cleanup - we only need to do the metadata, because
22 * we can depend on generic_block_fdatasync() to sync the data blocks.
26 #include <linux/locks.h>
31 #define blocksize (EXT2_BLOCK_SIZE(inode->i_sb))
32 #define addr_per_block (EXT2_ADDR_PER_BLOCK(inode->i_sb))
34 static int sync_indirect(struct inode
* inode
, u32
* block
, int wait
)
36 struct buffer_head
* bh
;
40 bh
= get_hash_table(inode
->i_dev
, le32_to_cpu(*block
), 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_iblock(struct inode
* inode
, u32
* iblock
,
68 struct buffer_head
** bh
, int wait
)
73 tmp
= le32_to_cpu(*iblock
);
76 rc
= sync_indirect(inode
, iblock
, wait
);
79 *bh
= bread(inode
->i_dev
, tmp
, blocksize
);
85 static int sync_dindirect(struct inode
* inode
, u32
* diblock
, int wait
)
88 struct buffer_head
* dind_bh
;
91 rc
= sync_iblock(inode
, diblock
, &dind_bh
, wait
);
95 for (i
= 0; i
< addr_per_block
; i
++) {
96 rc
= sync_indirect(inode
, ((u32
*) dind_bh
->b_data
) + i
, wait
);
104 static int sync_tindirect(struct inode
* inode
, u32
* tiblock
, int wait
)
107 struct buffer_head
* tind_bh
;
110 rc
= sync_iblock(inode
, tiblock
, &tind_bh
, wait
);
114 for (i
= 0; i
< addr_per_block
; i
++) {
115 rc
= sync_dindirect(inode
, ((u32
*) tind_bh
->b_data
) + i
, wait
);
124 * File may be NULL when we are called. Perhaps we shouldn't
125 * even pass file to fsync ?
128 int ext2_sync_file(struct file
* file
, struct dentry
*dentry
)
131 struct inode
*inode
= dentry
->d_inode
;
133 if (S_ISLNK(inode
->i_mode
) && !(inode
->i_blocks
))
135 * Don't sync fast links!
139 err
= generic_buffer_fdatasync(inode
, 0, ~0UL);
141 for (wait
=0; wait
<=1; wait
++)
143 err
|= sync_indirect(inode
,
144 inode
->u
.ext2_i
.i_data
+EXT2_IND_BLOCK
,
146 err
|= sync_dindirect(inode
,
147 inode
->u
.ext2_i
.i_data
+EXT2_DIND_BLOCK
,
149 err
|= sync_tindirect(inode
,
150 inode
->u
.ext2_i
.i_data
+EXT2_TIND_BLOCK
,
154 err
|= ext2_sync_inode (inode
);
155 return err
? -EIO
: 0;