This source file includes following definitions.
- trunc_direct
- trunc_indirect
- trunc_dindirect
- minix_truncate
- minix_release
- check_char_dev
- minix_open
1
2
3
4
5
6
7 #include <linux/sched.h>
8 #include <linux/minix_fs.h>
9 #include <linux/tty.h>
10
11 #include <errno.h>
12 #include <fcntl.h>
13 #include <sys/stat.h>
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 static int trunc_direct(struct inode * inode)
29 {
30 int i;
31 int result = 0;
32 #define DIRECT_BLOCK ((inode->i_size + 1023) >> 10)
33
34 repeat:
35 for (i = DIRECT_BLOCK ; i < 7 ; i++) {
36 if (i < DIRECT_BLOCK)
37 goto repeat;
38 if (!inode->i_data[i])
39 continue;
40 result = 1;
41 if (minix_free_block(inode->i_dev,inode->i_data[i]))
42 inode->i_data[i] = 0;
43 }
44 return result;
45 }
46
47 static int trunc_indirect(struct inode * inode, int offset, unsigned short * p)
48 {
49 int i;
50 struct buffer_head * bh = NULL;
51 unsigned short * ind;
52 int result = 0;
53 #define INDIRECT_BLOCK (DIRECT_BLOCK-offset)
54
55 if (*p)
56 bh = bread(inode->i_dev,*p);
57 if (!bh)
58 return 0;
59 repeat:
60 for (i = INDIRECT_BLOCK ; i < 512 ; i++) {
61 if (i < 0)
62 i = 0;
63 if (i < INDIRECT_BLOCK)
64 goto repeat;
65 ind = i+(unsigned short *) bh->b_data;
66 if (!*ind)
67 continue;
68 result = 1;
69 if (minix_free_block(inode->i_dev,*ind))
70 *ind = 0;
71 }
72 ind = (unsigned short *) bh->b_data;
73 for (i = 0; i < 512; i++)
74 if (*(ind++))
75 break;
76 brelse(bh);
77 if (i >= 512) {
78 result = 1;
79 if (minix_free_block(inode->i_dev,*p))
80 *p = 0;
81 }
82 return result;
83 }
84
85 static int trunc_dindirect(struct inode * inode)
86 {
87 int i;
88 struct buffer_head * bh = NULL;
89 unsigned short * dind;
90 int result = 0;
91 #define DINDIRECT_BLOCK ((DIRECT_BLOCK-(512+7))>>9)
92
93 if (inode->i_data[8])
94 bh = bread(inode->i_dev,inode->i_data[8]);
95 if (!bh)
96 return 0;
97 repeat:
98 for (i = DINDIRECT_BLOCK ; i < 512 ; i ++) {
99 if (i < 0)
100 i = 0;
101 if (i < DINDIRECT_BLOCK)
102 goto repeat;
103 dind = i+(unsigned short *) bh->b_data;
104 if (!*dind)
105 continue;
106 result |= trunc_indirect(inode,7+512+(i<<9),dind);
107 }
108 dind = (unsigned short *) bh->b_data;
109 for (i = 0; i < 512; i++)
110 if (*(dind++))
111 break;
112 brelse(bh);
113 if (i >= 512) {
114 result = 1;
115 if (minix_free_block(inode->i_dev,inode->i_data[8]))
116 inode->i_data[8] = 0;
117 }
118 return result;
119 }
120
121 void minix_truncate(struct inode * inode)
122 {
123 int flag;
124
125 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
126 S_ISLNK(inode->i_mode)))
127 return;
128 if (inode->i_data[7] & 0xffff0000)
129 printk("BAD! minix inode has 16 high bits set\n");
130 while (1) {
131 flag = trunc_direct(inode);
132 flag |= trunc_indirect(inode,7,(unsigned short *)&inode->i_data[7]);
133 flag |= trunc_dindirect(inode);
134 if (!flag)
135 break;
136 current->counter = 0;
137 schedule();
138 }
139 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
140 inode->i_dirt = 1;
141 }
142
143
144
145
146
147
148 void minix_release(struct inode * inode, struct file * filp)
149 {
150 printk("minix_release not implemented\n");
151 }
152
153 static int check_char_dev(struct inode * inode, struct file * filp)
154 {
155 struct tty_struct *tty;
156 int min, dev;
157
158 dev = inode->i_rdev;
159 if (MAJOR(dev) == 4 || MAJOR(dev) == 5) {
160 if (MAJOR(dev) == 5)
161 min = current->tty;
162 else
163 min = MINOR(dev);
164 if (min < 0)
165 return -1;
166 if ((IS_A_PTY_MASTER(min)) && (inode->i_count>1))
167 return -1;
168 tty = TTY_TABLE(min);
169 if (!(filp->f_flags & O_NOCTTY) &&
170 current->leader &&
171 current->tty<0 &&
172 tty->session==0) {
173 current->tty = min;
174 tty->session= current->session;
175 tty->pgrp = current->pgrp;
176 }
177 if (IS_A_SERIAL(min))
178 serial_open(min-64);
179 }
180 return 0;
181 }
182
183
184
185
186 int minix_open(struct inode * inode, struct file * filp)
187 {
188 if (S_ISCHR(inode->i_mode)) {
189 if (check_char_dev(inode,filp))
190 return -EAGAIN;
191 } else if (S_ISBLK(inode->i_mode))
192 check_disk_change(inode->i_rdev);
193 else if (S_ISREG(inode->i_mode))
194 filp->f_op = &minix_file_operations;
195 else if (S_ISDIR(inode->i_mode))
196 filp->f_op = &minix_dir_operations;
197 return 0;
198 }