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/dnode.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/dnode.c
    3  *
    4  *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
    5  *
    6  *  handling directory dnode tree - adding, deleteing & searching for dirents
    7  */
    8 
    9 #include "hpfs_fn.h"
   10 
   11 static loff_t get_pos(struct dnode *d, struct hpfs_dirent *fde)
   12 {
   13         struct hpfs_dirent *de;
   14         struct hpfs_dirent *de_end = dnode_end_de(d);
   15         int i = 1;
   16         for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
   17                 if (de == fde) return ((loff_t) d->self << 4) | (loff_t)i;
   18                 i++;
   19         }
   20         printk("HPFS: get_pos: not_found\n");
   21         return ((loff_t)d->self << 4) | (loff_t)1;
   22 }
   23 
   24 void hpfs_add_pos(struct inode *inode, loff_t *pos)
   25 {
   26         int i = 0;
   27         loff_t **ppos;
   28         if (inode->i_hpfs_rddir_off)
   29                 for (; inode->i_hpfs_rddir_off[i]; i++)
   30                         if (inode->i_hpfs_rddir_off[i] == pos) return;
   31         if (!(i&0x0f)) {
   32                 if (!(ppos = kmalloc((i+0x11) * sizeof(loff_t*), GFP_KERNEL))) {
   33                         printk("HPFS: out of memory for position list\n");
   34                         return;
   35                 }
   36                 if (inode->i_hpfs_rddir_off) {
   37                         memcpy(ppos, inode->i_hpfs_rddir_off, i * sizeof(loff_t));
   38                         kfree(inode->i_hpfs_rddir_off);
   39                 }
   40                 inode->i_hpfs_rddir_off = ppos;
   41         }
   42         inode->i_hpfs_rddir_off[i] = pos;
   43         inode->i_hpfs_rddir_off[i + 1] = NULL;
   44 }
   45 
   46 void hpfs_del_pos(struct inode *inode, loff_t *pos)
   47 {
   48         loff_t **i, **j;
   49         if (!inode->i_hpfs_rddir_off) goto not_f;
   50         for (i = inode->i_hpfs_rddir_off; *i; i++) if (*i == pos) goto fnd;
   51         goto not_f;
   52         fnd:
   53         for (j = i + 1; *j; j++) ;
   54         *i = *(j - 1);
   55         *(j - 1) = NULL;
   56         if (j - 1 == inode->i_hpfs_rddir_off) {
   57                 kfree(inode->i_hpfs_rddir_off);
   58                 inode->i_hpfs_rddir_off = NULL;
   59         }
   60         return;
   61         not_f:
   62         /*printk("HPFS: warning: position pointer %p->%08x not found\n", pos, (int)*pos);*/
   63         return;
   64 }
   65 
   66 static void for_all_poss(struct inode *inode, void (*f)(loff_t *, loff_t, loff_t),
   67                          loff_t p1, loff_t p2)
   68 {
   69         loff_t **i;
   70         if (!inode->i_hpfs_rddir_off) return;
   71         for (i = inode->i_hpfs_rddir_off; *i; i++) (*f)(*i, p1, p2);
   72         return;
   73 }
   74 
   75 void hpfs_pos_subst(loff_t *p, loff_t f, loff_t t)
   76 {
   77         if (*p == f) *p = t;
   78 }
   79 
   80 /*void hpfs_hpfs_pos_substd(loff_t *p, loff_t f, loff_t t)
   81 {
   82         if ((*p & ~0x3f) == (f & ~0x3f)) *p = (t & ~0x3f) | (*p & 0x3f);
   83 }*/
   84 
   85 void hpfs_pos_ins(loff_t *p, loff_t d, loff_t c)
   86 {
   87         if ((*p & ~0x3f) == (d & ~0x3f) && (*p & 0x3f) >= (d & 0x3f)) {
   88                 int n = (*p & 0x3f) + c;
   89                 if (n > 0x3f) printk("HPFS: hpfs_pos_ins: %08x + %d\n", (int)*p, (int)c >> 8);
   90                 else *p = (*p & ~0x3f) | n;
   91         }
   92 }
   93 
   94 void hpfs_pos_del(loff_t *p, loff_t d, loff_t c)
   95 {
   96         if ((*p & ~0x3f) == (d & ~0x3f) && (*p & 0x3f) >= (d & 0x3f)) {
   97                 int n = (*p & 0x3f) - c;
   98                 if (n < 1) printk("HPFS: hpfs_pos_ins: %08x - %d\n", (int)*p, (int)c >> 8);
   99                 else *p = (*p & ~0x3f) | n;
  100         }
  101 }
  102 
  103 static struct hpfs_dirent *dnode_pre_last_de(struct dnode *d)
  104 {
  105         struct hpfs_dirent *de, *de_end, *dee = NULL, *deee = NULL;
  106         de_end = dnode_end_de(d);
  107         for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
  108                 deee = dee; dee = de;
  109         }       
  110         return deee;
  111 }
  112 
  113 static struct hpfs_dirent *dnode_last_de(struct dnode *d)
  114 {
  115         struct hpfs_dirent *de, *de_end, *dee = NULL;
  116         de_end = dnode_end_de(d);
  117         for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
  118                 dee = de;
  119         }       
  120         return dee;
  121 }
  122 
  123 static void set_last_pointer(struct super_block *s, struct dnode *d, dnode_secno ptr)
  124 {
  125         struct hpfs_dirent *de;
  126         if (!(de = dnode_last_de(d))) {
  127                 hpfs_error(s, "set_last_pointer: empty dnode %08x", d->self);
  128                 return;
  129         }
  130         if (s->s_hpfs_chk) {
  131                 if (de->down) {
  132                         hpfs_error(s, "set_last_pointer: dnode %08x has already last pointer %08x",
  133                                 d->self, de_down_pointer(de));
  134                         return;
  135                 }
  136                 if (de->length != 32) {
  137                         hpfs_error(s, "set_last_pointer: bad last dirent in dnode %08x", d->self);
  138                         return;
  139                 }
  140         }
  141         if (ptr) {
  142                 if ((d->first_free += 4) > 2048) {
  143                         hpfs_error(s,"set_last_pointer: too long dnode %08x", d->self);
  144                         d->first_free -= 4;
  145                         return;
  146                 }
  147                 de->length = 36;
  148                 de->down = 1;
  149                 *(dnode_secno *)((char *)de + 32) = ptr;
  150         }
  151 }
  152 
  153 /* Add an entry to dnode and don't care if it grows over 2048 bytes */
  154 
  155 struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d, unsigned char *name,
  156                                 unsigned namelen, secno down_ptr)
  157 {
  158         struct hpfs_dirent *de;
  159         struct hpfs_dirent *de_end = dnode_end_de(d);
  160         unsigned d_size = de_size(namelen, down_ptr);
  161         for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
  162                 int c = hpfs_compare_names(s, name, namelen, de->name, de->namelen, de->last);
  163                 if (!c) {
  164                         hpfs_error(s, "name (%c,%d) already exists in dnode %08x", *name, namelen, d->self);
  165                         return NULL;
  166                 }
  167                 if (c < 0) break;
  168         }
  169         memmove((char *)de + d_size, de, (char *)de_end - (char *)de);
  170         memset(de, 0, d_size);
  171         if (down_ptr) {
  172                 *(int *)((char *)de + d_size - 4) = down_ptr;
  173                 de->down = 1;
  174         }
  175         de->length = d_size;
  176         if (down_ptr) de->down = 1;
  177         de->not_8x3 = hpfs_is_name_long(name, namelen);
  178         de->namelen = namelen;
  179         memcpy(de->name, name, namelen);
  180         d->first_free += d_size;
  181         return de;
  182 }
  183 
  184 /* Delete dirent and don't care about it's subtree */
  185 
  186 void hpfs_delete_de(struct super_block *s, struct dnode *d, struct hpfs_dirent *de)
  187 {
  188         if (de->last) {
  189                 hpfs_error(s, "attempt to delete last dirent in dnode %08x", d->self);
  190                 return;
  191         }
  192         d->first_free -= de->length;
  193         memmove(de, de_next_de(de), d->first_free + (char *)d - (char *)de);
  194 }
  195 
  196 static void fix_up_ptrs(struct super_block *s, struct dnode *d)
  197 {
  198         struct hpfs_dirent *de;
  199         struct hpfs_dirent *de_end = dnode_end_de(d);
  200         dnode_secno dno = d->self;
  201         for (de = dnode_first_de(d); de < de_end; de = de_next_de(de))
  202                 if (de->down) {
  203                         struct quad_buffer_head qbh;
  204                         struct dnode *dd;
  205                         if ((dd = hpfs_map_dnode(s, de_down_pointer(de), &qbh))) {
  206                                 if (dd->up != dno || dd->root_dnode) {
  207                                         dd->up = dno;
  208                                         dd->root_dnode = 0;
  209                                         hpfs_mark_4buffers_dirty(&qbh);
  210                                 }
  211                                 hpfs_brelse4(&qbh);
  212                         }
  213                 }
  214 }
  215 
  216 /* Add an entry to dnode and do dnode splitting if required */
  217 
  218 int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, unsigned char *name, unsigned namelen,
  219                       struct hpfs_dirent *new_de, dnode_secno down_ptr)
  220 {
  221         struct quad_buffer_head qbh, qbh1, qbh2;
  222         struct dnode *d, *ad, *rd, *nd = NULL;
  223         dnode_secno adno, rdno;
  224         struct hpfs_dirent *de;
  225         struct hpfs_dirent nde;
  226         char *nname;
  227         int h;
  228         int pos;
  229         struct buffer_head *bh;
  230         struct fnode *fnode;
  231         int c1, c2 = 0;
  232         if (!(nname = kmalloc(256, GFP_KERNEL))) {
  233                 printk("HPFS: out of memory, can't add to dnode\n");
  234                 return 1;
  235         }
  236         go_up:
  237         if (namelen >= 256) {
  238                 hpfs_error(i->i_sb, "hpfs_add_to_dnode: namelen == %d", namelen);
  239                 if (nd) kfree(nd);
  240                 kfree(nname);
  241                 return 1;
  242         }
  243         if (!(d = hpfs_map_dnode(i->i_sb, dno, &qbh))) {
  244                 if (nd) kfree(nd);
  245                 kfree(nname);
  246                 return 1;
  247         }
  248         go_up_a:
  249         if (i->i_sb->s_hpfs_chk)
  250                 if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "hpfs_add_to_dnode")) {
  251                         hpfs_brelse4(&qbh);
  252                         if (nd) kfree(nd);
  253                         kfree(nname);
  254                         return 1;
  255                 }
  256         if (d->first_free + de_size(namelen, down_ptr) <= 2048) {
  257                 loff_t t;
  258                 copy_de(de=hpfs_add_de(i->i_sb, d, name, namelen, down_ptr), new_de);
  259                 t = get_pos(d, de);
  260                 for_all_poss(i, hpfs_pos_ins, t, 1);
  261                 for_all_poss(i, hpfs_pos_subst, 4, t);
  262                 for_all_poss(i, hpfs_pos_subst, 5, t + 1);
  263                 hpfs_mark_4buffers_dirty(&qbh);
  264                 hpfs_brelse4(&qbh);
  265                 if (nd) kfree(nd);
  266                 kfree(nname);
  267                 return 0;
  268         }
  269         if (!nd) if (!(nd = kmalloc(0x924, GFP_KERNEL))) {
  270                 /* 0x924 is a max size of dnode after adding a dirent with
  271                    max name length. We alloc this only once. There must
  272                    not be any error while splitting dnodes, otherwise the
  273                    whole directory, not only file we're adding, would
  274                    be lost. */
  275                 printk("HPFS: out of memory for dnode splitting\n");
  276                 hpfs_brelse4(&qbh);
  277                 kfree(nname);
  278                 return 1;
  279         }       
  280         memcpy(nd, d, d->first_free);
  281         copy_de(de = hpfs_add_de(i->i_sb, nd, name, namelen, down_ptr), new_de);
  282         for_all_poss(i, hpfs_pos_ins, get_pos(nd, de), 1);
  283         h = ((char *)dnode_last_de(nd) - (char *)nd) / 2 + 10;
  284         if (!(ad = hpfs_alloc_dnode(i->i_sb, d->up, &adno, &qbh1, 0))) {
  285                 hpfs_error(i->i_sb, "unable to alloc dnode - dnode tree will be corrupted");
  286                 hpfs_brelse4(&qbh);
  287                 kfree(nd);
  288                 kfree(nname);
  289                 return 1;
  290         }
  291         i->i_size += 2048;
  292         i->i_blocks += 4;
  293         pos = 1;
  294         for (de = dnode_first_de(nd); (char *)de_next_de(de) - (char *)nd < h; de = de_next_de(de)) {
  295                 copy_de(hpfs_add_de(i->i_sb, ad, de->name, de->namelen, de->down ? de_down_pointer(de) : 0), de);
  296                 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | pos, ((loff_t)adno << 4) | pos);
  297                 pos++;
  298         }
  299         copy_de(new_de = &nde, de);
  300         memcpy(name = nname, de->name, namelen = de->namelen);
  301         for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | pos, 4);
  302         down_ptr = adno;
  303         set_last_pointer(i->i_sb, ad, de->down ? de_down_pointer(de) : 0);
  304         de = de_next_de(de);
  305         memmove((char *)nd + 20, de, nd->first_free + (char *)nd - (char *)de);
  306         nd->first_free -= (char *)de - (char *)nd - 20;
  307         memcpy(d, nd, nd->first_free);
  308         for_all_poss(i, hpfs_pos_del, (loff_t)dno << 4, pos);
  309         fix_up_ptrs(i->i_sb, ad);
  310         if (!d->root_dnode) {
  311                 dno = ad->up = d->up;
  312                 hpfs_mark_4buffers_dirty(&qbh);
  313                 hpfs_brelse4(&qbh);
  314                 hpfs_mark_4buffers_dirty(&qbh1);
  315                 hpfs_brelse4(&qbh1);
  316                 goto go_up;
  317         }
  318         if (!(rd = hpfs_alloc_dnode(i->i_sb, d->up, &rdno, &qbh2, 0))) {
  319                 hpfs_error(i->i_sb, "unable to alloc dnode - dnode tree will be corrupted");
  320                 hpfs_brelse4(&qbh);
  321                 hpfs_brelse4(&qbh1);
  322                 kfree(nd);
  323                 kfree(nname);
  324                 return 1;
  325         }
  326         i->i_size += 2048;
  327         i->i_blocks += 4;
  328         rd->root_dnode = 1;
  329         rd->up = d->up;
  330         if (!(fnode = hpfs_map_fnode(i->i_sb, d->up, &bh))) {
  331                 hpfs_free_dnode(i->i_sb, rdno);
  332                 hpfs_brelse4(&qbh);
  333                 hpfs_brelse4(&qbh1);
  334                 hpfs_brelse4(&qbh2);
  335                 kfree(nd);
  336                 kfree(nname);
  337                 return 1;
  338         }
  339         fnode->u.external[0].disk_secno = rdno;
  340         mark_buffer_dirty(bh);
  341         brelse(bh);
  342         d->up = ad->up = i->i_hpfs_dno = rdno;
  343         d->root_dnode = ad->root_dnode = 0;
  344         hpfs_mark_4buffers_dirty(&qbh);
  345         hpfs_brelse4(&qbh);
  346         hpfs_mark_4buffers_dirty(&qbh1);
  347         hpfs_brelse4(&qbh1);
  348         qbh = qbh2;
  349         set_last_pointer(i->i_sb, rd, dno);
  350         dno = rdno;
  351         d = rd;
  352         goto go_up_a;
  353 }
  354 
  355 /*
  356  * Add an entry to directory btree.
  357  * I hate such crazy directory structure.
  358  * It's easy to read but terrible to write.
  359  * I wrote this directory code 4 times.
  360  * I hope, now it's finally bug-free.
  361  */
  362 
  363 int hpfs_add_dirent(struct inode *i, unsigned char *name, unsigned namelen,
  364                     struct hpfs_dirent *new_de, int cdepth)
  365 {
  366         struct dnode *d;
  367         struct hpfs_dirent *de, *de_end;
  368         struct quad_buffer_head qbh;
  369         dnode_secno dno;
  370         int c;
  371         int c1, c2 = 0;
  372         dno = i->i_hpfs_dno;
  373         down:
  374         if (i->i_sb->s_hpfs_chk)
  375                 if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "hpfs_add_dirent")) return 1;
  376         if (!(d = hpfs_map_dnode(i->i_sb, dno, &qbh))) return 1;
  377         de_end = dnode_end_de(d);
  378         for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
  379                 if (!(c = hpfs_compare_names(i->i_sb, name, namelen, de->name, de->namelen, de->last))) {
  380                         hpfs_brelse4(&qbh);
  381                         return -1;
  382                 }       
  383                 if (c < 0) {
  384                         if (de->down) {
  385                                 dno = de_down_pointer(de);
  386                                 hpfs_brelse4(&qbh);
  387                                 goto down;
  388                         }
  389                         break;
  390                 }
  391         }
  392         hpfs_brelse4(&qbh);
  393         if (!cdepth) hpfs_lock_creation(i->i_sb);
  394         if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_ADD)) {
  395                 c = 1;
  396                 goto ret;
  397         }       
  398         i->i_version = ++event;
  399         c = hpfs_add_to_dnode(i, dno, name, namelen, new_de, 0);
  400         ret:
  401         if (!cdepth) hpfs_unlock_creation(i->i_sb);
  402         return c;
  403 }
  404 
  405 /* 
  406  * Find dirent with higher name in 'from' subtree and move it to 'to' dnode.
  407  * Return the dnode we moved from (to be checked later if it's empty)
  408  */
  409 
  410 static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to)
  411 {
  412         dnode_secno dno, ddno;
  413         dnode_secno chk_up = to;
  414         struct dnode *dnode;
  415         struct quad_buffer_head qbh;
  416         struct hpfs_dirent *de, *nde;
  417         int a;
  418         loff_t t;
  419         int c1, c2 = 0;
  420         dno = from;
  421         while (1) {
  422                 if (i->i_sb->s_hpfs_chk)
  423                         if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "move_to_top"))
  424                                 return 0;
  425                 if (!(dnode = hpfs_map_dnode(i->i_sb, dno, &qbh))) return 0;
  426                 if (i->i_sb->s_hpfs_chk) {
  427                         if (dnode->up != chk_up) {
  428                                 hpfs_error(i->i_sb, "move_to_top: up pointer from %08x should be %08x, is %08x",
  429                                         dno, chk_up, dnode->up);
  430                                 hpfs_brelse4(&qbh);
  431                                 return 0;
  432                         }
  433                         chk_up = dno;
  434                 }
  435                 if (!(de = dnode_last_de(dnode))) {
  436                         hpfs_error(i->i_sb, "move_to_top: dnode %08x has no last de", dno);
  437                         hpfs_brelse4(&qbh);
  438                         return 0;
  439                 }
  440                 if (!de->down) break;
  441                 dno = de_down_pointer(de);
  442                 hpfs_brelse4(&qbh);
  443         }
  444         while (!(de = dnode_pre_last_de(dnode))) {
  445                 dnode_secno up = dnode->up;
  446                 hpfs_brelse4(&qbh);
  447                 hpfs_free_dnode(i->i_sb, dno);
  448                 i->i_size -= 2048;
  449                 i->i_blocks -= 4;
  450                 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, 5);
  451                 if (up == to) return to;
  452                 if (!(dnode = hpfs_map_dnode(i->i_sb, up, &qbh))) return 0;
  453                 if (dnode->root_dnode) {
  454                         hpfs_error(i->i_sb, "move_to_top: got to root_dnode while moving from %08x to %08x", from, to);
  455                         hpfs_brelse4(&qbh);
  456                         return 0;
  457                 }
  458                 de = dnode_last_de(dnode);
  459                 if (!de || !de->down) {
  460                         hpfs_error(i->i_sb, "move_to_top: dnode %08x doesn't point down to %08x", up, dno);
  461                         hpfs_brelse4(&qbh);
  462                         return 0;
  463                 }
  464                 dnode->first_free -= 4;
  465                 de->length -= 4;
  466                 de->down = 0;
  467                 hpfs_mark_4buffers_dirty(&qbh);
  468                 dno = up;
  469         }
  470         t = get_pos(dnode, de);
  471         for_all_poss(i, hpfs_pos_subst, t, 4);
  472         for_all_poss(i, hpfs_pos_subst, t + 1, 5);
  473         if (!(nde = kmalloc(de->length, GFP_KERNEL))) {
  474                 hpfs_error(i->i_sb, "out of memory for dirent - directory will be corrupted");
  475                 hpfs_brelse4(&qbh);
  476                 return 0;
  477         }
  478         memcpy(nde, de, de->length);
  479         ddno = de->down ? de_down_pointer(de) : 0;
  480         hpfs_delete_de(i->i_sb, dnode, de);
  481         set_last_pointer(i->i_sb, dnode, ddno);
  482         hpfs_mark_4buffers_dirty(&qbh);
  483         hpfs_brelse4(&qbh);
  484         a = hpfs_add_to_dnode(i, to, nde->name, nde->namelen, nde, from);
  485         kfree(nde);
  486         if (a) return 0;
  487         return dno;
  488 }
  489 
  490 /* 
  491  * Check if a dnode is empty and delete it from the tree
  492  * (chkdsk doesn't like empty dnodes)
  493  */
  494 
  495 static void delete_empty_dnode(struct inode *i, dnode_secno dno)
  496 {
  497         struct quad_buffer_head qbh;
  498         struct dnode *dnode;
  499         dnode_secno down, up, ndown;
  500         int p;
  501         struct hpfs_dirent *de;
  502         int c1, c2 = 0;
  503         try_it_again:
  504         if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "delete_empty_dnode")) return;
  505         if (!(dnode = hpfs_map_dnode(i->i_sb, dno, &qbh))) return;
  506         if (dnode->first_free > 56) goto end;
  507         if (dnode->first_free == 52 || dnode->first_free == 56) {
  508                 struct hpfs_dirent *de_end;
  509                 int root = dnode->root_dnode;
  510                 up = dnode->up;
  511                 de = dnode_first_de(dnode);
  512                 down = de->down ? de_down_pointer(de) : 0;
  513                 if (i->i_sb->s_hpfs_chk) if (root && !down) {
  514                         hpfs_error(i->i_sb, "delete_empty_dnode: root dnode %08x is empty", dno);
  515                         goto end;
  516                 }
  517                 hpfs_brelse4(&qbh);
  518                 hpfs_free_dnode(i->i_sb, dno);
  519                 i->i_size -= 2048;
  520                 i->i_blocks -= 4;
  521                 if (root) {
  522                         struct fnode *fnode;
  523                         struct buffer_head *bh;
  524                         struct dnode *d1;
  525                         struct quad_buffer_head qbh1;
  526                         if (i->i_sb->s_hpfs_chk) if (up != i->i_ino) {
  527                                 hpfs_error(i->i_sb, "bad pointer to fnode, dnode %08x, pointing to %08x, should be %08x", dno, up, i->i_ino);
  528                                 return;
  529                         }
  530                         if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) {
  531                                 d1->up = up;
  532                                 d1->root_dnode = 1;
  533                                 hpfs_mark_4buffers_dirty(&qbh1);
  534                                 hpfs_brelse4(&qbh1);
  535                         }
  536                         if ((fnode = hpfs_map_fnode(i->i_sb, up, &bh))) {
  537                                 fnode->u.external[0].disk_secno = down;
  538                                 mark_buffer_dirty(bh);
  539                                 brelse(bh);
  540                         }
  541                         i->i_hpfs_dno = down;
  542                         for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, (loff_t) 12);
  543                         return;
  544                 }
  545                 if (!(dnode = hpfs_map_dnode(i->i_sb, up, &qbh))) return;
  546                 p = 1;
  547                 de_end = dnode_end_de(dnode);
  548                 for (de = dnode_first_de(dnode); de < de_end; de = de_next_de(de), p++)
  549                         if (de->down) if (de_down_pointer(de) == dno) goto fnd;
  550                 hpfs_error(i->i_sb, "delete_empty_dnode: pointer to dnode %08x not found in dnode %08x", dno, up);
  551                 goto end;
  552                 fnd:
  553                 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, ((loff_t)up << 4) | p);
  554                 if (!down) {
  555                         de->down = 0;
  556                         de->length -= 4;
  557                         dnode->first_free -= 4;
  558                         memmove(de_next_de(de), (char *)de_next_de(de) + 4,
  559                                 (char *)dnode + dnode->first_free - (char *)de_next_de(de));
  560                 } else {
  561                         struct dnode *d1;
  562                         struct quad_buffer_head qbh1;
  563                         *(dnode_secno *) ((void *) de + de->length - 4) = down;
  564                         if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) {
  565                                 d1->up = up;
  566                                 hpfs_mark_4buffers_dirty(&qbh1);
  567                                 hpfs_brelse4(&qbh1);
  568                         }
  569                 }
  570         } else {
  571                 hpfs_error(i->i_sb, "delete_empty_dnode: dnode %08x, first_free == %03x", dno, dnode->first_free);
  572                 goto end;
  573         }
  574 
  575         if (!de->last) {
  576                 struct hpfs_dirent *de_next = de_next_de(de);
  577                 struct hpfs_dirent *de_cp;
  578                 struct dnode *d1;
  579                 struct quad_buffer_head qbh1;
  580                 if (!de_next->down) goto endm;
  581                 ndown = de_down_pointer(de_next);
  582                 if (!(de_cp = kmalloc(de->length, GFP_KERNEL))) {
  583                         printk("HPFS: out of memory for dtree balancing\n");
  584                         goto endm;
  585                 }
  586                 memcpy(de_cp, de, de->length);
  587                 hpfs_delete_de(i->i_sb, dnode, de);
  588                 hpfs_mark_4buffers_dirty(&qbh);
  589                 hpfs_brelse4(&qbh);
  590                 for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | p, 4);
  591                 for_all_poss(i, hpfs_pos_del, ((loff_t)up << 4) | p, 1);
  592                 if (de_cp->down) if ((d1 = hpfs_map_dnode(i->i_sb, de_down_pointer(de_cp), &qbh1))) {
  593                         d1->up = ndown;
  594                         hpfs_mark_4buffers_dirty(&qbh1);
  595                         hpfs_brelse4(&qbh1);
  596                 }
  597                 hpfs_add_to_dnode(i, ndown, de_cp->name, de_cp->namelen, de_cp, de_cp->down ? de_down_pointer(de_cp) : 0);
  598                 /*printk("UP-TO-DNODE: %08x (ndown = %08x, down = %08x, dno = %08x)\n", up, ndown, down, dno);*/
  599                 dno = up;
  600                 kfree(de_cp);
  601                 goto try_it_again;
  602         } else {
  603                 struct hpfs_dirent *de_prev = dnode_pre_last_de(dnode);
  604                 struct hpfs_dirent *de_cp;
  605                 struct dnode *d1;
  606                 struct quad_buffer_head qbh1;
  607                 dnode_secno dlp;
  608                 if (!de_prev) {
  609                         hpfs_error(i->i_sb, "delete_empty_dnode: empty dnode %08x", up);
  610                         hpfs_mark_4buffers_dirty(&qbh);
  611                         hpfs_brelse4(&qbh);
  612                         dno = up;
  613                         goto try_it_again;
  614                 }
  615                 if (!de_prev->down) goto endm;
  616                 ndown = de_down_pointer(de_prev);
  617                 if ((d1 = hpfs_map_dnode(i->i_sb, ndown, &qbh1))) {
  618                         struct hpfs_dirent *del = dnode_last_de(d1);
  619                         dlp = del->down ? de_down_pointer(del) : 0;
  620                         if (!dlp && down) {
  621                                 if (d1->first_free > 2044) {
  622                                         if (i->i_sb->s_hpfs_chk >= 2) {
  623                                                 printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n");
  624                                                 printk("HPFS: warning: terminating balancing operation\n");
  625                                         }
  626                                         hpfs_brelse4(&qbh1);
  627                                         goto endm;
  628                                 }
  629                                 if (i->i_sb->s_hpfs_chk >= 2) {
  630                                         printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n");
  631                                         printk("HPFS: warning: goin'on\n");
  632                                 }
  633                                 del->length += 4;
  634                                 del->down = 1;
  635                                 d1->first_free += 4;
  636                         }
  637                         if (dlp && !down) {
  638                                 del->length -= 4;
  639                                 del->down = 0;
  640                                 d1->first_free -= 4;
  641                         } else if (down)
  642                                 *(dnode_secno *) ((void *) del + del->length - 4) = down;
  643                 } else goto endm;
  644                 if (!(de_cp = kmalloc(de_prev->length, GFP_KERNEL))) {
  645                         printk("HPFS: out of memory for dtree balancing\n");
  646                         hpfs_brelse4(&qbh1);
  647                         goto endm;
  648                 }
  649                 hpfs_mark_4buffers_dirty(&qbh1);
  650                 hpfs_brelse4(&qbh1);
  651                 memcpy(de_cp, de_prev, de_prev->length);
  652                 hpfs_delete_de(i->i_sb, dnode, de_prev);
  653                 if (!de_prev->down) {
  654                         de_prev->length += 4;
  655                         de_prev->down = 1;
  656                         dnode->first_free += 4;
  657                 }
  658                 *(dnode_secno *) ((void *) de_prev + de_prev->length - 4) = ndown;
  659                 hpfs_mark_4buffers_dirty(&qbh);
  660                 hpfs_brelse4(&qbh);
  661                 for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | (p - 1), 4);
  662                 for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | p, ((loff_t)up << 4) | (p - 1));
  663                 if (down) if ((d1 = hpfs_map_dnode(i->i_sb, de_down_pointer(de), &qbh1))) {
  664                         d1->up = ndown;
  665                         hpfs_mark_4buffers_dirty(&qbh1);
  666                         hpfs_brelse4(&qbh1);
  667                 }
  668                 hpfs_add_to_dnode(i, ndown, de_cp->name, de_cp->namelen, de_cp, dlp);
  669                 dno = up;
  670                 kfree(de_cp);
  671                 goto try_it_again;
  672         }
  673         endm:
  674         hpfs_mark_4buffers_dirty(&qbh);
  675         end:
  676         hpfs_brelse4(&qbh);
  677 }
  678 
  679 
  680 /* Delete dirent from directory */
  681 
  682 int hpfs_remove_dirent(struct inode *i, dnode_secno dno, struct hpfs_dirent *de,
  683                        struct quad_buffer_head *qbh, int depth)
  684 {
  685         struct dnode *dnode = qbh->data;
  686         dnode_secno down = 0;
  687         int lock = 0;
  688         loff_t t;
  689         if (de->first || de->last) {
  690                 hpfs_error(i->i_sb, "hpfs_remove_dirent: attempt to delete first or last dirent in dnode %08x", dno);
  691                 hpfs_brelse4(qbh);
  692                 return 1;
  693         }
  694         if (de->down) down = de_down_pointer(de);
  695         if (depth && (de->down || (de == dnode_first_de(dnode) && de_next_de(de)->last))) {
  696                 lock = 1;
  697                 hpfs_lock_creation(i->i_sb);
  698                 if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_DEL)) {
  699                         hpfs_brelse4(qbh);
  700                         hpfs_unlock_creation(i->i_sb);
  701                         return 2;
  702                 }
  703         }
  704         i->i_version = ++event;
  705         for_all_poss(i, hpfs_pos_del, (t = get_pos(dnode, de)) + 1, 1);
  706         hpfs_delete_de(i->i_sb, dnode, de);
  707         hpfs_mark_4buffers_dirty(qbh);
  708         hpfs_brelse4(qbh);
  709         if (down) {
  710                 dnode_secno a = move_to_top(i, down, dno);
  711                 for_all_poss(i, hpfs_pos_subst, 5, t);
  712                 if (a) delete_empty_dnode(i, a);
  713                 if (lock) hpfs_unlock_creation(i->i_sb);
  714                 return !a;
  715         }
  716         delete_empty_dnode(i, dno);
  717         if (lock) hpfs_unlock_creation(i->i_sb);
  718         return 0;
  719 }
  720 
  721 void hpfs_count_dnodes(struct super_block *s, dnode_secno dno, int *n_dnodes,
  722                        int *n_subdirs, int *n_items)
  723 {
  724         struct dnode *dnode;
  725         struct quad_buffer_head qbh;
  726         struct hpfs_dirent *de;
  727         dnode_secno ptr, odno = 0;
  728         int c1, c2 = 0;
  729         int d1, d2 = 0;
  730         go_down:
  731         if (n_dnodes) (*n_dnodes)++;
  732         if (s->s_hpfs_chk)
  733                 if (hpfs_stop_cycles(s, dno, &c1, &c2, "hpfs_count_dnodes #1")) return;
  734         ptr = 0;
  735         go_up:
  736         if (!(dnode = hpfs_map_dnode(s, dno, &qbh))) return;
  737         if (s->s_hpfs_chk) if (odno && odno != -1 && dnode->up != odno)
  738                 hpfs_error(s, "hpfs_count_dnodes: bad up pointer; dnode %08x, down %08x points to %08x", odno, dno, dnode->up);
  739         de = dnode_first_de(dnode);
  740         if (ptr) while(1) {
  741                 if (de->down) if (de_down_pointer(de) == ptr) goto process_de;
  742                 if (de->last) {
  743                         hpfs_brelse4(&qbh);
  744                         hpfs_error(s, "hpfs_count_dnodes: pointer to dnode %08x not found in dnode %08x, got here from %08x",
  745                                 ptr, dno, odno);
  746                         return;
  747                 }
  748                 de = de_next_de(de);
  749         }
  750         next_de:
  751         if (de->down) {
  752                 odno = dno;
  753                 dno = de_down_pointer(de);
  754                 hpfs_brelse4(&qbh);
  755                 goto go_down;
  756         }
  757         process_de:
  758         if (!de->first && !de->last && de->directory && n_subdirs) (*n_subdirs)++;
  759         if (!de->first && !de->last && n_items) (*n_items)++;
  760         if ((de = de_next_de(de)) < dnode_end_de(dnode)) goto next_de;
  761         ptr = dno;
  762         dno = dnode->up;
  763         if (dnode->root_dnode) {
  764                 hpfs_brelse4(&qbh);
  765                 return;
  766         }
  767         hpfs_brelse4(&qbh);
  768         if (s->s_hpfs_chk)
  769                 if (hpfs_stop_cycles(s, ptr, &d1, &d2, "hpfs_count_dnodes #2")) return;
  770         odno = -1;
  771         goto go_up;
  772 }
  773 
  774 static struct hpfs_dirent *map_nth_dirent(struct super_block *s, dnode_secno dno, int n,
  775                                           struct quad_buffer_head *qbh, struct dnode **dn)
  776 {
  777         int i;
  778         struct hpfs_dirent *de, *de_end;
  779         struct dnode *dnode;
  780         dnode = hpfs_map_dnode(s, dno, qbh);
  781         if (!dnode) return NULL;
  782         if (dn) *dn=dnode;
  783         de = dnode_first_de(dnode);
  784         de_end = dnode_end_de(dnode);
  785         for (i = 1; de < de_end; i++, de = de_next_de(de)) {
  786                 if (i == n) {
  787                         return de;
  788                 }       
  789                 if (de->last) break;
  790         }
  791         hpfs_brelse4(qbh);
  792         hpfs_error(s, "map_nth_dirent: n too high; dnode = %08x, requested %08x", dno, n);
  793         return NULL;
  794 }
  795 
  796 dnode_secno hpfs_de_as_down_as_possible(struct super_block *s, dnode_secno dno)
  797 {
  798         struct quad_buffer_head qbh;
  799         dnode_secno d = dno;
  800         dnode_secno up = 0;
  801         struct hpfs_dirent *de;
  802         int c1, c2 = 0;
  803 
  804         again:
  805         if (s->s_hpfs_chk)
  806                 if (hpfs_stop_cycles(s, d, &c1, &c2, "hpfs_de_as_down_as_possible"))
  807                         return d;
  808         if (!(de = map_nth_dirent(s, d, 1, &qbh, NULL))) return dno;
  809         if (s->s_hpfs_chk)
  810                 if (up && ((struct dnode *)qbh.data)->up != up)
  811                         hpfs_error(s, "hpfs_de_as_down_as_possible: bad up pointer; dnode %08x, down %08x points to %08x", up, d, ((struct dnode *)qbh.data)->up);
  812         if (!de->down) {
  813                 hpfs_brelse4(&qbh);
  814                 return d;
  815         }
  816         up = d;
  817         d = de_down_pointer(de);
  818         hpfs_brelse4(&qbh);
  819         goto again;
  820 }
  821 
  822 struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp,
  823                                    struct quad_buffer_head *qbh)
  824 {
  825         loff_t pos;
  826         unsigned c;
  827         dnode_secno dno;
  828         struct hpfs_dirent *de, *d;
  829         struct hpfs_dirent *up_de;
  830         struct hpfs_dirent *end_up_de;
  831         struct dnode *dnode;
  832         struct dnode *up_dnode;
  833         struct quad_buffer_head qbh0;
  834 
  835         pos = *posp;
  836         dno = pos >> 6 << 2;
  837         pos &= 077;
  838         if (!(de = map_nth_dirent(inode->i_sb, dno, pos, qbh, &dnode)))
  839                 goto bail;
  840 
  841         /* Going to the next dirent */
  842         if ((d = de_next_de(de)) < dnode_end_de(dnode)) {
  843                 if (!(++*posp & 077)) {
  844                         hpfs_error(inode->i_sb, "map_pos_dirent: pos crossed dnode boundary; pos = %08x", *posp);
  845                         goto bail;
  846                 }
  847                 /* We're going down the tree */
  848                 if (d->down) {
  849                         *posp = ((loff_t) hpfs_de_as_down_as_possible(inode->i_sb, de_down_pointer(d)) << 4) + 1;
  850                 }
  851         
  852                 return de;
  853         }
  854 
  855         /* Going up */
  856         if (dnode->root_dnode) goto bail;
  857 
  858         if (!(up_dnode = hpfs_map_dnode(inode->i_sb, dnode->up, &qbh0)))
  859                 goto bail;
  860 
  861         end_up_de = dnode_end_de(up_dnode);
  862         c = 0;
  863         for (up_de = dnode_first_de(up_dnode); up_de < end_up_de;
  864              up_de = de_next_de(up_de)) {
  865                 if (!(++c & 077)) hpfs_error(inode->i_sb,
  866                         "map_pos_dirent: pos crossed dnode boundary; dnode = %08x", dnode->up);
  867                 if (up_de->down && de_down_pointer(up_de) == dno) {
  868                         *posp = ((loff_t) dnode->up << 4) + c;
  869                         hpfs_brelse4(&qbh0);
  870                         return de;
  871                 }
  872         }
  873         
  874         hpfs_error(inode->i_sb, "map_pos_dirent: pointer to dnode %08x not found in parent dnode %08x",
  875                 dno, dnode->up);
  876         hpfs_brelse4(&qbh0);
  877         
  878         bail:
  879         *posp = 12;
  880         return de;
  881 }
  882 
  883 /* Find a dirent in tree */
  884 
  885 struct hpfs_dirent *map_dirent(struct inode *inode, dnode_secno dno, char *name, unsigned len,
  886                                dnode_secno *dd, struct quad_buffer_head *qbh)
  887 {
  888         struct dnode *dnode;
  889         struct hpfs_dirent *de;
  890         struct hpfs_dirent *de_end;
  891         int c1, c2 = 0;
  892 
  893         if (!S_ISDIR(inode->i_mode)) hpfs_error(inode->i_sb, "map_dirent: not a directory\n");
  894         again:
  895         if (inode->i_sb->s_hpfs_chk)
  896                 if (hpfs_stop_cycles(inode->i_sb, dno, &c1, &c2, "map_dirent")) return NULL;
  897         if (!(dnode = hpfs_map_dnode(inode->i_sb, dno, qbh))) return NULL;
  898         
  899         de_end = dnode_end_de(dnode);
  900         for (de = dnode_first_de(dnode); de < de_end; de = de_next_de(de)) {
  901                 int t = hpfs_compare_names(inode->i_sb, name, len, de->name, de->namelen, de->last);
  902                 if (!t) {
  903                         if (dd) *dd = dno;
  904                         return de;
  905                 }
  906                 if (t < 0) {
  907                         if (de->down) {
  908                                 dno = de_down_pointer(de);
  909                                 hpfs_brelse4(qbh);
  910                                 goto again;
  911                         }
  912                 break;
  913                 }
  914         }
  915         hpfs_brelse4(qbh);
  916         return NULL;
  917 }
  918 
  919 /*
  920  * Remove empty directory. In normal cases it is only one dnode with two
  921  * entries, but we must handle also such obscure cases when it's a tree
  922  * of empty dnodes.
  923  */
  924 
  925 void hpfs_remove_dtree(struct super_block *s, dnode_secno dno)
  926 {
  927         struct quad_buffer_head qbh;
  928         struct dnode *dnode;
  929         struct hpfs_dirent *de;
  930         dnode_secno d1, d2, rdno = dno;
  931         while (1) {
  932                 if (!(dnode = hpfs_map_dnode(s, dno, &qbh))) return;
  933                 de = dnode_first_de(dnode);
  934                 if (de->last) {
  935                         if (de->down) d1 = de_down_pointer(de);
  936                         else goto error;
  937                         hpfs_brelse4(&qbh);
  938                         hpfs_free_dnode(s, dno);
  939                         dno = d1;
  940                 } else break;
  941         }
  942         if (!de->first) goto error;
  943         d1 = de->down ? de_down_pointer(de) : 0;
  944         de = de_next_de(de);
  945         if (!de->last) goto error;
  946         d2 = de->down ? de_down_pointer(de) : 0;
  947         hpfs_brelse4(&qbh);
  948         hpfs_free_dnode(s, dno);
  949         do {
  950                 while (d1) {
  951                         if (!(dnode = hpfs_map_dnode(s, dno = d1, &qbh))) return;
  952                         de = dnode_first_de(dnode);
  953                         if (!de->last) goto error;
  954                         d1 = de->down ? de_down_pointer(de) : 0;
  955                         hpfs_brelse4(&qbh);
  956                         hpfs_free_dnode(s, dno);
  957                 }
  958                 d1 = d2;
  959                 d2 = 0;
  960         } while (d1);
  961         return;
  962         error:
  963         hpfs_brelse4(&qbh);
  964         hpfs_free_dnode(s, dno);
  965         hpfs_error(s, "directory %08x is corrupted or not empty", rdno);
  966 }
  967 
  968 /* 
  969  * Find dirent for specified fnode. Use truncated 15-char name in fnode as
  970  * a help for searching.
  971  */
  972 
  973 struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno,
  974                                      struct fnode *f, struct quad_buffer_head *qbh)
  975 {
  976         char *name1;
  977         char *name2;
  978         int name1len, name2len;
  979         struct dnode *d;
  980         dnode_secno dno, downd;
  981         struct fnode *upf;
  982         struct buffer_head *bh;
  983         struct hpfs_dirent *de, *de_end;
  984         int c;
  985         int c1, c2 = 0;
  986         int d1, d2 = 0;
  987         name1 = f->name;
  988         if (!(name2 = kmalloc(256, GFP_KERNEL))) {
  989                 printk("HPFS: out of memory, can't map dirent\n");
  990                 return NULL;
  991         }
  992         if (f->len <= 15)
  993                 memcpy(name2, name1, name1len = name2len = f->len);
  994         else {
  995                 memcpy(name2, name1, 15);
  996                 memset(name2 + 15, 0xff, 256 - 15);
  997                 /*name2[15] = 0xff;*/
  998                 name1len = 15; name2len = 256;
  999         }
 1000         if (!(upf = hpfs_map_fnode(s, f->up, &bh))) {
 1001                 kfree(name2);
 1002                 return NULL;
 1003         }       
 1004         if (!upf->dirflag) {
 1005                 brelse(bh);
 1006                 hpfs_error(s, "fnode %08x has non-directory parent %08x", fno, f->up);
 1007                 kfree(name2);
 1008                 return NULL;
 1009         }
 1010         dno = upf->u.external[0].disk_secno;
 1011         brelse(bh);
 1012         go_down:
 1013         downd = 0;
 1014         go_up:
 1015         if (!(d = hpfs_map_dnode(s, dno, qbh))) {
 1016                 kfree(name2);
 1017                 return NULL;
 1018         }
 1019         de_end = dnode_end_de(d);
 1020         de = dnode_first_de(d);
 1021         if (downd) {
 1022                 while (de < de_end) {
 1023                         if (de->down) if (de_down_pointer(de) == downd) goto f;
 1024                         de = de_next_de(de);
 1025                 }
 1026                 hpfs_error(s, "pointer to dnode %08x not found in dnode %08x", downd, dno);
 1027                 hpfs_brelse4(qbh);
 1028                 kfree(name2);
 1029                 return NULL;
 1030         }
 1031         next_de:
 1032         if (de->fnode == fno) {
 1033                 kfree(name2);
 1034                 return de;
 1035         }
 1036         c = hpfs_compare_names(s, name1, name1len, de->name, de->namelen, de->last);
 1037         if (c < 0 && de->down) {
 1038                 dno = de_down_pointer(de);
 1039                 hpfs_brelse4(qbh);
 1040                 if (s->s_hpfs_chk)
 1041                         if (hpfs_stop_cycles(s, dno, &c1, &c2, "map_fnode_dirent #1")) {
 1042                         kfree(name2);
 1043                         return NULL;
 1044                 }
 1045                 goto go_down;
 1046         }
 1047         f:
 1048         if (de->fnode == fno) {
 1049                 kfree(name2);
 1050                 return de;
 1051         }
 1052         c = hpfs_compare_names(s, name2, name2len, de->name, de->namelen, de->last);
 1053         if (c < 0 && !de->last) goto not_found;
 1054         if ((de = de_next_de(de)) < de_end) goto next_de;
 1055         if (d->root_dnode) goto not_found;
 1056         downd = dno;
 1057         dno = d->up;
 1058         hpfs_brelse4(qbh);
 1059         if (s->s_hpfs_chk)
 1060                 if (hpfs_stop_cycles(s, downd, &d1, &d2, "map_fnode_dirent #2")) {
 1061                         kfree(name2);
 1062                         return NULL;
 1063                 }
 1064         goto go_up;
 1065         not_found:
 1066         hpfs_brelse4(qbh);
 1067         hpfs_error(s, "dirent for fnode %08x not found", fno);
 1068         kfree(name2);
 1069         return NULL;
 1070 }

Cache object: 90b6037a464bbf4d53345115d0f20d2e


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