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