Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  linux/fs/ufs/cylinder.c
0004  *
0005  * Copyright (C) 1998
0006  * Daniel Pirkl <daniel.pirkl@email.cz>
0007  * Charles University, Faculty of Mathematics and Physics
0008  *
0009  *  ext2 - inode (block) bitmap caching inspired
0010  */
0011 
0012 #include <linux/fs.h>
0013 #include <linux/time.h>
0014 #include <linux/stat.h>
0015 #include <linux/string.h>
0016 #include <linux/bitops.h>
0017 
0018 #include <asm/byteorder.h>
0019 
0020 #include "ufs_fs.h"
0021 #include "ufs.h"
0022 #include "swab.h"
0023 #include "util.h"
0024 
0025 /*
0026  * Read cylinder group into cache. The memory space for ufs_cg_private_info
0027  * structure is already allocated during ufs_read_super.
0028  */
0029 static void ufs_read_cylinder (struct super_block * sb,
0030     unsigned cgno, unsigned bitmap_nr)
0031 {
0032     struct ufs_sb_info * sbi = UFS_SB(sb);
0033     struct ufs_sb_private_info * uspi;
0034     struct ufs_cg_private_info * ucpi;
0035     struct ufs_cylinder_group * ucg;
0036     unsigned i, j;
0037 
0038     UFSD("ENTER, cgno %u, bitmap_nr %u\n", cgno, bitmap_nr);
0039     uspi = sbi->s_uspi;
0040     ucpi = sbi->s_ucpi[bitmap_nr];
0041     ucg = (struct ufs_cylinder_group *)sbi->s_ucg[cgno]->b_data;
0042 
0043     UCPI_UBH(ucpi)->fragment = ufs_cgcmin(cgno);
0044     UCPI_UBH(ucpi)->count = uspi->s_cgsize >> sb->s_blocksize_bits;
0045     /*
0046      * We have already the first fragment of cylinder group block in buffer
0047      */
0048     UCPI_UBH(ucpi)->bh[0] = sbi->s_ucg[cgno];
0049     for (i = 1; i < UCPI_UBH(ucpi)->count; i++)
0050         if (!(UCPI_UBH(ucpi)->bh[i] = sb_bread(sb, UCPI_UBH(ucpi)->fragment + i)))
0051             goto failed;
0052     sbi->s_cgno[bitmap_nr] = cgno;
0053             
0054     ucpi->c_cgx = fs32_to_cpu(sb, ucg->cg_cgx);
0055     ucpi->c_ncyl    = fs16_to_cpu(sb, ucg->cg_ncyl);
0056     ucpi->c_niblk   = fs16_to_cpu(sb, ucg->cg_niblk);
0057     ucpi->c_ndblk   = fs32_to_cpu(sb, ucg->cg_ndblk);
0058     ucpi->c_rotor   = fs32_to_cpu(sb, ucg->cg_rotor);
0059     ucpi->c_frotor  = fs32_to_cpu(sb, ucg->cg_frotor);
0060     ucpi->c_irotor  = fs32_to_cpu(sb, ucg->cg_irotor);
0061     ucpi->c_btotoff = fs32_to_cpu(sb, ucg->cg_btotoff);
0062     ucpi->c_boff    = fs32_to_cpu(sb, ucg->cg_boff);
0063     ucpi->c_iusedoff = fs32_to_cpu(sb, ucg->cg_iusedoff);
0064     ucpi->c_freeoff = fs32_to_cpu(sb, ucg->cg_freeoff);
0065     ucpi->c_nextfreeoff = fs32_to_cpu(sb, ucg->cg_nextfreeoff);
0066     ucpi->c_clustersumoff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clustersumoff);
0067     ucpi->c_clusteroff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clusteroff);
0068     ucpi->c_nclusterblks = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_nclusterblks);
0069     UFSD("EXIT\n");
0070     return; 
0071     
0072 failed:
0073     for (j = 1; j < i; j++)
0074         brelse (sbi->s_ucg[j]);
0075     sbi->s_cgno[bitmap_nr] = UFS_CGNO_EMPTY;
0076     ufs_error (sb, "ufs_read_cylinder", "can't read cylinder group block %u", cgno);
0077 }
0078 
0079 /*
0080  * Remove cylinder group from cache, doesn't release memory
0081  * allocated for cylinder group (this is done at ufs_put_super only).
0082  */
0083 void ufs_put_cylinder (struct super_block * sb, unsigned bitmap_nr)
0084 {
0085     struct ufs_sb_info * sbi = UFS_SB(sb);
0086     struct ufs_sb_private_info * uspi; 
0087     struct ufs_cg_private_info * ucpi;
0088     struct ufs_cylinder_group * ucg;
0089     unsigned i;
0090 
0091     UFSD("ENTER, bitmap_nr %u\n", bitmap_nr);
0092 
0093     uspi = sbi->s_uspi;
0094     if (sbi->s_cgno[bitmap_nr] == UFS_CGNO_EMPTY) {
0095         UFSD("EXIT\n");
0096         return;
0097     }
0098     ucpi = sbi->s_ucpi[bitmap_nr];
0099     ucg = ubh_get_ucg(UCPI_UBH(ucpi));
0100 
0101     if (uspi->s_ncg > UFS_MAX_GROUP_LOADED && bitmap_nr >= sbi->s_cg_loaded) {
0102         ufs_panic (sb, "ufs_put_cylinder", "internal error");
0103         return;
0104     }
0105     /*
0106      * rotor is not so important data, so we put it to disk 
0107      * at the end of working with cylinder
0108      */
0109     ucg->cg_rotor = cpu_to_fs32(sb, ucpi->c_rotor);
0110     ucg->cg_frotor = cpu_to_fs32(sb, ucpi->c_frotor);
0111     ucg->cg_irotor = cpu_to_fs32(sb, ucpi->c_irotor);
0112     ubh_mark_buffer_dirty (UCPI_UBH(ucpi));
0113     for (i = 1; i < UCPI_UBH(ucpi)->count; i++) {
0114         brelse (UCPI_UBH(ucpi)->bh[i]);
0115     }
0116 
0117     sbi->s_cgno[bitmap_nr] = UFS_CGNO_EMPTY;
0118     UFSD("EXIT\n");
0119 }
0120 
0121 /*
0122  * Find cylinder group in cache and return it as pointer.
0123  * If cylinder group is not in cache, we will load it from disk.
0124  *
0125  * The cache is managed by LRU algorithm. 
0126  */
0127 struct ufs_cg_private_info * ufs_load_cylinder (
0128     struct super_block * sb, unsigned cgno)
0129 {
0130     struct ufs_sb_info * sbi = UFS_SB(sb);
0131     struct ufs_sb_private_info * uspi;
0132     struct ufs_cg_private_info * ucpi;
0133     unsigned cg, i, j;
0134 
0135     UFSD("ENTER, cgno %u\n", cgno);
0136 
0137     uspi = sbi->s_uspi;
0138     if (cgno >= uspi->s_ncg) {
0139         ufs_panic (sb, "ufs_load_cylinder", "internal error, high number of cg");
0140         return NULL;
0141     }
0142     /*
0143      * Cylinder group number cg it in cache and it was last used
0144      */
0145     if (sbi->s_cgno[0] == cgno) {
0146         UFSD("EXIT\n");
0147         return sbi->s_ucpi[0];
0148     }
0149     /*
0150      * Number of cylinder groups is not higher than UFS_MAX_GROUP_LOADED
0151      */
0152     if (uspi->s_ncg <= UFS_MAX_GROUP_LOADED) {
0153         if (sbi->s_cgno[cgno] != UFS_CGNO_EMPTY) {
0154             if (sbi->s_cgno[cgno] != cgno) {
0155                 ufs_panic (sb, "ufs_load_cylinder", "internal error, wrong number of cg in cache");
0156                 UFSD("EXIT (FAILED)\n");
0157                 return NULL;
0158             }
0159             else {
0160                 UFSD("EXIT\n");
0161                 return sbi->s_ucpi[cgno];
0162             }
0163         } else {
0164             ufs_read_cylinder (sb, cgno, cgno);
0165             UFSD("EXIT\n");
0166             return sbi->s_ucpi[cgno];
0167         }
0168     }
0169     /*
0170      * Cylinder group number cg is in cache but it was not last used, 
0171      * we will move to the first position
0172      */
0173     for (i = 0; i < sbi->s_cg_loaded && sbi->s_cgno[i] != cgno; i++);
0174     if (i < sbi->s_cg_loaded && sbi->s_cgno[i] == cgno) {
0175         cg = sbi->s_cgno[i];
0176         ucpi = sbi->s_ucpi[i];
0177         for (j = i; j > 0; j--) {
0178             sbi->s_cgno[j] = sbi->s_cgno[j-1];
0179             sbi->s_ucpi[j] = sbi->s_ucpi[j-1];
0180         }
0181         sbi->s_cgno[0] = cg;
0182         sbi->s_ucpi[0] = ucpi;
0183     /*
0184      * Cylinder group number cg is not in cache, we will read it from disk
0185      * and put it to the first position
0186      */
0187     } else {
0188         if (sbi->s_cg_loaded < UFS_MAX_GROUP_LOADED)
0189             sbi->s_cg_loaded++;
0190         else
0191             ufs_put_cylinder (sb, UFS_MAX_GROUP_LOADED-1);
0192         ucpi = sbi->s_ucpi[sbi->s_cg_loaded - 1];
0193         for (j = sbi->s_cg_loaded - 1; j > 0; j--) {
0194             sbi->s_cgno[j] = sbi->s_cgno[j-1];
0195             sbi->s_ucpi[j] = sbi->s_ucpi[j-1];
0196         }
0197         sbi->s_ucpi[0] = ucpi;
0198         ufs_read_cylinder (sb, cgno, 0);
0199     }
0200     UFSD("EXIT\n");
0201     return sbi->s_ucpi[0];
0202 }