This source file includes following definitions.
- sync_block
- sync_iblock
- sync_direct
- sync_indirect
- sync_dindirect
- sync_tindirect
- ext2_sync_file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include <asm/segment.h>
16 #include <asm/system.h>
17
18 #include <linux/errno.h>
19 #include <linux/fs.h>
20 #include <linux/ext2_fs.h>
21 #include <linux/fcntl.h>
22 #include <linux/sched.h>
23 #include <linux/stat.h>
24 #include <linux/locks.h>
25
26
27 #define blocksize (EXT2_BLOCK_SIZE(inode->i_sb))
28 #define addr_per_block (EXT2_ADDR_PER_BLOCK(inode->i_sb))
29
30 static int sync_block (struct inode * inode, u32 * block, int wait)
31 {
32 struct buffer_head * bh;
33 int tmp;
34
35 if (!*block)
36 return 0;
37 tmp = *block;
38 bh = get_hash_table (inode->i_dev, *block, blocksize);
39 if (!bh)
40 return 0;
41 if (*block != tmp) {
42 brelse (bh);
43 return 1;
44 }
45 if (wait && bh->b_req && !bh->b_uptodate) {
46 brelse (bh);
47 return -1;
48 }
49 if (wait || !bh->b_uptodate || !bh->b_dirt) {
50 brelse (bh);
51 return 0;
52 }
53 ll_rw_block (WRITE, 1, &bh);
54 bh->b_count--;
55 return 0;
56 }
57
58 static int sync_iblock (struct inode * inode, u32 * iblock,
59 struct buffer_head ** bh, int wait)
60 {
61 int rc, tmp;
62
63 *bh = NULL;
64 tmp = *iblock;
65 if (!tmp)
66 return 0;
67 rc = sync_block (inode, iblock, wait);
68 if (rc)
69 return rc;
70 *bh = bread (inode->i_dev, tmp, blocksize);
71 if (tmp != *iblock) {
72 brelse (*bh);
73 *bh = NULL;
74 return 1;
75 }
76 if (!*bh)
77 return -1;
78 return 0;
79 }
80
81
82 static int sync_direct (struct inode * inode, int wait)
83 {
84 int i;
85 int rc, err = 0;
86
87 for (i = 0; i < EXT2_NDIR_BLOCKS; i++) {
88 rc = sync_block (inode, inode->u.ext2_i.i_data + i, wait);
89 if (rc > 0)
90 break;
91 if (rc)
92 err = rc;
93 }
94 return err;
95 }
96
97 static int sync_indirect (struct inode * inode, u32 * iblock, int wait)
98 {
99 int i;
100 struct buffer_head * ind_bh;
101 int rc, err = 0;
102
103 rc = sync_iblock (inode, iblock, &ind_bh, wait);
104 if (rc || !ind_bh)
105 return rc;
106
107 for (i = 0; i < addr_per_block; i++) {
108 rc = sync_block (inode,
109 ((u32 *) ind_bh->b_data) + i,
110 wait);
111 if (rc > 0)
112 break;
113 if (rc)
114 err = rc;
115 }
116 brelse (ind_bh);
117 return err;
118 }
119
120 static int sync_dindirect (struct inode * inode, u32 * diblock, int wait)
121 {
122 int i;
123 struct buffer_head * dind_bh;
124 int rc, err = 0;
125
126 rc = sync_iblock (inode, diblock, &dind_bh, wait);
127 if (rc || !dind_bh)
128 return rc;
129
130 for (i = 0; i < addr_per_block; i++) {
131 rc = sync_indirect (inode,
132 ((u32 *) dind_bh->b_data) + i,
133 wait);
134 if (rc > 0)
135 break;
136 if (rc)
137 err = rc;
138 }
139 brelse (dind_bh);
140 return err;
141 }
142
143 static int sync_tindirect (struct inode * inode, u32 * tiblock, int wait)
144 {
145 int i;
146 struct buffer_head * tind_bh;
147 int rc, err = 0;
148
149 rc = sync_iblock (inode, tiblock, &tind_bh, wait);
150 if (rc || !tind_bh)
151 return rc;
152
153 for (i = 0; i < addr_per_block; i++) {
154 rc = sync_dindirect (inode,
155 ((u32 *) tind_bh->b_data) + i,
156 wait);
157 if (rc > 0)
158 break;
159 if (rc)
160 err = rc;
161 }
162 brelse (tind_bh);
163 return err;
164 }
165
166 int ext2_sync_file (struct inode * inode, struct file * file)
167 {
168 int wait, err = 0;
169
170 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
171 S_ISLNK(inode->i_mode)))
172 return -EINVAL;
173 if (S_ISLNK(inode->i_mode) && !(inode->i_blocks))
174
175
176
177 goto skip;
178
179 for (wait=0; wait<=1; wait++)
180 {
181 err |= sync_direct (inode, wait);
182 err |= sync_indirect (inode,
183 inode->u.ext2_i.i_data+EXT2_IND_BLOCK,
184 wait);
185 err |= sync_dindirect (inode,
186 inode->u.ext2_i.i_data+EXT2_DIND_BLOCK,
187 wait);
188 err |= sync_tindirect (inode,
189 inode->u.ext2_i.i_data+EXT2_TIND_BLOCK,
190 wait);
191 }
192 skip:
193 err |= ext2_sync_inode (inode);
194 return (err < 0) ? -EIO : 0;
195 }