1 /* fslib.c - routines needed by fs and fs utilities */
3 #include <minix/config.h> /* for unused stuff in <minix/type.h> :-( */
8 #include <minix/const.h>
9 #include <minix/type.h> /* for unshort :-( */
10 #include "mfs/const.h" /* depends of -I flag in Makefile */
11 #include "mfs/type.h" /* ditto */
12 #include "mfs/inode.h" /* ditto */
13 #include "mfs/super.h"
14 #include <minix/fslib.h>
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.
20 /* Convert from bit count to a block count. The usual expression
22 * (nr_bits + (1 << BITMAPSHIFT) - 1) >> BITMAPSHIFT
24 * doesn't work because of overflow.
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.
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.
34 PUBLIC
int bitmapsize(nr_bits
, block_size
)
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
;
46 /*===========================================================================*
48 *===========================================================================*/
49 PUBLIC
unsigned conv2(norm
, w
)
50 int norm
; /* TRUE if no swap, FALSE for byte swap */
51 int w
; /* promotion of 16-bit word to be swapped */
53 /* Possibly swap a 16-bit word between 8086 and 68000 byte order. */
55 if (norm
) return( (unsigned) w
& 0xFFFF);
56 return( ((w
&BYTE
) << 8) | ( (w
>>8) & BYTE
));
60 /*===========================================================================*
62 *===========================================================================*/
63 PUBLIC
long conv4(norm
, x
)
64 int norm
; /* TRUE if no swap, FALSE for byte swap */
65 long x
; /* 32-bit long to be byte swapped */
67 /* Possibly swap a 32-bit long between 8086 and 68000 byte order. */
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
;
80 /*===========================================================================*
82 *===========================================================================*/
83 PUBLIC
void conv_inode(rip
, dip
, dip2
, rw_flag
, magic
)
84 register struct inode
*rip
; /* pointer to the in-core inode struct */
85 register d1_inode
*dip
; /* pointer to the V1 on-disk inode struct */
86 register d2_inode
*dip2
; /* pointer to the V2 on-disk inode struct */
87 int rw_flag
; /* READING or WRITING */
88 int magic
; /* magic number of file system */
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.
94 case SUPER_MAGIC
: old_icopy(rip
, dip
, rw_flag
, TRUE
); break;
95 case SUPER_REV
: old_icopy(rip
, dip
, rw_flag
, FALSE
); break;
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;
103 /*===========================================================================*
105 *===========================================================================*/
106 PUBLIC
void old_icopy(rip
, dip
, direction
, norm
)
107 register struct inode
*rip
; /* pointer to the in-core inode struct */
108 register d1_inode
*dip
; /* pointer to the d1_inode inode struct */
109 int direction
; /* READING (from disk) or WRITING (to disk) */
110 int norm
; /* TRUE = do not swap bytes; FALSE = swap */
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.
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
);
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
]);
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
]);
150 /*===========================================================================*
152 *===========================================================================*/
153 PUBLIC
void new_icopy(rip
, dip
, direction
, norm
)
154 register struct inode
*rip
; /* pointer to the in-core inode struct */
155 register d2_inode
*dip
; /* pointer to the d2_inode struct */
156 int direction
; /* READING (from disk) or WRITING (to disk) */
157 int norm
; /* TRUE = do not swap bytes; FALSE = swap */
160 /* Same as old_icopy, but to/from V2 disk layout. */
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
]);
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
]);