source: trunk/minix/lib/other/fslib.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 7.0 KB
Line 
1/* fslib.c - routines needed by fs and fs utilities */
2
3#include <minix/config.h> /* for unused stuff in <minix/type.h> :-( */
4#include <ansi.h>
5#include <limits.h>
6#include <dirent.h>
7#include <sys/types.h>
8#include <minix/const.h>
9#include <minix/type.h> /* for unshort :-( */
10#include "fs/const.h" /* depends of -I flag in Makefile */
11#include "fs/type.h" /* ditto */
12#include "fs/inode.h" /* ditto */
13#include "fs/super.h"
14#include <minix/fslib.h>
15
16/* The next routine is copied from fsck.c and mkfs.c... (Re)define some
17 * things for consistency. Some things should be done better.
18 */
19
20/* Convert from bit count to a block count. The usual expression
21 *
22 * (nr_bits + (1 << BITMAPSHIFT) - 1) >> BITMAPSHIFT
23 *
24 * doesn't work because of overflow.
25 *
26 * Other overflow bugs, such as the expression for N_ILIST overflowing when
27 * s_inodes is just over V*_INODES_PER_BLOCK less than the maximum+1, are not
28 * fixed yet, because that number of inodes is silly.
29 */
30/* The above comment doesn't all apply now bit_t is long. Overflow is now
31 * unlikely, but negative bit counts are now possible (though unlikely)
32 * and give silly results.
33 */
34PUBLIC int bitmapsize(nr_bits, block_size)
35bit_t nr_bits;
36int block_size;
37{
38 int nr_blocks;
39
40 nr_blocks = (int) (nr_bits / FS_BITS_PER_BLOCK(block_size));
41 if (((bit_t) nr_blocks * FS_BITS_PER_BLOCK(block_size)) < nr_bits) ++nr_blocks;
42 return(nr_blocks);
43}
44
45
46/*===========================================================================*
47 * conv2 *
48 *===========================================================================*/
49PUBLIC unsigned conv2(norm, w)
50int norm; /* TRUE if no swap, FALSE for byte swap */
51int w; /* promotion of 16-bit word to be swapped */
52{
53/* Possibly swap a 16-bit word between 8086 and 68000 byte order. */
54
55 if (norm) return( (unsigned) w & 0xFFFF);
56 return( ((w&BYTE) << 8) | ( (w>>8) & BYTE));
57}
58
59
60/*===========================================================================*
61 * conv4 *
62 *===========================================================================*/
63PUBLIC long conv4(norm, x)
64int norm; /* TRUE if no swap, FALSE for byte swap */
65long x; /* 32-bit long to be byte swapped */
66{
67/* Possibly swap a 32-bit long between 8086 and 68000 byte order. */
68
69 unsigned lo, hi;
70 long l;
71
72 if (norm) return(x); /* byte order was already ok */
73 lo = conv2(FALSE, (int) x & 0xFFFF); /* low-order half, byte swapped */
74 hi = conv2(FALSE, (int) (x>>16) & 0xFFFF); /* high-order half, swapped */
75 l = ( (long) lo <<16) | hi;
76 return(l);
77}
78
79
80/*===========================================================================*
81 * conv_inode *
82 *===========================================================================*/
83PUBLIC void conv_inode(rip, dip, dip2, rw_flag, magic)
84register struct inode *rip; /* pointer to the in-core inode struct */
85register d1_inode *dip; /* pointer to the V1 on-disk inode struct */
86register d2_inode *dip2; /* pointer to the V2 on-disk inode struct */
87int rw_flag; /* READING or WRITING */
88int magic; /* magic number of file system */
89{
90/* Copy the inode from the disk block to the in-core table or vice versa.
91 * If the fourth parameter below is FALSE, the bytes are swapped.
92 */
93 switch (magic) {
94 case SUPER_MAGIC: old_icopy(rip, dip, rw_flag, TRUE); break;
95 case SUPER_REV: old_icopy(rip, dip, rw_flag, FALSE); break;
96 case SUPER_V3:
97 case SUPER_V2: new_icopy(rip, dip2, rw_flag, TRUE); break;
98 case SUPER_V2_REV: new_icopy(rip, dip2, rw_flag, FALSE); break;
99 }
100}
101
102
103/*===========================================================================*
104 * old_icopy *
105 *===========================================================================*/
106PUBLIC void old_icopy(rip, dip, direction, norm)
107register struct inode *rip; /* pointer to the in-core inode struct */
108register d1_inode *dip; /* pointer to the d1_inode inode struct */
109int direction; /* READING (from disk) or WRITING (to disk) */
110int norm; /* TRUE = do not swap bytes; FALSE = swap */
111
112{
113/* 4 different on-disk inode layouts are supported, one for each combination
114 * of V1.x/V2.x * bytes-swapped/not-swapped. When an inode is read or written
115 * this routine handles the conversions so that the information in the inode
116 * table is independent of the disk structure from which the inode came.
117 * The old_icopy routine copies to and from V1 disks.
118 */
119
120 int i;
121
122 if (direction == READING) {
123 /* Copy V1.x inode to the in-core table, swapping bytes if need be. */
124 rip->i_mode = conv2(norm, dip->d1_mode);
125 rip->i_uid = conv2(norm,dip->d1_uid );
126 rip->i_size = conv4(norm,dip->d1_size);
127 rip->i_mtime = conv4(norm,dip->d1_mtime);
128 rip->i_atime = 0;
129 rip->i_ctime = 0;
130 rip->i_nlinks = (nlink_t) dip->d1_nlinks; /* 1 char */
131 rip->i_gid = (gid_t) dip->d1_gid; /* 1 char */
132 rip->i_ndzones = V1_NR_DZONES;
133 rip->i_nindirs = V1_INDIRECTS;
134 for (i = 0; i < V1_NR_TZONES; i++)
135 rip->i_zone[i] = conv2(norm, (int) dip->d1_zone[i]);
136 } else {
137 /* Copying V1.x inode to disk from the in-core table. */
138 dip->d1_mode = conv2(norm,rip->i_mode);
139 dip->d1_uid = conv2(norm,rip->i_uid );
140 dip->d1_size = conv4(norm,rip->i_size);
141 dip->d1_mtime = conv4(norm,rip->i_mtime);
142 dip->d1_nlinks = (nlink_t) rip->i_nlinks; /* 1 char */
143 dip->d1_gid = (gid_t) rip->i_gid; /* 1 char */
144 for (i = 0; i < V1_NR_TZONES; i++)
145 dip->d1_zone[i] = conv2(norm, (int) rip->i_zone[i]);
146 }
147}
148
149
150/*===========================================================================*
151 * new_icopy *
152 *===========================================================================*/
153PUBLIC void new_icopy(rip, dip, direction, norm)
154register struct inode *rip; /* pointer to the in-core inode struct */
155register d2_inode *dip; /* pointer to the d2_inode struct */
156int direction; /* READING (from disk) or WRITING (to disk) */
157int norm; /* TRUE = do not swap bytes; FALSE = swap */
158
159{
160/* Same as old_icopy, but to/from V2 disk layout. */
161
162 int i;
163
164 if (direction == READING) {
165 /* Copy V2.x inode to the in-core table, swapping bytes if need be. */
166 rip->i_mode = conv2(norm,dip->d2_mode);
167 rip->i_uid = conv2(norm,dip->d2_uid );
168 rip->i_nlinks = conv2(norm,(int) dip->d2_nlinks);
169 rip->i_gid = conv2(norm,(int) dip->d2_gid );
170 rip->i_size = conv4(norm,dip->d2_size);
171 rip->i_atime = conv4(norm,dip->d2_atime);
172 rip->i_ctime = conv4(norm,dip->d2_ctime);
173 rip->i_mtime = conv4(norm,dip->d2_mtime);
174 rip->i_ndzones = V2_NR_DZONES;
175 rip->i_nindirs = V2_INDIRECTS(rip->i_sp->s_block_size);
176 for (i = 0; i < V2_NR_TZONES; i++)
177 rip->i_zone[i] = conv4(norm, (long) dip->d2_zone[i]);
178 } else {
179 /* Copying V2.x inode to disk from the in-core table. */
180 dip->d2_mode = conv2(norm,rip->i_mode);
181 dip->d2_uid = conv2(norm,rip->i_uid );
182 dip->d2_nlinks = conv2(norm,rip->i_nlinks);
183 dip->d2_gid = conv2(norm,rip->i_gid );
184 dip->d2_size = conv4(norm,rip->i_size);
185 dip->d2_atime = conv4(norm,rip->i_atime);
186 dip->d2_ctime = conv4(norm,rip->i_ctime);
187 dip->d2_mtime = conv4(norm,rip->i_mtime);
188 for (i = 0; i < V2_NR_TZONES; i++)
189 dip->d2_zone[i] = conv4(norm, (long) rip->i_zone[i]);
190 }
191}
Note: See TracBrowser for help on using the repository browser.