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

Cache object: 491721816cda119ca910f9bd28dc4eab


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