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.
22 #include <asm/uaccess.h>
23 #include <asm/system.h>
24 #include <asm/byteorder.h>
26 #include <linux/errno.h>
28 #include <linux/ext2_fs.h>
29 #include <linux/fcntl.h>
30 #include <linux/sched.h>
31 #include <linux/stat.h>
32 #include <linux/locks.h>
35 #define blocksize (EXT2_BLOCK_SIZE(inode->i_sb))
36 #define addr_per_block (EXT2_ADDR_PER_BLOCK(inode->i_sb))
38 static int sync_indirect(struct inode
* inode
, u32
* block
, int wait
)
40 struct buffer_head
* bh
;
44 bh
= get_hash_table (inode
->i_dev
, le32_to_cpu(*block
), blocksize
);
47 if (wait
&& buffer_req(bh
) && !buffer_uptodate(bh
)) {
51 if (wait
|| !buffer_uptodate(bh
) || !buffer_dirty(bh
)) {
55 ll_rw_block (WRITE
, 1, &bh
);
60 static int sync_iblock (struct inode
* inode
, u32
* iblock
,
61 struct buffer_head
** bh
, int wait
)
66 tmp
= le32_to_cpu(*iblock
);
69 rc
= sync_indirect(inode
, iblock
, wait
);
72 *bh
= bread (inode
->i_dev
, tmp
, blocksize
);
78 static int sync_dindirect (struct inode
* inode
, u32
* diblock
, int wait
)
81 struct buffer_head
* dind_bh
;
84 rc
= sync_iblock (inode
, diblock
, &dind_bh
, wait
);
88 for (i
= 0; i
< addr_per_block
; i
++) {
89 rc
= sync_indirect(inode
,
90 ((u32
*) dind_bh
->b_data
) + i
,
99 static int sync_tindirect (struct inode
* inode
, u32
* tiblock
, int wait
)
102 struct buffer_head
* tind_bh
;
105 rc
= sync_iblock (inode
, tiblock
, &tind_bh
, wait
);
109 for (i
= 0; i
< addr_per_block
; i
++) {
110 rc
= sync_dindirect(inode
,
111 ((u32
*) tind_bh
->b_data
) + i
,
121 * File may be NULL when we are called. Perhaps we shouldn't
122 * even pass file to fsync ?
125 int ext2_sync_file(struct file
* file
, struct dentry
*dentry
)
128 struct inode
*inode
= dentry
->d_inode
;
130 if (S_ISLNK(inode
->i_mode
) && !(inode
->i_blocks
))
132 * Don't sync fast links!
136 err
= generic_buffer_fdatasync(inode
, 0, ~0UL);
138 for (wait
=0; wait
<=1; wait
++)
140 err
|= sync_indirect (inode
,
141 inode
->u
.ext2_i
.i_data
+EXT2_IND_BLOCK
,
143 err
|= sync_dindirect (inode
,
144 inode
->u
.ext2_i
.i_data
+EXT2_DIND_BLOCK
,
146 err
|= sync_tindirect (inode
,
147 inode
->u
.ext2_i
.i_data
+EXT2_TIND_BLOCK
,
151 err
|= ext2_sync_inode (inode
);
152 return err
? -EIO
: 0;