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