This source file includes following definitions.
- sync_block
- sync_iblock
- sync_direct
- sync_indirect
- sync_dindirect
- minix_sync_file
1
2
3
4
5
6
7
8
9
10
11 #include <asm/segment.h>
12 #include <asm/system.h>
13
14 #include <linux/errno.h>
15 #include <linux/sched.h>
16 #include <linux/stat.h>
17 #include <linux/fcntl.h>
18 #include <linux/locks.h>
19
20 #include <linux/fs.h>
21 #include <linux/minix_fs.h>
22
23
24 #define blocksize BLOCK_SIZE
25 #define addr_per_block 512
26
27 static int sync_block (struct inode * inode, unsigned short * block, int wait)
28 {
29 struct buffer_head * bh;
30 unsigned short tmp;
31
32 if (!*block)
33 return 0;
34 tmp = *block;
35 bh = get_hash_table(inode->i_dev, *block, blocksize);
36 if (!bh)
37 return 0;
38 if (*block != tmp) {
39 brelse (bh);
40 return 1;
41 }
42 if (wait && bh->b_req && !bh->b_uptodate) {
43 brelse(bh);
44 return -1;
45 }
46 if (wait || !bh->b_uptodate || !bh->b_dirt)
47 {
48 brelse(bh);
49 return 0;
50 }
51 ll_rw_block(WRITE, 1, &bh);
52 bh->b_count--;
53 return 0;
54 }
55
56 static int sync_iblock (struct inode * inode, unsigned short * iblock,
57 struct buffer_head **bh, int wait)
58 {
59 int rc;
60 unsigned short tmp;
61
62 *bh = NULL;
63 tmp = *iblock;
64 if (!tmp)
65 return 0;
66 rc = sync_block (inode, iblock, wait);
67 if (rc)
68 return rc;
69 *bh = bread(inode->i_dev, tmp, blocksize);
70 if (tmp != *iblock) {
71 brelse(*bh);
72 *bh = NULL;
73 return 1;
74 }
75 if (!*bh)
76 return -1;
77 return 0;
78 }
79
80
81 static int sync_direct(struct inode *inode, int wait)
82 {
83 int i;
84 int rc, err = 0;
85
86 for (i = 0; i < 7; i++) {
87 rc = sync_block (inode, inode->u.minix_i.i_data + i, wait);
88 if (rc > 0)
89 break;
90 if (rc)
91 err = rc;
92 }
93 return err;
94 }
95
96 static int sync_indirect(struct inode *inode, unsigned short *iblock, int wait)
97 {
98 int i;
99 struct buffer_head * ind_bh;
100 int rc, err = 0;
101
102 rc = sync_iblock (inode, iblock, &ind_bh, wait);
103 if (rc || !ind_bh)
104 return rc;
105
106 for (i = 0; i < addr_per_block; i++) {
107 rc = sync_block (inode,
108 ((unsigned short *) ind_bh->b_data) + i,
109 wait);
110 if (rc > 0)
111 break;
112 if (rc)
113 err = rc;
114 }
115 brelse(ind_bh);
116 return err;
117 }
118
119 static int sync_dindirect(struct inode *inode, unsigned short *diblock,
120 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 ((unsigned short *) 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 int minix_sync_file(struct inode * inode, struct file * file)
144 {
145 int wait, err = 0;
146
147 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
148 S_ISLNK(inode->i_mode)))
149 return -EINVAL;
150
151 for (wait=0; wait<=1; wait++)
152 {
153 err |= sync_direct(inode, wait);
154 err |= sync_indirect(inode, inode->u.minix_i.i_data+7, wait);
155 err |= sync_dindirect(inode, inode->u.minix_i.i_data+8, wait);
156 }
157 err |= minix_sync_inode (inode);
158 return (err < 0) ? -EIO : 0;
159 }