home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume5 / fsanalyze4.1 / part01 / fragm.c < prev    next >
C/C++ Source or Header  |  1989-02-03  |  4KB  |  138 lines

  1. static char sccsid[] = "@(#)$Id: fragm.c, V4.1 88/11/16 17:29:42 $";
  2.  
  3. /*
  4.  * fragm.c - fragmentation analysis
  5.  * Version  : 4.1 - 88/11/16 17:29:42
  6.  *
  7.  * Author   : Michael J. Young
  8.  * USmail   : Software Development Technologies, Inc.
  9.  *            375 Dutton Rd
  10.  *            Sudbury MA 01776
  11.  * UUCP     : harvard!sdti!mjy
  12.  * Internet : mjy@sdti.SDTI.COM
  13.  *
  14.  * =========================================================================
  15.  * Note : This program has been placed in the public domain to permit
  16.  * unrestricted distribution and use.  I have placed no copyright on it, but
  17.  * I request that you keep me informed about any enhancements and bug fixes
  18.  * you make so I can keep an up-to-date copy for further distribution.
  19.  *
  20.  * This program is being provided "as is", with no warrantee as to safety or
  21.  * accuracy of results.  Use at your own risk.
  22.  * =========================================================================
  23.  */
  24.  
  25. /*
  26.  * Modification History:
  27.  *
  28.  * Thu Jul 28 15:57:32 EDT 1988 - M. Young (mjy@sdti.SDTI.COM),
  29.  *    Extracted from fsanalyze.c
  30.  *
  31.  * Mon Aug 08 11:27:39 EDT 1988 - M. Young (mjy@sdti.SDTI.COM),
  32.  *    Revised OS_TYPE and FS_TYPE macros to avoid name-space conflicts
  33.  *
  34.  * Wed Nov 16 11:31:32 EST 1988 - M. Young (mjy@sdti.SDTI.COM),
  35.  *    Placed under SCCS
  36.  */
  37.  
  38. /*
  39.  * Include files
  40.  */
  41. #include "fsconfig.h"
  42. #include "fsanalyze.h"
  43.  
  44. /*
  45.  * must_seek : returns true if the two data blocks reside on different
  46.  * disk cylinders.
  47.  */
  48. boolean must_seek (new_block, old_block)
  49. daddr_t new_block;            /* next data block */
  50. daddr_t old_block;            /* previous data block */
  51. {
  52.     daddr_t old_cyl;          /* base block of current cylinder */
  53.     daddr_t new_cyl;          /* base block of new cylinder */
  54.  
  55.     old_cyl = cylinder (fil_sys, old_block);
  56.     new_cyl = cylinder (fil_sys, new_block);
  57.  
  58.     return (old_cyl != new_cyl);
  59.     }
  60.  
  61. /*
  62.  * rotate_delay : returns true if the new data block is within the same
  63.  * cylinder, but is not at the optimum position within the cylinder
  64.  */
  65. boolean rot_delay (new_block, old_block)
  66. daddr_t new_block;            /* next data block */
  67. daddr_t old_block;            /* previous data block */
  68. {
  69.     daddr_t old_off;          /* cylinder offset of current block */
  70.     daddr_t new_off;          /* cylinder offset of next block */
  71.  
  72.     old_off = cyl_pos (fil_sys, old_block);
  73.     new_off = cyl_pos (fil_sys, new_block);
  74.  
  75.     return ((new_off != old_off + interleave) &&
  76.         (new_off != (old_off + interleave) % cyl_size) &&
  77.         (new_block != old_block + 1));
  78.     }
  79.  
  80. /*
  81.  * seek_dist : returns the number of cylinders that must be traversed
  82.  * to get from blk2 to blk1.
  83.  */
  84. long seek_dist (blk1, blk2)
  85. daddr_t blk1;                       /* new block */
  86. daddr_t blk2;                       /* previous block */
  87. {
  88.     daddr_t cyl1;          /* base block of current cylinder */
  89.     daddr_t cyl2;          /* base block of new cylinder */
  90.  
  91.     cyl1 = cylinder (fil_sys, blk1);
  92.     cyl2 = cylinder (fil_sys, blk2);
  93.  
  94.     return diff (cyl1, cyl2);
  95.     }
  96.  
  97. /*
  98.  * minimum_seeks : returns the number of cylinders that the file spans just
  99.  * by virtue of its size.  Any single-cylinder seeks due to the sheer size
  100.  * of the file will be ignored in the fragmentation calculation.
  101.  */
  102. long minimum_seeks (file_size)
  103. off_t file_size;                   /* size of file from inode entry */
  104. {
  105.     off_t bytes_per_cyl;
  106.  
  107.     bytes_per_cyl = (off_t)cyl_size * DEV_BSIZE;
  108.     return (file_size / bytes_per_cyl);
  109.     }
  110.  
  111. /*
  112.  * test_fragmentation : determines whether or not the two specified blocks
  113.  * indicate that fragmentation has occurred.  Disk seeks that are required
  114.  * due to the sheer size of the file are ignored in the calculation.  If
  115.  * no disk seeks are required, a heuristic is used to determine if the
  116.  * data blocks are optimally placed within the cylinder.
  117.  */
  118. void test_fragmentation (new_pos, old_pos, data)
  119. daddr_t new_pos;                 /* new block number */
  120. daddr_t old_pos;                 /* original block */
  121. struct file_data *data;          /* file statistics data structure */
  122. {
  123.     data->potential_seeks++;
  124.     if (must_seek (new_pos, old_pos)){
  125.     if (data->min_cost && seek_dist (new_pos, old_pos) == 1){
  126.             data->min_cost--;
  127.         }
  128.         else {
  129.             data->cost += seek_dist (new_pos, old_pos);
  130.             data->seeks++;
  131.         }
  132.         }
  133.     else if (rot_delay (new_pos, old_pos)){
  134.         data->rotates++;
  135.         }
  136.     }
  137.  
  138.