The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/hpfs/map.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *  linux/fs/hpfs/map.c
    3  *
    4  *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
    5  *
    6  *  mapping structures to memory with some minimal checks
    7  */
    8 
    9 #include "hpfs_fn.h"
   10 
   11 __le32 *hpfs_map_dnode_bitmap(struct super_block *s, struct quad_buffer_head *qbh)
   12 {
   13         return hpfs_map_4sectors(s, hpfs_sb(s)->sb_dmap, qbh, 0);
   14 }
   15 
   16 __le32 *hpfs_map_bitmap(struct super_block *s, unsigned bmp_block,
   17                          struct quad_buffer_head *qbh, char *id)
   18 {
   19         secno sec;
   20         if (hpfs_sb(s)->sb_chk) if (bmp_block * 16384 > hpfs_sb(s)->sb_fs_size) {
   21                 hpfs_error(s, "hpfs_map_bitmap called with bad parameter: %08x at %s", bmp_block, id);
   22                 return NULL;
   23         }
   24         sec = le32_to_cpu(hpfs_sb(s)->sb_bmp_dir[bmp_block]);
   25         if (!sec || sec > hpfs_sb(s)->sb_fs_size-4) {
   26                 hpfs_error(s, "invalid bitmap block pointer %08x -> %08x at %s", bmp_block, sec, id);
   27                 return NULL;
   28         }
   29         return hpfs_map_4sectors(s, sec, qbh, 4);
   30 }
   31 
   32 /*
   33  * Load first code page into kernel memory, return pointer to 256-byte array,
   34  * first 128 bytes are uppercasing table for chars 128-255, next 128 bytes are
   35  * lowercasing table
   36  */
   37 
   38 unsigned char *hpfs_load_code_page(struct super_block *s, secno cps)
   39 {
   40         struct buffer_head *bh;
   41         secno cpds;
   42         unsigned cpi;
   43         unsigned char *ptr;
   44         unsigned char *cp_table;
   45         int i;
   46         struct code_page_data *cpd;
   47         struct code_page_directory *cp = hpfs_map_sector(s, cps, &bh, 0);
   48         if (!cp) return NULL;
   49         if (le32_to_cpu(cp->magic) != CP_DIR_MAGIC) {
   50                 printk("HPFS: Code page directory magic doesn't match (magic = %08x)\n", le32_to_cpu(cp->magic));
   51                 brelse(bh);
   52                 return NULL;
   53         }
   54         if (!le32_to_cpu(cp->n_code_pages)) {
   55                 printk("HPFS: n_code_pages == 0\n");
   56                 brelse(bh);
   57                 return NULL;
   58         }
   59         cpds = le32_to_cpu(cp->array[0].code_page_data);
   60         cpi = le16_to_cpu(cp->array[0].index);
   61         brelse(bh);
   62 
   63         if (cpi >= 3) {
   64                 printk("HPFS: Code page index out of array\n");
   65                 return NULL;
   66         }
   67         
   68         if (!(cpd = hpfs_map_sector(s, cpds, &bh, 0))) return NULL;
   69         if (le16_to_cpu(cpd->offs[cpi]) > 0x178) {
   70                 printk("HPFS: Code page index out of sector\n");
   71                 brelse(bh);
   72                 return NULL;
   73         }
   74         ptr = (unsigned char *)cpd + le16_to_cpu(cpd->offs[cpi]) + 6;
   75         if (!(cp_table = kmalloc(256, GFP_KERNEL))) {
   76                 printk("HPFS: out of memory for code page table\n");
   77                 brelse(bh);
   78                 return NULL;
   79         }
   80         memcpy(cp_table, ptr, 128);
   81         brelse(bh);
   82 
   83         /* Try to build lowercasing table from uppercasing one */
   84 
   85         for (i=128; i<256; i++) cp_table[i]=i;
   86         for (i=128; i<256; i++) if (cp_table[i-128]!=i && cp_table[i-128]>=128)
   87                 cp_table[cp_table[i-128]] = i;
   88         
   89         return cp_table;
   90 }
   91 
   92 __le32 *hpfs_load_bitmap_directory(struct super_block *s, secno bmp)
   93 {
   94         struct buffer_head *bh;
   95         int n = (hpfs_sb(s)->sb_fs_size + 0x200000 - 1) >> 21;
   96         int i;
   97         __le32 *b;
   98         if (!(b = kmalloc(n * 512, GFP_KERNEL))) {
   99                 printk("HPFS: can't allocate memory for bitmap directory\n");
  100                 return NULL;
  101         }       
  102         for (i=0;i<n;i++) {
  103                 __le32 *d = hpfs_map_sector(s, bmp+i, &bh, n - i - 1);
  104                 if (!d) {
  105                         kfree(b);
  106                         return NULL;
  107                 }
  108                 memcpy((char *)b + 512 * i, d, 512);
  109                 brelse(bh);
  110         }
  111         return b;
  112 }
  113 
  114 /*
  115  * Load fnode to memory
  116  */
  117 
  118 struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_head **bhp)
  119 {
  120         struct fnode *fnode;
  121         if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, ino, 1, "fnode")) {
  122                 return NULL;
  123         }
  124         if ((fnode = hpfs_map_sector(s, ino, bhp, FNODE_RD_AHEAD))) {
  125                 if (hpfs_sb(s)->sb_chk) {
  126                         struct extended_attribute *ea;
  127                         struct extended_attribute *ea_end;
  128                         if (le32_to_cpu(fnode->magic) != FNODE_MAGIC) {
  129                                 hpfs_error(s, "bad magic on fnode %08lx",
  130                                         (unsigned long)ino);
  131                                 goto bail;
  132                         }
  133                         if (!fnode_is_dir(fnode)) {
  134                                 if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes !=
  135                                     (bp_internal(&fnode->btree) ? 12 : 8)) {
  136                                         hpfs_error(s,
  137                                            "bad number of nodes in fnode %08lx",
  138                                             (unsigned long)ino);
  139                                         goto bail;
  140                                 }
  141                                 if (le16_to_cpu(fnode->btree.first_free) !=
  142                                     8 + fnode->btree.n_used_nodes * (bp_internal(&fnode->btree) ? 8 : 12)) {
  143                                         hpfs_error(s,
  144                                             "bad first_free pointer in fnode %08lx",
  145                                             (unsigned long)ino);
  146                                         goto bail;
  147                                 }
  148                         }
  149                         if (le16_to_cpu(fnode->ea_size_s) && (le16_to_cpu(fnode->ea_offs) < 0xc4 ||
  150                            le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) > 0x200)) {
  151                                 hpfs_error(s,
  152                                         "bad EA info in fnode %08lx: ea_offs == %04x ea_size_s == %04x",
  153                                         (unsigned long)ino,
  154                                         le16_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s));
  155                                 goto bail;
  156                         }
  157                         ea = fnode_ea(fnode);
  158                         ea_end = fnode_end_ea(fnode);
  159                         while (ea != ea_end) {
  160                                 if (ea > ea_end) {
  161                                         hpfs_error(s, "bad EA in fnode %08lx",
  162                                                 (unsigned long)ino);
  163                                         goto bail;
  164                                 }
  165                                 ea = next_ea(ea);
  166                         }
  167                 }
  168         }
  169         return fnode;
  170         bail:
  171         brelse(*bhp);
  172         return NULL;
  173 }
  174 
  175 struct anode *hpfs_map_anode(struct super_block *s, anode_secno ano, struct buffer_head **bhp)
  176 {
  177         struct anode *anode;
  178         if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, ano, 1, "anode")) return NULL;
  179         if ((anode = hpfs_map_sector(s, ano, bhp, ANODE_RD_AHEAD)))
  180                 if (hpfs_sb(s)->sb_chk) {
  181                         if (le32_to_cpu(anode->magic) != ANODE_MAGIC) {
  182                                 hpfs_error(s, "bad magic on anode %08x", ano);
  183                                 goto bail;
  184                         }
  185                         if (le32_to_cpu(anode->self) != ano) {
  186                                 hpfs_error(s, "self pointer invalid on anode %08x", ano);
  187                                 goto bail;
  188                         }
  189                         if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes !=
  190                             (bp_internal(&anode->btree) ? 60 : 40)) {
  191                                 hpfs_error(s, "bad number of nodes in anode %08x", ano);
  192                                 goto bail;
  193                         }
  194                         if (le16_to_cpu(anode->btree.first_free) !=
  195                             8 + anode->btree.n_used_nodes * (bp_internal(&anode->btree) ? 8 : 12)) {
  196                                 hpfs_error(s, "bad first_free pointer in anode %08x", ano);
  197                                 goto bail;
  198                         }
  199                 }
  200         return anode;
  201         bail:
  202         brelse(*bhp);
  203         return NULL;
  204 }
  205 
  206 /*
  207  * Load dnode to memory and do some checks
  208  */
  209 
  210 struct dnode *hpfs_map_dnode(struct super_block *s, unsigned secno,
  211                              struct quad_buffer_head *qbh)
  212 {
  213         struct dnode *dnode;
  214         if (hpfs_sb(s)->sb_chk) {
  215                 if (hpfs_chk_sectors(s, secno, 4, "dnode")) return NULL;
  216                 if (secno & 3) {
  217                         hpfs_error(s, "dnode %08x not byte-aligned", secno);
  218                         return NULL;
  219                 }       
  220         }
  221         if ((dnode = hpfs_map_4sectors(s, secno, qbh, DNODE_RD_AHEAD)))
  222                 if (hpfs_sb(s)->sb_chk) {
  223                         unsigned p, pp = 0;
  224                         unsigned char *d = (unsigned char *)dnode;
  225                         int b = 0;
  226                         if (le32_to_cpu(dnode->magic) != DNODE_MAGIC) {
  227                                 hpfs_error(s, "bad magic on dnode %08x", secno);
  228                                 goto bail;
  229                         }
  230                         if (le32_to_cpu(dnode->self) != secno)
  231                                 hpfs_error(s, "bad self pointer on dnode %08x self = %08x", secno, le32_to_cpu(dnode->self));
  232                         /* Check dirents - bad dirents would cause infinite
  233                            loops or shooting to memory */
  234                         if (le32_to_cpu(dnode->first_free) > 2048) {
  235                                 hpfs_error(s, "dnode %08x has first_free == %08x", secno, le32_to_cpu(dnode->first_free));
  236                                 goto bail;
  237                         }
  238                         for (p = 20; p < le32_to_cpu(dnode->first_free); p += d[p] + (d[p+1] << 8)) {
  239                                 struct hpfs_dirent *de = (struct hpfs_dirent *)((char *)dnode + p);
  240                                 if (le16_to_cpu(de->length) > 292 || (le16_to_cpu(de->length) < 32) || (le16_to_cpu(de->length) & 3) || p + le16_to_cpu(de->length) > 2048) {
  241                                         hpfs_error(s, "bad dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp);
  242                                         goto bail;
  243                                 }
  244                                 if (((31 + de->namelen + de->down*4 + 3) & ~3) != le16_to_cpu(de->length)) {
  245                                         if (((31 + de->namelen + de->down*4 + 3) & ~3) < le16_to_cpu(de->length) && s->s_flags & MS_RDONLY) goto ok;
  246                                         hpfs_error(s, "namelen does not match dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp);
  247                                         goto bail;
  248                                 }
  249                                 ok:
  250                                 if (hpfs_sb(s)->sb_chk >= 2) b |= 1 << de->down;
  251                                 if (de->down) if (de_down_pointer(de) < 0x10) {
  252                                         hpfs_error(s, "bad down pointer in dnode %08x, dirent %03x, last %03x", secno, p, pp);
  253                                         goto bail;
  254                                 }
  255                                 pp = p;
  256                                 
  257                         }
  258                         if (p != le32_to_cpu(dnode->first_free)) {
  259                                 hpfs_error(s, "size on last dirent does not match first_free; dnode %08x", secno);
  260                                 goto bail;
  261                         }
  262                         if (d[pp + 30] != 1 || d[pp + 31] != 255) {
  263                                 hpfs_error(s, "dnode %08x does not end with \\377 entry", secno);
  264                                 goto bail;
  265                         }
  266                         if (b == 3) printk("HPFS: warning: unbalanced dnode tree, dnode %08x; see hpfs.txt 4 more info\n", secno);
  267                 }
  268         return dnode;
  269         bail:
  270         hpfs_brelse4(qbh);
  271         return NULL;
  272 }
  273 
  274 dnode_secno hpfs_fnode_dno(struct super_block *s, ino_t ino)
  275 {
  276         struct buffer_head *bh;
  277         struct fnode *fnode;
  278         dnode_secno dno;
  279 
  280         fnode = hpfs_map_fnode(s, ino, &bh);
  281         if (!fnode)
  282                 return 0;
  283 
  284         dno = le32_to_cpu(fnode->u.external[0].disk_secno);
  285         brelse(bh);
  286         return dno;
  287 }

Cache object: 18bd53398c7462c8ffa6a9d5da19b542


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.