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/hpfs_subr.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  * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD$
   27  */
   28 
   29 #include <sys/param.h>
   30 #include <sys/systm.h>
   31 #include <sys/kernel.h>
   32 #include <sys/proc.h>
   33 #include <sys/time.h>
   34 #include <sys/types.h>
   35 #include <sys/stat.h>
   36 #include <sys/vnode.h>
   37 #include <sys/mount.h>
   38 #include <sys/namei.h>
   39 #include <sys/malloc.h>
   40 #include <sys/buf.h>
   41 
   42 #include <fs/hpfs/hpfs.h>
   43 #include <fs/hpfs/hpfsmount.h>
   44 #include <fs/hpfs/hpfs_subr.h>
   45 
   46 u_long
   47 hpfs_checksum(
   48         u_int8_t *object,
   49         int size)
   50 {
   51         register int i;
   52         u_long csum=0L;
   53         for (i=0; i < size; i++) {
   54                 csum += (u_long) *object++;
   55                 csum = (csum << 7) + (csum >> (25));
   56         }
   57         return (csum);
   58 }
   59 
   60 void
   61 hpfs_bmdeinit(
   62         struct hpfsmount *hpmp)
   63 {
   64         struct buf *bp;
   65         int i;
   66 
   67         dprintf(("hpmp_bmdeinit: "));
   68 
   69         if (!(hpmp->hpm_mp->mnt_flag & MNT_RDONLY)) {
   70                 /*
   71                  * Write down BitMap.
   72                  */
   73                 for (i=0; i<hpmp->hpm_dbnum; i++) {
   74                         dprintf(("[%d: 0x%x] ", i, hpmp->hpm_bmind[i]));
   75 
   76                         bp = getblk(hpmp->hpm_devvp, hpmp->hpm_bmind[i],
   77                                     BMSIZE, 0, 0);
   78                         clrbuf(bp);
   79 
   80                         bcopy(hpmp->hpm_bitmap + BMSIZE * i, bp->b_data,
   81                               BMSIZE);
   82 
   83                         bwrite(bp);
   84                 }
   85         }
   86 
   87         FREE(hpmp->hpm_bitmap,M_HPFSMNT);
   88         FREE(hpmp->hpm_bmind,M_HPFSMNT);
   89 
   90         dprintf(("\n"));
   91 }
   92 
   93 /*
   94  * Initialize BitMap management, includes calculation of
   95  * available blocks number.
   96  */
   97 int
   98 hpfs_bminit(
   99         struct hpfsmount *hpmp)
  100 {
  101         struct buf *bp;
  102         int error, i, k;
  103         u_long dbavail;
  104 
  105         dprintf(("hpfs_bminit: "));
  106 
  107         hpmp->hpm_dbnum = (hpmp->hpm_su.su_btotal + 0x3FFF) / 0x4000;
  108 
  109         dprintf(("0x%lx data bands, ", hpmp->hpm_dbnum));
  110 
  111         MALLOC(hpmp->hpm_bmind, lsn_t *, hpmp->hpm_dbnum * sizeof(lsn_t),
  112                 M_HPFSMNT, M_WAITOK);
  113 
  114         MALLOC(hpmp->hpm_bitmap, u_int8_t *, hpmp->hpm_dbnum * BMSIZE,
  115                 M_HPFSMNT, M_WAITOK);
  116 
  117         error = bread(hpmp->hpm_devvp, hpmp->hpm_su.su_bitmap.lsn1,
  118                 ((hpmp->hpm_dbnum + 0x7F) & ~(0x7F)) << 2, NOCRED, &bp);
  119         if (error) {
  120                 brelse(bp);
  121                 FREE(hpmp->hpm_bitmap, M_HPFSMNT);
  122                 FREE(hpmp->hpm_bmind, M_HPFSMNT);
  123                 dprintf((" error %d\n", error));
  124                 return (error);
  125         }
  126         bcopy(bp->b_data, hpmp->hpm_bmind, hpmp->hpm_dbnum * sizeof(lsn_t));
  127         
  128         brelse(bp);
  129 
  130         /*
  131          * Read in all BitMap
  132          */
  133         for (i=0; i<hpmp->hpm_dbnum; i++) {
  134                 dprintf(("[%d: 0x%x] ", i, hpmp->hpm_bmind[i]));
  135 
  136                 error = bread(hpmp->hpm_devvp, hpmp->hpm_bmind[i],
  137                                 BMSIZE, NOCRED, &bp);
  138                 if (error) {
  139                         brelse(bp);
  140                         FREE(hpmp->hpm_bitmap, M_HPFSMNT);
  141                         FREE(hpmp->hpm_bmind, M_HPFSMNT);
  142                         dprintf((" error %d\n", error));
  143                         return (error);
  144                 }
  145                 bcopy(bp->b_data, hpmp->hpm_bitmap + BMSIZE * i, BMSIZE);
  146 
  147                 brelse(bp);
  148         }
  149 
  150         /*
  151          * Look througth BitMap and count free bits
  152          */
  153         dbavail = 0;
  154         for (i=0; i < hpmp->hpm_su.su_btotal >> 5; i++) {
  155                 register u_int32_t mask;
  156                 for (k=0, mask=1; k < 32; k++, mask<<=1)
  157                         if(((u_int32_t *)hpmp->hpm_bitmap)[i] & mask) 
  158                                 dbavail ++;
  159 
  160         }
  161         hpmp->hpm_bavail = dbavail;
  162 
  163         return (0);
  164 }
  165 
  166 int
  167 hpfs_cmpfname (
  168         struct hpfsmount *hpmp,
  169         char * uname,
  170         int ulen,
  171         char * dname,
  172         int dlen,
  173         u_int16_t cp)
  174 {
  175         register int i, res;
  176 
  177         for (i = 0; i < ulen && i < dlen; i++) {
  178                 res = hpfs_toupper(hpmp, hpfs_u2d(hpmp, uname[i]), cp) - 
  179                       hpfs_toupper(hpmp, dname[i], cp);
  180                 if (res)
  181                         return res;
  182         }
  183         return (ulen - dlen);
  184 }
  185 
  186 int
  187 hpfs_cpstrnnicmp (
  188         struct hpfsmount *hpmp,
  189         char * str1,
  190         int str1len,
  191         u_int16_t str1cp,
  192         char * str2,
  193         int str2len,
  194         u_int16_t str2cp)
  195 {
  196         int i, res;
  197 
  198         for (i = 0; i < str1len && i < str2len; i++) {
  199                 res = (int)hpfs_toupper(hpmp, ((u_char *)str1)[i], str1cp) - 
  200                       (int)hpfs_toupper(hpmp, ((u_char *)str2)[i], str2cp);
  201                 if (res)
  202                         return res;
  203         }
  204         return (str1len - str2len);
  205 }
  206 
  207 
  208 int
  209 hpfs_cpload (
  210         struct hpfsmount *hpmp,
  211         struct cpiblk *cpibp,
  212         struct cpdblk *cpdbp)
  213 {
  214         struct buf *bp;
  215         struct cpdsec * cpdsp;
  216         int error, i;
  217 
  218         error = bread(hpmp->hpm_devvp, cpibp->b_cpdsec, DEV_BSIZE, NOCRED, &bp);
  219         if (error) {
  220                 brelse(bp);
  221                 return (error);
  222         }
  223 
  224         cpdsp = (struct cpdsec *)bp->b_data;
  225 
  226         for (i=cpdsp->d_cpfirst; i<cpdsp->d_cpcnt; i++) {
  227                 if (cpdsp->d_cpdblk[i].b_cpid == cpibp->b_cpid) {
  228                         bcopy(cpdsp->d_cpdblk + i, cpdbp, 
  229                               sizeof(struct cpdblk));
  230 
  231                         brelse(bp);
  232 
  233                         return (0);
  234                 }
  235         }
  236 
  237         brelse(bp);
  238 
  239         return (ENOENT);
  240 }
  241 
  242 
  243 /*
  244  * Initialize Code Page information management.
  245  * Load all copdepages in memory.
  246  */
  247 int
  248 hpfs_cpinit (
  249         struct hpfsmount *hpmp,
  250         struct hpfs_args *argsp)
  251 {
  252         struct buf *bp;
  253         int error, i;
  254         lsn_t lsn;
  255         int cpicnt;
  256         struct cpisec * cpisp;
  257         struct cpiblk * cpibp;
  258         struct cpdblk * cpdbp;
  259 
  260         dprintf(("hpfs_cpinit: \n"));
  261 
  262         if (argsp->flags & HPFSMNT_TABLES) {
  263                 bcopy(argsp->d2u, hpmp->hpm_d2u, sizeof(u_char) * 0x80);
  264                 bcopy(argsp->u2d, hpmp->hpm_u2d, sizeof(u_char) * 0x80);
  265         } else {
  266                 for (i=0x0; i<0x80;i++) {
  267                         hpmp->hpm_d2u[i] = i + 0x80;
  268                         hpmp->hpm_u2d[i] = i + 0x80;
  269                 }
  270         }
  271 
  272         cpicnt = hpmp->hpm_sp.sp_cpinum;
  273 
  274         MALLOC(hpmp->hpm_cpdblk, struct cpdblk *,       
  275                 cpicnt * sizeof(struct cpdblk), M_HPFSMNT, M_WAITOK);
  276 
  277         cpdbp = hpmp->hpm_cpdblk;
  278         lsn = hpmp->hpm_sp.sp_cpi;
  279 
  280         while (cpicnt > 0) {
  281                 error = bread(hpmp->hpm_devvp, lsn, DEV_BSIZE, NOCRED, &bp);
  282                 if (error) {
  283                         brelse(bp);
  284                         return (error);
  285                 }
  286 
  287                 cpisp = (struct cpisec *)bp->b_data;
  288 
  289                 cpibp = cpisp->s_cpi;
  290                 for (i=0; i<cpisp->s_cpicnt; i++, cpicnt --, cpdbp++, cpibp++) {
  291                         dprintf(("hpfs_cpinit: Country: %d, CP: %d (%d)\n",
  292                                  cpibp->b_country, cpibp->b_cpid, 
  293                                  cpibp->b_vcpid));
  294 
  295                         error = hpfs_cpload(hpmp, cpibp, cpdbp);
  296                         if (error) {
  297                                 brelse(bp);
  298                                 return (error);
  299                         }
  300                 }
  301                 lsn = cpisp->s_next;
  302                 brelse(bp);
  303         }
  304 
  305         return (0);
  306 }
  307 
  308 int
  309 hpfs_cpdeinit (
  310         struct hpfsmount *hpmp)
  311 {
  312         dprintf(("hpmp_cpdeinit: "));
  313         FREE(hpmp->hpm_cpdblk,M_HPFSMNT);
  314         return (0);
  315 }
  316 
  317 /*
  318  * Lookup for a run of blocks.
  319  */
  320 int
  321 hpfs_bmlookup (
  322         struct hpfsmount *hpmp,
  323         u_long flags,   /* 1 means we want right len blocks in run, not less */
  324         lsn_t lsn,              /* We want near this one */
  325         u_long len,             /* We want such long */
  326         lsn_t *lsnp,    /* We got here */
  327         u_long *lenp)   /* We got this long */
  328 {
  329         u_int32_t * bitmap;
  330         register u_int32_t mask;
  331         int i,k;
  332         int cband, vcband;
  333         u_int bandsz;
  334         int count;
  335 
  336         dprintf(("hpfs_bmlookup: lsn: 0x%x, len 0x%lx | Step1\n", lsn, len));
  337 
  338         if (lsn > hpmp->hpm_su.su_btotal) {
  339                 printf("hpfs_bmlookup: OUT OF VOLUME\n");
  340                 return ENOSPC;
  341         }
  342         if (len > hpmp->hpm_bavail) {
  343                 printf("hpfs_bmlookup: OUT OF SPACE\n");
  344                 return ENOSPC;
  345         }
  346         i = lsn >> 5;
  347         k = lsn & 0x1F;
  348         mask = 1 << k;
  349         bitmap = (u_int32_t *)hpmp->hpm_bitmap + i;
  350 
  351         if (*bitmap & mask) {
  352                 *lsnp = lsn;
  353                 *lenp = 0;
  354                 for (; k < 32; k++, mask<<=1) {
  355                         if (*bitmap & mask)
  356                                 (*lenp) ++;
  357                         else {
  358                                 if (flags & 1)
  359                                         goto step2;
  360                                 else 
  361                                         return (0);
  362                         }
  363 
  364                         if (*lenp == len)
  365                                 return (0);
  366                 }
  367 
  368                 bitmap++;
  369                 i++;
  370                 for (; i < hpmp->hpm_su.su_btotal >> 5; i++, bitmap++) {
  371                         for (k=0, mask=1; k < 32; k++, mask<<=1) {
  372                                 if (*bitmap & mask)
  373                                         (*lenp) ++;
  374                                 else {
  375                                         if (flags & 1)
  376                                                 goto step2;
  377                                         else 
  378                                                 return (0);
  379                                 }
  380 
  381                                 if (*lenp == len)
  382                                         return (0);
  383                         }
  384                 }
  385                 return (0);
  386         }
  387 
  388 step2:
  389         /*
  390          * Lookup all bands begining from cband, lookup for first block
  391          */
  392         cband = (lsn >> 14);
  393         dprintf(("hpfs_bmlookup: Step2: band 0x%x (0x%lx)\n",
  394                  cband, hpmp->hpm_dbnum));
  395         for (vcband = 0; vcband < hpmp->hpm_dbnum; vcband ++, cband++) {
  396                 cband = cband % hpmp->hpm_dbnum;
  397                 bandsz = min (hpmp->hpm_su.su_btotal - (cband << 14), 0x4000);
  398                 dprintf(("hpfs_bmlookup: band: %d, sz: 0x%x\n", cband, bandsz));
  399 
  400                 bitmap = (u_int32_t *)hpmp->hpm_bitmap + (cband << 9);
  401                 *lsnp = cband << 14;
  402                 *lenp = 0;
  403                 count = 0;
  404                 for (i=0; i < bandsz >> 5; i++, bitmap++) {
  405                         for (k=0, mask=1; k < 32; k++, mask<<=1) {
  406                                 if (*bitmap & mask) {
  407                                         if (count) {
  408                                                 (*lenp) ++;
  409                                         } else {
  410                                                 count = 1;
  411                                                 *lsnp = (cband << 14) + (i << 5) + k;
  412                                                 *lenp = 1;
  413                                         }
  414                                 } else {
  415                                         if ((*lenp) && !(flags & 1)) {
  416                                                 return (0);
  417                                         } else {
  418                                                 count = 0;
  419                                         }
  420                                 }
  421 
  422                                 if (*lenp == len)
  423                                         return (0);
  424                         }
  425                 }
  426                 if (cband == hpmp->hpm_dbnum - 1)  {
  427                         if ((*lenp) && !(flags & 1)) {
  428                                 return (0);
  429                         } else {
  430                                 count = 0;
  431                         }
  432                 }
  433         }
  434 
  435         return (ENOSPC);
  436 }
  437 
  438 /*
  439  * Lookup a single free block.  XXX Need locking on BitMap operations
  440  * VERY STUPID ROUTINE!!!
  441  */
  442 int
  443 hpfs_bmfblookup (
  444         struct hpfsmount *hpmp,
  445         lsn_t *lp)
  446 {
  447         u_int32_t * bitmap;
  448         int i,k;
  449 
  450         dprintf(("hpfs_bmfblookup: "));
  451 
  452         bitmap = (u_int32_t *)hpmp->hpm_bitmap;
  453         for (i=0; i < hpmp->hpm_su.su_btotal >> 5; i++, bitmap++) {
  454                 k = ffs(*bitmap);
  455                 if (k) {
  456                         *lp = (i << 5) + k - 1;
  457                         dprintf((" found: 0x%x\n",*lp));
  458                         return (0);
  459                 }
  460         }
  461 
  462         return (ENOSPC);
  463 }
  464 
  465 /*
  466  * Mark contignous block of blocks.
  467  */
  468 int
  469 hpfs_bmmark (
  470         struct hpfsmount *hpmp,
  471         lsn_t bn,
  472         u_long bl,
  473         int state)
  474 {
  475         u_int32_t * bitmap;
  476         int i, didprint = 0;
  477 
  478         dprintf(("hpfs_bmmark(0x%x, 0x%lx, %d): \n",bn,bl, state));
  479 
  480         if ((bn > hpmp->hpm_su.su_btotal) || (bn+bl > hpmp->hpm_su.su_btotal)) {
  481                 printf("hpfs_bmmark: MARKING OUT OF VOLUME\n");
  482                 return 0;
  483         }
  484         bitmap = (u_int32_t *)hpmp->hpm_bitmap;
  485         bitmap += bn >> 5;
  486 
  487         while (bl > 0) {
  488                 for (i = bn & 0x1F; (i < 0x20) && (bl > 0) ; i++, bl--) {
  489                         if (state) {
  490                                 if ( *bitmap & (1 << i)) {
  491                                         if (!didprint) {
  492                                                 printf("hpfs_bmmark: ALREADY FREE\n");
  493                                                 didprint = 1;
  494                                         }
  495                                 } else 
  496                                         hpmp->hpm_bavail++;
  497 
  498                                 *bitmap |= (1 << i);
  499                         } else {
  500                                 if ((~(*bitmap)) & (1 << i)) {
  501                                         if (!didprint) {
  502                                                 printf("hpfs_bmmark: ALREADY BUSY\n");
  503                                                 didprint = 1;
  504                                         }
  505                                 } else 
  506                                         hpmp->hpm_bavail--;
  507 
  508                                 *bitmap &= ~(1 << i);
  509                         }
  510                 }
  511                 bn = 0;
  512                 bitmap++;
  513         }
  514 
  515         return (0);
  516 }
  517 
  518 
  519 int
  520 hpfs_validateparent (
  521         struct hpfsnode *hp)
  522 {
  523         struct hpfsnode *dhp;
  524         struct vnode *dvp;
  525         struct hpfsmount *hpmp = hp->h_hpmp;
  526         struct buf *bp;
  527         struct dirblk *dp;
  528         struct hpfsdirent *dep;
  529         lsn_t lsn, olsn;
  530         int level, error;
  531 
  532         dprintf(("hpfs_validatetimes(0x%x): [parent: 0x%x] ",
  533                 hp->h_no, hp->h_fn.fn_parent));
  534 
  535         if (hp->h_no == hp->h_fn.fn_parent) {
  536                 dhp = hp;
  537         } else {
  538                 error = VFS_VGET(hpmp->hpm_mp, hp->h_fn.fn_parent, &dvp);
  539                 if (error)
  540                         return (error);
  541                 dhp = VTOHP(dvp);
  542         }
  543 
  544         lsn = ((alleaf_t *)dhp->h_fn.fn_abd)->al_lsn;
  545 
  546         olsn = 0;
  547         level = 1;
  548         bp = NULL;
  549 
  550 dive:
  551         dprintf(("[dive 0x%x] ", lsn));
  552         if (bp != NULL)
  553                 brelse(bp);
  554         error = bread(dhp->h_devvp, lsn, D_BSIZE, NOCRED, &bp);
  555         if (error)
  556                 goto failed;
  557 
  558         dp = (struct dirblk *) bp->b_data;
  559         if (dp->d_magic != D_MAGIC) {
  560                 printf("hpfs_validatetimes: magic doesn't match\n");
  561                 error = EINVAL;
  562                 goto failed;
  563         }
  564 
  565         dep = D_DIRENT(dp);
  566 
  567         if (olsn) {
  568                 dprintf(("[restore 0x%x] ", olsn));
  569 
  570                 while(!(dep->de_flag & DE_END) ) {
  571                         if((dep->de_flag & DE_DOWN) &&
  572                            (olsn == DE_DOWNLSN(dep)))
  573                                          break;
  574                         dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
  575                 }
  576 
  577                 if((dep->de_flag & DE_DOWN) && (olsn == DE_DOWNLSN(dep))) {
  578                         if (dep->de_flag & DE_END)
  579                                 goto blockdone;
  580 
  581                         if (hp->h_no == dep->de_fnode) {
  582                                 dprintf(("[found] "));
  583                                 goto readdone;
  584                         }
  585 
  586                         dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
  587                 } else {
  588                         printf("hpfs_validatetimes: ERROR! oLSN not found\n");
  589                         error = EINVAL;
  590                         goto failed;
  591                 }
  592         }
  593 
  594         olsn = 0;
  595 
  596         while(!(dep->de_flag & DE_END)) {
  597                 if(dep->de_flag & DE_DOWN) {
  598                         lsn = DE_DOWNLSN(dep);
  599                         level++;
  600                         goto dive;
  601                 }
  602 
  603                 if (hp->h_no == dep->de_fnode) {
  604                         dprintf(("[found] "));
  605                         goto readdone;
  606                 }
  607 
  608                 dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
  609         }
  610 
  611         if(dep->de_flag & DE_DOWN) {
  612                 dprintf(("[enddive] "));
  613                 lsn = DE_DOWNLSN(dep);
  614                 level++;
  615                 goto dive;
  616         }
  617 
  618 blockdone:
  619         dprintf(("[EOB] "));
  620         olsn = lsn;
  621         lsn = dp->d_parent;
  622         level--;
  623         dprintf(("[level %d] ", level));
  624         if (level > 0)
  625                 goto dive;      /* undive really */
  626 
  627         goto failed;
  628 
  629 readdone:
  630         bcopy(dep->de_name,hp->h_name,dep->de_namelen);
  631         hp->h_name[dep->de_namelen] = '\0';
  632         hp->h_namelen = dep->de_namelen;
  633         hp->h_ctime = dep->de_ctime;
  634         hp->h_atime = dep->de_atime;
  635         hp->h_mtime = dep->de_mtime;
  636         hp->h_flag |= H_PARVALID;
  637 
  638         dprintf(("[readdone]"));
  639 
  640 failed:
  641         dprintf(("\n"));
  642         if (bp != NULL)
  643                 brelse(bp);
  644         if (hp != dhp)
  645                 vput(dvp);
  646 
  647         return (error);
  648 }
  649 
  650 struct timespec
  651 hpfstimetounix (
  652         u_long hptime)
  653 {
  654         struct timespec t;
  655 
  656         t.tv_nsec = 0;
  657         t.tv_sec = hptime;
  658 
  659         return t;
  660 }
  661 
  662 /*
  663  * Write down changes done to parent dir, these are only times for now. 
  664  * hpfsnode have to be locked.
  665  */
  666 int
  667 hpfs_updateparent (
  668         struct hpfsnode *hp)
  669 {
  670         struct hpfsnode *dhp;
  671         struct vnode *dvp;
  672         struct hpfsdirent *dep;
  673         struct buf * bp;
  674         int error;
  675 
  676         dprintf(("hpfs_updateparent(0x%x): \n", hp->h_no));
  677 
  678         if (!(hp->h_flag & H_PARCHANGE))
  679                 return (0);
  680 
  681         if (!(hp->h_flag & H_PARVALID)) {
  682                 error = hpfs_validateparent (hp);
  683                 if (error)
  684                         return (error);
  685         }
  686 
  687         if (hp->h_no == hp->h_fn.fn_parent) {
  688                 dhp = hp;
  689         } else {
  690                 error = VFS_VGET(hp->h_hpmp->hpm_mp, hp->h_fn.fn_parent,
  691                                  &dvp);
  692                 if (error)
  693                         return (error);
  694                 dhp = VTOHP(dvp);
  695         }
  696 
  697         error = hpfs_genlookupbyname (dhp, hp->h_name, hp->h_namelen,
  698                                         &bp, &dep);
  699         if (error) {
  700                 goto failed;
  701         }
  702 
  703         dep->de_atime = hp->h_atime;
  704         dep->de_mtime = hp->h_mtime;
  705         dep->de_size = hp->h_fn.fn_size;
  706 
  707         bdwrite (bp);
  708 
  709         hp->h_flag &= ~H_PARCHANGE;
  710 
  711         error = 0;
  712 failed:
  713         if (hp != dhp)
  714                 vput(dvp);
  715 
  716         return (0);
  717 }
  718 
  719 /*
  720  * Write down on disk changes done to fnode. hpfsnode have to be locked.
  721  */
  722 int
  723 hpfs_update (
  724         struct hpfsnode *hp)
  725 {
  726         struct buf * bp;
  727 
  728         dprintf(("hpfs_update(0x%x): \n", hp->h_no));
  729 
  730         if (!(hp->h_flag & H_CHANGE))
  731                 return (0);
  732 
  733         bp = getblk(hp->h_devvp, hp->h_no, FNODESIZE, 0, 0);
  734         clrbuf(bp);
  735 
  736         bcopy (&hp->h_fn, bp->b_data, sizeof(struct fnode));
  737         bdwrite (bp);
  738 
  739         hp->h_flag &= ~H_CHANGE;
  740 
  741         if (hp->h_flag & H_PARCHANGE)
  742                 return (hpfs_updateparent(hp));
  743 
  744         return (0);
  745 }
  746 
  747 /*
  748  * Truncate file to specifed size. hpfsnode have to be locked.
  749  */
  750 int
  751 hpfs_truncate (
  752         struct hpfsnode *hp,
  753         u_long size)
  754 {
  755         struct hpfsmount *hpmp = hp->h_hpmp;
  756         lsn_t newblen, oldblen;
  757         int error, pf;
  758 
  759         dprintf(("hpfs_truncate(0x%x, 0x%x -> 0x%lx): ",
  760                 hp->h_no, hp->h_fn.fn_size, size));
  761 
  762         newblen = (size + DEV_BSIZE - 1) >> DEV_BSHIFT;
  763         oldblen = (hp->h_fn.fn_size + DEV_BSIZE - 1) >> DEV_BSHIFT;
  764 
  765         dprintf(("blen: 0x%x -> 0x%x\n", oldblen, newblen));
  766 
  767         error = hpfs_truncatealblk (hpmp, &hp->h_fn.fn_ab, newblen, &pf);
  768         if (error)
  769                 return (error);
  770         if (pf) {
  771                 hp->h_fn.fn_ab.ab_flag = 0;
  772                 hp->h_fn.fn_ab.ab_freecnt = 0x8;
  773                 hp->h_fn.fn_ab.ab_busycnt = 0x0;
  774                 hp->h_fn.fn_ab.ab_freeoff = sizeof(alblk_t);
  775         }
  776 
  777         hp->h_fn.fn_size = size;
  778 
  779         hp->h_flag |= (H_CHANGE | H_PARCHANGE);
  780 
  781         dprintf(("hpfs_truncate: successful\n"));
  782 
  783         return (0);
  784 }
  785 
  786 /*
  787  * Enlarge file to specifed size. hpfsnode have to be locked.
  788  */
  789 int
  790 hpfs_extend (
  791         struct hpfsnode *hp,
  792         u_long size)
  793 {
  794         struct hpfsmount *hpmp = hp->h_hpmp;
  795         lsn_t newblen, oldblen;
  796         int error;
  797 
  798         dprintf(("hpfs_extend(0x%x, 0x%x -> 0x%lx): ",
  799                 hp->h_no, hp->h_fn.fn_size, size));
  800 
  801         if (hpmp->hpm_bavail < 0x10) 
  802                 return (ENOSPC);
  803 
  804         newblen = (size + DEV_BSIZE - 1) >> DEV_BSHIFT;
  805         oldblen = (hp->h_fn.fn_size + DEV_BSIZE - 1) >> DEV_BSHIFT;
  806 
  807         dprintf(("blen: 0x%x -> 0x%x\n", oldblen, newblen));
  808 
  809         error = hpfs_addextent(hpmp, hp, newblen - oldblen);
  810         if (error) {
  811                 printf("hpfs_extend: FAILED TO ADD EXTENT %d\n", error);
  812                 return (error);
  813         }
  814 
  815         hp->h_fn.fn_size = size;
  816 
  817         hp->h_flag |= (H_CHANGE | H_PARCHANGE);
  818 
  819         dprintf(("hpfs_extend: successful\n"));
  820 
  821         return (0);
  822 }
  823 
  824 /*
  825  * Read AlSec structure, and check if magic is valid.
  826  * You don't need to brelse buf on error.
  827  */
  828 int
  829 hpfs_breadstruct (
  830         struct hpfsmount *hpmp,
  831         lsn_t lsn,
  832         u_int len,
  833         u_int32_t magic,
  834         struct buf **bpp)
  835 {
  836         struct buf *bp;
  837         u_int32_t *mp;
  838         int error;
  839 
  840         dprintf(("hpfs_breadstruct: reading at 0x%x\n", lsn));
  841 
  842         *bpp = NULL;
  843 
  844         error = bread(hpmp->hpm_devvp, lsn, len, NOCRED, &bp);
  845         if (error) {
  846                 brelse(bp);
  847                 return (error);
  848         }
  849         mp = (u_int32_t *) bp->b_data;
  850         if (*mp != magic) {
  851                 brelse(bp);
  852                 printf("hpfs_breadstruct: MAGIC DOESN'T MATCH (0x%08x != 0x%08x)\n",
  853                         *mp, magic);
  854                 return (EINVAL);
  855         }
  856 
  857         *bpp = bp;
  858 
  859         return (0);
  860 }
  861 

Cache object: 167c38dd610d83ca63a0eff02ebe74b0


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