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 unsigned *hpfs_map_dnode_bitmap(struct super_block *s, struct quad_buffer_head *qbh)
   12 {
   13         return hpfs_map_4sectors(s, s->s_hpfs_dmap, qbh, 0);
   14 }
   15 
   16 unsigned int *hpfs_map_bitmap(struct super_block *s, unsigned bmp_block,
   17                          struct quad_buffer_head *qbh, char *id)
   18 {
   19         secno sec;
   20         if (s->s_hpfs_chk) if (bmp_block * 16384 > s->s_hpfs_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 = s->s_hpfs_bmp_dir[bmp_block];
   25         if (!sec || sec > s->s_hpfs_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 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 (cp->magic != CP_DIR_MAGIC) {
   50                 printk("HPFS: Code page directory magic doesn't match (magic = %08x)\n", cp->magic);
   51                 brelse(bh);
   52                 return NULL;
   53         }
   54         if (!cp->n_code_pages) {
   55                 printk("HPFS: n_code_pages == 0\n");
   56                 brelse(bh);
   57                 return NULL;
   58         }
   59         cpds = cp->array[0].code_page_data;
   60         cpi = 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 ((unsigned)cpd->offs[cpi] > 0x178) {
   70                 printk("HPFS: Code page index out of sector\n");
   71                 brelse(bh);
   72                 return NULL;
   73         }
   74         ptr = (char *)cpd + 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 secno *hpfs_load_bitmap_directory(struct super_block *s, secno bmp)
   93 {
   94         struct buffer_head *bh;
   95         int n = (s->s_hpfs_fs_size + 0x200000 - 1) >> 21;
   96         int i;
   97         secno *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                 secno *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 (s->s_hpfs_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 (s->s_hpfs_chk) {
  126                         struct extended_attribute *ea;
  127                         struct extended_attribute *ea_end;
  128                         if (fnode->magic != FNODE_MAGIC) {
  129                                 hpfs_error(s, "bad magic on fnode %08x", ino);
  130                                 goto bail;
  131                         }
  132                         if (!fnode->dirflag) {
  133                                 if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes !=
  134                                     (fnode->btree.internal ? 12 : 8)) {
  135                                         hpfs_error(s, "bad number of nodes in fnode %08x", ino);
  136                                         goto bail;
  137                                 }
  138                                 if (fnode->btree.first_free !=
  139                                     8 + fnode->btree.n_used_nodes * (fnode->btree.internal ? 8 : 12)) {
  140                                         hpfs_error(s, "bad first_free pointer in fnode %08x", ino);
  141                                         goto bail;
  142                                 }
  143                         }
  144                         if (fnode->ea_size_s && ((signed int)fnode->ea_offs < 0xc4 ||
  145                            (signed int)fnode->ea_offs + fnode->ea_size_s > 0x200)) {
  146                                 hpfs_error(s, "bad EA info in fnode %08x: ea_offs == %04x ea_size_s == %04x",
  147                                         ino, fnode->ea_offs, fnode->ea_size_s);
  148                                 goto bail;
  149                         }
  150                         ea = fnode_ea(fnode);
  151                         ea_end = fnode_end_ea(fnode);
  152                         while (ea != ea_end) {
  153                                 if (ea > ea_end) {
  154                                         hpfs_error(s, "bad EA in fnode %08x", ino);
  155                                         goto bail;
  156                                 }
  157                                 ea = next_ea(ea);
  158                         }
  159                 }
  160         }
  161         return fnode;
  162         bail:
  163         brelse(*bhp);
  164         return NULL;
  165 }
  166 
  167 struct anode *hpfs_map_anode(struct super_block *s, anode_secno ano, struct buffer_head **bhp)
  168 {
  169         struct anode *anode;
  170         if (s->s_hpfs_chk) if (hpfs_chk_sectors(s, ano, 1, "anode")) return NULL;
  171         if ((anode = hpfs_map_sector(s, ano, bhp, ANODE_RD_AHEAD)))
  172                 if (s->s_hpfs_chk) {
  173                         if (anode->magic != ANODE_MAGIC || anode->self != ano) {
  174                                 hpfs_error(s, "bad magic on anode %08x", ano);
  175                                 goto bail;
  176                         }
  177                         if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes !=
  178                             (anode->btree.internal ? 60 : 40)) {
  179                                 hpfs_error(s, "bad number of nodes in anode %08x", ano);
  180                                 goto bail;
  181                         }
  182                         if (anode->btree.first_free !=
  183                             8 + anode->btree.n_used_nodes * (anode->btree.internal ? 8 : 12)) {
  184                                 hpfs_error(s, "bad first_free pointer in anode %08x", ano);
  185                                 goto bail;
  186                         }
  187                 }
  188         return anode;
  189         bail:
  190         brelse(*bhp);
  191         return NULL;
  192 }
  193 
  194 /*
  195  * Load dnode to memory and do some checks
  196  */
  197 
  198 struct dnode *hpfs_map_dnode(struct super_block *s, unsigned secno,
  199                              struct quad_buffer_head *qbh)
  200 {
  201         struct dnode *dnode;
  202         if (s->s_hpfs_chk) {
  203                 if (hpfs_chk_sectors(s, secno, 4, "dnode")) return NULL;
  204                 if (secno & 3) {
  205                         hpfs_error(s, "dnode %08x not byte-aligned", secno);
  206                         return NULL;
  207                 }       
  208         }
  209         if ((dnode = hpfs_map_4sectors(s, secno, qbh, DNODE_RD_AHEAD)))
  210                 if (s->s_hpfs_chk) {
  211                         unsigned p, pp = 0;
  212                         unsigned char *d = (char *)dnode;
  213                         int b = 0;
  214                         if (dnode->magic != DNODE_MAGIC) {
  215                                 hpfs_error(s, "bad magic on dnode %08x", secno);
  216                                 goto bail;
  217                         }
  218                         if (dnode->self != secno)
  219                                 hpfs_error(s, "bad self pointer on dnode %08x self = %08x", secno, dnode->self);
  220                         /* Check dirents - bad dirents would cause infinite
  221                            loops or shooting to memory */
  222                         if (dnode->first_free > 2048/* || dnode->first_free < 84*/) {
  223                                 hpfs_error(s, "dnode %08x has first_free == %08x", secno, dnode->first_free);
  224                                 goto bail;
  225                         }
  226                         for (p = 20; p < dnode->first_free; p += d[p] + (d[p+1] << 8)) {
  227                                 struct hpfs_dirent *de = (struct hpfs_dirent *)((char *)dnode + p);
  228                                 if (de->length > 292 || (de->length < 32) || (de->length & 3)) {
  229                                         hpfs_error(s, "bad dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp);
  230                                         goto bail;
  231                                 }
  232                                 if (((31 + de->namelen + de->down*4 + 3) & ~3) != de->length) {
  233                                         hpfs_error(s, "namelen does not match dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp);
  234                                         goto bail;
  235                                 }
  236                                 if (s->s_hpfs_chk >= 2) b |= 1 << de->down;
  237                                 if (de->down) if (de_down_pointer(de) < 0x10) {
  238                                         hpfs_error(s, "bad down pointer in dnode %08x, dirent %03x, last %03x", secno, p, pp);
  239                                         goto bail;
  240                                 }
  241                                 pp = p;
  242                                 
  243                         }
  244                         if (p != dnode->first_free) {
  245                                 hpfs_error(s, "size on last dirent does not match first_free; dnode %08x", secno);
  246                                 goto bail;
  247                         }
  248                         if (d[pp + 30] != 1 || d[pp + 31] != 255) {
  249                                 hpfs_error(s, "dnode %08x does not end with \\377 entry", secno);
  250                                 goto bail;
  251                         }
  252                         if (b == 3) printk("HPFS: warning: unbalanced dnode tree, dnode %08x; see hpfs.txt 4 more info\n", secno);
  253                 }
  254         return dnode;
  255         bail:
  256         hpfs_brelse4(qbh);
  257         return NULL;
  258 }
  259 
  260 dnode_secno hpfs_fnode_dno(struct super_block *s, ino_t ino)
  261 {
  262         struct buffer_head *bh;
  263         struct fnode *fnode;
  264         dnode_secno dno;
  265 
  266         fnode = hpfs_map_fnode(s, ino, &bh);
  267         if (!fnode)
  268                 return 0;
  269 
  270         dno = fnode->u.external[0].disk_secno;
  271         brelse(bh);
  272         return dno;
  273 }

Cache object: 768b2d9617fbe6d8c01fa511f2a0fbd6


[ 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.