This source file includes following definitions.
- sync_block
- sync_iblock
- sync_direct
- sync_indirect
- sync_dindirect
- sync_tindirect
- ext_sync_file
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <asm/segment.h>
15 #include <asm/system.h>
16
17 #include <linux/errno.h>
18 #include <linux/sched.h>
19 #include <linux/stat.h>
20 #include <linux/fcntl.h>
21 #include <linux/locks.h>
22
23 #include <linux/fs.h>
24 #include <linux/ext_fs.h>
25
26
27 #define blocksize BLOCK_SIZE
28 #define addr_per_block 256
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 {
51 brelse(bh);
52 return 0;
53 }
54 ll_rw_block(WRITE, 1, &bh);
55 bh->b_count--;
56 return 0;
57 }
58
59 static int sync_iblock (struct inode * inode, unsigned long * iblock,
60 struct buffer_head **bh, int wait)
61 {
62 int rc, tmp;
63
64 *bh = NULL;
65 tmp = *iblock;
66 if (!tmp)
67 return 0;
68 rc = sync_block (inode, iblock, wait);
69 if (rc)
70 return rc;
71 *bh = bread(inode->i_dev, tmp, blocksize);
72 if (tmp != *iblock) {
73 brelse(*bh);
74 *bh = NULL;
75 return 1;
76 }
77 if (!*bh)
78 return -1;
79 return 0;
80 }
81
82
83 static int sync_direct(struct inode *inode, int wait)
84 {
85 int i;
86 int rc, err = 0;
87
88 for (i = 0; i < 9; i++) {
89 rc = sync_block (inode, inode->u.ext_i.i_data + i, wait);
90 if (rc > 0)
91 break;
92 if (rc)
93 err = rc;
94 }
95 return err;
96 }
97
98 static int sync_indirect(struct inode *inode, unsigned long *iblock, 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 ext_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 for (wait=0; wait<=1; wait++)
177 {
178 err |= sync_direct(inode, wait);
179 err |= sync_indirect(inode, inode->u.ext_i.i_data+9, wait);
180 err |= sync_dindirect(inode, inode->u.ext_i.i_data+10, wait);
181 err |= sync_tindirect(inode, inode->u.ext_i.i_data+11, wait);
182 }
183 err |= ext_sync_inode (inode);
184 return (err < 0) ? -EIO : 0;
185 }