This source file includes following definitions.
- sync_block
- sync_iblock
- sync_direct
- sync_indirect
- sync_dindirect
- xiafs_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/xia_fs.h>
22
23 #include "xiafs_mac.h"
24
25
26 #define blocksize (XIAFS_ZSIZE(inode->i_sb))
27 #define addr_per_block (XIAFS_ADDRS_PER_Z(inode->i_sb))
28
29 static int sync_block (struct inode * inode, unsigned long * block, int wait)
30 {
31 struct buffer_head * bh;
32 int tmp;
33
34 if (!*block)
35 return 0;
36 tmp = *block;
37 bh = get_hash_table(inode->i_dev, *block, blocksize);
38 if (!bh)
39 return 0;
40 if (*block != tmp) {
41 brelse (bh);
42 return 1;
43 }
44 if (wait && bh->b_req && !bh->b_uptodate) {
45 brelse(bh);
46 return -1;
47 }
48 if (wait || !bh->b_uptodate || !bh->b_dirt)
49 {
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 < 8; i++) {
88 rc = sync_block (inode, inode->u.ext_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, int wait)
98 {
99 int i;
100 struct buffer_head * ind_bh;
101 int rc, err = 0;
102
103 rc = sync_iblock (inode, iblock, &ind_bh, wait);
104 if (rc || !ind_bh)
105 return rc;
106
107 for (i = 0; i < addr_per_block; i++) {
108 rc = sync_block (inode,
109 ((unsigned long *) ind_bh->b_data) + i,
110 wait);
111 if (rc > 0)
112 break;
113 if (rc)
114 err = rc;
115 }
116 brelse(ind_bh);
117 return err;
118 }
119
120 static int sync_dindirect(struct inode *inode, unsigned long *diblock,
121 int wait)
122 {
123 int i;
124 struct buffer_head * dind_bh;
125 int rc, err = 0;
126
127 rc = sync_iblock (inode, diblock, &dind_bh, wait);
128 if (rc || !dind_bh)
129 return rc;
130
131 for (i = 0; i < addr_per_block; i++) {
132 rc = sync_indirect (inode,
133 ((unsigned long *) dind_bh->b_data) + i,
134 wait);
135 if (rc > 0)
136 break;
137 if (rc)
138 err = rc;
139 }
140 brelse(dind_bh);
141 return err;
142 }
143
144 int xiafs_sync_file(struct inode * inode, struct file * file)
145 {
146 int wait, err = 0;
147
148 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
149 S_ISLNK(inode->i_mode)))
150 return -EINVAL;
151 for (wait=0; wait<=1; wait++)
152 {
153 err |= sync_direct(inode, wait);
154 err |= sync_indirect(inode, &inode->u.xiafs_i.i_ind_zone, wait);
155 err |= sync_dindirect(inode, &inode->u.xiafs_i.i_dind_zone, wait);
156 }
157 err |= xiafs_sync_inode (inode);
158 return (err < 0) ? -EIO : 0;
159 }