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, unsigned long * 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, unsigned long * 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, unsigned long * iblock,
98 int wait)
99 {
100 int i;
101 struct buffer_head * ind_bh;
102 int rc, err = 0;
103
104 rc = sync_iblock (inode, iblock, &ind_bh, wait);
105 if (rc || !ind_bh)
106 return rc;
107
108 for (i = 0; i < addr_per_block; i++) {
109 rc = sync_block (inode,
110 ((unsigned long *) ind_bh->b_data) + i,
111 wait);
112 if (rc > 0)
113 break;
114 if (rc)
115 err = rc;
116 }
117 brelse (ind_bh);
118 return err;
119 }
120
121 static int sync_dindirect (struct inode * inode, unsigned long * diblock,
122 int wait)
123 {
124 int i;
125 struct buffer_head * dind_bh;
126 int rc, err = 0;
127
128 rc = sync_iblock (inode, diblock, &dind_bh, wait);
129 if (rc || !dind_bh)
130 return rc;
131
132 for (i = 0; i < addr_per_block; i++) {
133 rc = sync_indirect (inode,
134 ((unsigned long *) dind_bh->b_data) + i,
135 wait);
136 if (rc > 0)
137 break;
138 if (rc)
139 err = rc;
140 }
141 brelse (dind_bh);
142 return err;
143 }
144
145 static int sync_tindirect (struct inode * inode, unsigned long * tiblock,
146 int wait)
147 {
148 int i;
149 struct buffer_head * tind_bh;
150 int rc, err = 0;
151
152 rc = sync_iblock (inode, tiblock, &tind_bh, wait);
153 if (rc || !tind_bh)
154 return rc;
155
156 for (i = 0; i < addr_per_block; i++) {
157 rc = sync_dindirect (inode,
158 ((unsigned long *) tind_bh->b_data) + i,
159 wait);
160 if (rc > 0)
161 break;
162 if (rc)
163 err = rc;
164 }
165 brelse (tind_bh);
166 return err;
167 }
168
169 int ext2_sync_file (struct inode * inode, struct file * file)
170 {
171 int wait, err = 0;
172
173 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
174 S_ISLNK(inode->i_mode)))
175 return -EINVAL;
176 if (S_ISLNK(inode->i_mode) && !(inode->i_blocks))
177
178
179
180 goto skip;
181
182 for (wait=0; wait<=1; wait++)
183 {
184 err |= sync_direct (inode, wait);
185 err |= sync_indirect (inode,
186 inode->u.ext2_i.i_data+EXT2_IND_BLOCK,
187 wait);
188 err |= sync_dindirect (inode,
189 inode->u.ext2_i.i_data+EXT2_DIND_BLOCK,
190 wait);
191 err |= sync_tindirect (inode,
192 inode->u.ext2_i.i_data+EXT2_TIND_BLOCK,
193 wait);
194 }
195 skip:
196 err |= ext2_sync_inode (inode);
197 return (err < 0) ? -EIO : 0;
198 }