home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume5
/
fsanalyze4.1
/
part01
/
fragm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-02-03
|
4KB
|
138 lines
static char sccsid[] = "@(#)$Id: fragm.c, V4.1 88/11/16 17:29:42 $";
/*
* fragm.c - fragmentation analysis
* Version : 4.1 - 88/11/16 17:29:42
*
* Author : Michael J. Young
* USmail : Software Development Technologies, Inc.
* 375 Dutton Rd
* Sudbury MA 01776
* UUCP : harvard!sdti!mjy
* Internet : mjy@sdti.SDTI.COM
*
* =========================================================================
* Note : This program has been placed in the public domain to permit
* unrestricted distribution and use. I have placed no copyright on it, but
* I request that you keep me informed about any enhancements and bug fixes
* you make so I can keep an up-to-date copy for further distribution.
*
* This program is being provided "as is", with no warrantee as to safety or
* accuracy of results. Use at your own risk.
* =========================================================================
*/
/*
* Modification History:
*
* Thu Jul 28 15:57:32 EDT 1988 - M. Young (mjy@sdti.SDTI.COM),
* Extracted from fsanalyze.c
*
* Mon Aug 08 11:27:39 EDT 1988 - M. Young (mjy@sdti.SDTI.COM),
* Revised OS_TYPE and FS_TYPE macros to avoid name-space conflicts
*
* Wed Nov 16 11:31:32 EST 1988 - M. Young (mjy@sdti.SDTI.COM),
* Placed under SCCS
*/
/*
* Include files
*/
#include "fsconfig.h"
#include "fsanalyze.h"
/*
* must_seek : returns true if the two data blocks reside on different
* disk cylinders.
*/
boolean must_seek (new_block, old_block)
daddr_t new_block; /* next data block */
daddr_t old_block; /* previous data block */
{
daddr_t old_cyl; /* base block of current cylinder */
daddr_t new_cyl; /* base block of new cylinder */
old_cyl = cylinder (fil_sys, old_block);
new_cyl = cylinder (fil_sys, new_block);
return (old_cyl != new_cyl);
}
/*
* rotate_delay : returns true if the new data block is within the same
* cylinder, but is not at the optimum position within the cylinder
*/
boolean rot_delay (new_block, old_block)
daddr_t new_block; /* next data block */
daddr_t old_block; /* previous data block */
{
daddr_t old_off; /* cylinder offset of current block */
daddr_t new_off; /* cylinder offset of next block */
old_off = cyl_pos (fil_sys, old_block);
new_off = cyl_pos (fil_sys, new_block);
return ((new_off != old_off + interleave) &&
(new_off != (old_off + interleave) % cyl_size) &&
(new_block != old_block + 1));
}
/*
* seek_dist : returns the number of cylinders that must be traversed
* to get from blk2 to blk1.
*/
long seek_dist (blk1, blk2)
daddr_t blk1; /* new block */
daddr_t blk2; /* previous block */
{
daddr_t cyl1; /* base block of current cylinder */
daddr_t cyl2; /* base block of new cylinder */
cyl1 = cylinder (fil_sys, blk1);
cyl2 = cylinder (fil_sys, blk2);
return diff (cyl1, cyl2);
}
/*
* minimum_seeks : returns the number of cylinders that the file spans just
* by virtue of its size. Any single-cylinder seeks due to the sheer size
* of the file will be ignored in the fragmentation calculation.
*/
long minimum_seeks (file_size)
off_t file_size; /* size of file from inode entry */
{
off_t bytes_per_cyl;
bytes_per_cyl = (off_t)cyl_size * DEV_BSIZE;
return (file_size / bytes_per_cyl);
}
/*
* test_fragmentation : determines whether or not the two specified blocks
* indicate that fragmentation has occurred. Disk seeks that are required
* due to the sheer size of the file are ignored in the calculation. If
* no disk seeks are required, a heuristic is used to determine if the
* data blocks are optimally placed within the cylinder.
*/
void test_fragmentation (new_pos, old_pos, data)
daddr_t new_pos; /* new block number */
daddr_t old_pos; /* original block */
struct file_data *data; /* file statistics data structure */
{
data->potential_seeks++;
if (must_seek (new_pos, old_pos)){
if (data->min_cost && seek_dist (new_pos, old_pos) == 1){
data->min_cost--;
}
else {
data->cost += seek_dist (new_pos, old_pos);
data->seeks++;
}
}
else if (rot_delay (new_pos, old_pos)){
data->rotates++;
}
}