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/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, 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         hpmp->hpm_bmind = malloc(hpmp->hpm_dbnum * sizeof(lsn_t),
  113                 M_HPFSMNT, M_WAITOK);
  114 
  115         hpmp->hpm_bitmap = malloc(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 mount *mp,
  251         struct hpfsmount *hpmp)
  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         error = vfs_copyopt(mp->mnt_optnew, "d2u", hpmp->hpm_d2u,
  264             sizeof hpmp->hpm_d2u);
  265         if (error == ENOENT)
  266                 for (i=0x0; i<0x80;i++)
  267                         hpmp->hpm_d2u[i] = i + 0x80;
  268         else if (error)
  269                 return (error);
  270 
  271         error = vfs_copyopt(mp->mnt_optnew, "u2d", hpmp->hpm_u2d,
  272             sizeof hpmp->hpm_u2d);
  273         if (error == ENOENT)
  274                 for (i=0x0; i<0x80;i++)
  275                         hpmp->hpm_u2d[i] = i + 0x80;
  276         else if (error)
  277                 return (error);
  278 
  279         cpicnt = hpmp->hpm_sp.sp_cpinum;
  280 
  281         hpmp->hpm_cpdblk = malloc(cpicnt * sizeof(struct cpdblk),
  282             M_HPFSMNT, M_WAITOK);
  283 
  284         cpdbp = hpmp->hpm_cpdblk;
  285         lsn = hpmp->hpm_sp.sp_cpi;
  286 
  287         while (cpicnt > 0) {
  288                 error = bread(hpmp->hpm_devvp, lsn, DEV_BSIZE, NOCRED, &bp);
  289                 if (error) {
  290                         brelse(bp);
  291                         return (error);
  292                 }
  293 
  294                 cpisp = (struct cpisec *)bp->b_data;
  295 
  296                 cpibp = cpisp->s_cpi;
  297                 for (i=0; i<cpisp->s_cpicnt; i++, cpicnt --, cpdbp++, cpibp++) {
  298                         dprintf(("hpfs_cpinit: Country: %d, CP: %d (%d)\n",
  299                                  cpibp->b_country, cpibp->b_cpid, 
  300                                  cpibp->b_vcpid));
  301 
  302                         error = hpfs_cpload(hpmp, cpibp, cpdbp);
  303                         if (error) {
  304                                 brelse(bp);
  305                                 return (error);
  306                         }
  307                 }
  308                 lsn = cpisp->s_next;
  309                 brelse(bp);
  310         }
  311 
  312         return (0);
  313 }
  314 
  315 int
  316 hpfs_cpdeinit (
  317         struct hpfsmount *hpmp)
  318 {
  319         dprintf(("hpmp_cpdeinit: "));
  320         free(hpmp->hpm_cpdblk,M_HPFSMNT);
  321         return (0);
  322 }
  323 
  324 /*
  325  * Lookup for a run of blocks.
  326  */
  327 int
  328 hpfs_bmlookup (
  329         struct hpfsmount *hpmp,
  330         u_long flags,   /* 1 means we want right len blocks in run, not less */
  331         lsn_t lsn,              /* We want near this one */
  332         u_long len,             /* We want such long */
  333         lsn_t *lsnp,    /* We got here */
  334         u_long *lenp)   /* We got this long */
  335 {
  336         u_int32_t * bitmap;
  337         register u_int32_t mask;
  338         int i,k;
  339         int cband, vcband;
  340         u_int bandsz;
  341         int count;
  342 
  343         dprintf(("hpfs_bmlookup: lsn: 0x%x, len 0x%lx | Step1\n", lsn, len));
  344 
  345         if (lsn > hpmp->hpm_su.su_btotal) {
  346                 printf("hpfs_bmlookup: OUT OF VOLUME\n");
  347                 return ENOSPC;
  348         }
  349         if (len > hpmp->hpm_bavail) {
  350                 printf("hpfs_bmlookup: OUT OF SPACE\n");
  351                 return ENOSPC;
  352         }
  353         i = lsn >> 5;
  354         k = lsn & 0x1F;
  355         mask = 1 << k;
  356         bitmap = (u_int32_t *)hpmp->hpm_bitmap + i;
  357 
  358         if (*bitmap & mask) {
  359                 *lsnp = lsn;
  360                 *lenp = 0;
  361                 for (; k < 32; k++, mask<<=1) {
  362                         if (*bitmap & mask)
  363                                 (*lenp) ++;
  364                         else {
  365                                 if (flags & 1)
  366                                         goto step2;
  367                                 else 
  368                                         return (0);
  369                         }
  370 
  371                         if (*lenp == len)
  372                                 return (0);
  373                 }
  374 
  375                 bitmap++;
  376                 i++;
  377                 for (; i < hpmp->hpm_su.su_btotal >> 5; i++, bitmap++) {
  378                         for (k=0, mask=1; k < 32; k++, mask<<=1) {
  379                                 if (*bitmap & mask)
  380                                         (*lenp) ++;
  381                                 else {
  382                                         if (flags & 1)
  383                                                 goto step2;
  384                                         else 
  385                                                 return (0);
  386                                 }
  387 
  388                                 if (*lenp == len)
  389                                         return (0);
  390                         }
  391                 }
  392                 return (0);
  393         }
  394 
  395 step2:
  396         /*
  397          * Lookup all bands begining from cband, lookup for first block
  398          */
  399         cband = (lsn >> 14);
  400         dprintf(("hpfs_bmlookup: Step2: band 0x%x (0x%lx)\n",
  401                  cband, hpmp->hpm_dbnum));
  402         for (vcband = 0; vcband < hpmp->hpm_dbnum; vcband ++, cband++) {
  403                 cband = cband % hpmp->hpm_dbnum;
  404                 bandsz = min (hpmp->hpm_su.su_btotal - (cband << 14), 0x4000);
  405                 dprintf(("hpfs_bmlookup: band: %d, sz: 0x%x\n", cband, bandsz));
  406 
  407                 bitmap = (u_int32_t *)hpmp->hpm_bitmap + (cband << 9);
  408                 *lsnp = cband << 14;
  409                 *lenp = 0;
  410                 count = 0;
  411                 for (i=0; i < bandsz >> 5; i++, bitmap++) {
  412                         for (k=0, mask=1; k < 32; k++, mask<<=1) {
  413                                 if (*bitmap & mask) {
  414                                         if (count) {
  415                                                 (*lenp) ++;
  416                                         } else {
  417                                                 count = 1;
  418                                                 *lsnp = (cband << 14) + (i << 5) + k;
  419                                                 *lenp = 1;
  420                                         }
  421                                 } else {
  422                                         if ((*lenp) && !(flags & 1)) {
  423                                                 return (0);
  424                                         } else {
  425                                                 count = 0;
  426                                         }
  427                                 }
  428 
  429                                 if (*lenp == len)
  430                                         return (0);
  431                         }
  432                 }
  433                 if (cband == hpmp->hpm_dbnum - 1)  {
  434                         if ((*lenp) && !(flags & 1)) {
  435                                 return (0);
  436                         } else {
  437                                 count = 0;
  438                         }
  439                 }
  440         }
  441 
  442         return (ENOSPC);
  443 }
  444 
  445 /*
  446  * Lookup a single free block.  XXX Need locking on BitMap operations
  447  * VERY STUPID ROUTINE!!!
  448  */
  449 int
  450 hpfs_bmfblookup (
  451         struct hpfsmount *hpmp,
  452         lsn_t *lp)
  453 {
  454         u_int32_t * bitmap;
  455         int i,k;
  456 
  457         dprintf(("hpfs_bmfblookup: "));
  458 
  459         bitmap = (u_int32_t *)hpmp->hpm_bitmap;
  460         for (i=0; i < hpmp->hpm_su.su_btotal >> 5; i++, bitmap++) {
  461                 k = ffs(*bitmap);
  462                 if (k) {
  463                         *lp = (i << 5) + k - 1;
  464                         dprintf((" found: 0x%x\n",*lp));
  465                         return (0);
  466                 }
  467         }
  468 
  469         return (ENOSPC);
  470 }
  471 
  472 /*
  473  * Mark contignous block of blocks.
  474  */
  475 int
  476 hpfs_bmmark (
  477         struct hpfsmount *hpmp,
  478         lsn_t bn,
  479         u_long bl,
  480         int state)
  481 {
  482         u_int32_t * bitmap;
  483         int i, didprint = 0;
  484 
  485         dprintf(("hpfs_bmmark(0x%x, 0x%lx, %d): \n",bn,bl, state));
  486 
  487         if ((bn > hpmp->hpm_su.su_btotal) || (bn+bl > hpmp->hpm_su.su_btotal)) {
  488                 printf("hpfs_bmmark: MARKING OUT OF VOLUME\n");
  489                 return 0;
  490         }
  491         bitmap = (u_int32_t *)hpmp->hpm_bitmap;
  492         bitmap += bn >> 5;
  493 
  494         while (bl > 0) {
  495                 for (i = bn & 0x1F; (i < 0x20) && (bl > 0) ; i++, bl--) {
  496                         if (state) {
  497                                 if ( *bitmap & (1 << i)) {
  498                                         if (!didprint) {
  499                                                 printf("hpfs_bmmark: ALREADY FREE\n");
  500                                                 didprint = 1;
  501                                         }
  502                                 } else 
  503                                         hpmp->hpm_bavail++;
  504 
  505                                 *bitmap |= (1 << i);
  506                         } else {
  507                                 if ((~(*bitmap)) & (1 << i)) {
  508                                         if (!didprint) {
  509                                                 printf("hpfs_bmmark: ALREADY BUSY\n");
  510                                                 didprint = 1;
  511                                         }
  512                                 } else 
  513                                         hpmp->hpm_bavail--;
  514 
  515                                 *bitmap &= ~(1 << i);
  516                         }
  517                 }
  518                 bn = 0;
  519                 bitmap++;
  520         }
  521 
  522         return (0);
  523 }
  524 
  525 
  526 int
  527 hpfs_validateparent (
  528         struct hpfsnode *hp)
  529 {
  530         struct hpfsnode *dhp;
  531         struct vnode *dvp;
  532         struct hpfsmount *hpmp = hp->h_hpmp;
  533         struct buf *bp;
  534         struct dirblk *dp;
  535         struct hpfsdirent *dep;
  536         lsn_t lsn, olsn;
  537         int level, error;
  538 
  539         dprintf(("hpfs_validatetimes(0x%x): [parent: 0x%x] ",
  540                 hp->h_no, hp->h_fn.fn_parent));
  541 
  542         if (hp->h_no == hp->h_fn.fn_parent) {
  543                 dhp = hp;
  544         } else {
  545                 error = VFS_VGET(hpmp->hpm_mp, hp->h_fn.fn_parent,
  546                                  LK_EXCLUSIVE, &dvp);
  547                 if (error)
  548                         return (error);
  549                 dhp = VTOHP(dvp);
  550         }
  551 
  552         lsn = ((alleaf_t *)dhp->h_fn.fn_abd)->al_lsn;
  553 
  554         olsn = 0;
  555         level = 1;
  556         bp = NULL;
  557 
  558 dive:
  559         dprintf(("[dive 0x%x] ", lsn));
  560         if (bp != NULL)
  561                 brelse(bp);
  562         error = bread(dhp->h_devvp, lsn, D_BSIZE, NOCRED, &bp);
  563         if (error)
  564                 goto failed;
  565 
  566         dp = (struct dirblk *) bp->b_data;
  567         if (dp->d_magic != D_MAGIC) {
  568                 printf("hpfs_validatetimes: magic doesn't match\n");
  569                 error = EINVAL;
  570                 goto failed;
  571         }
  572 
  573         dep = D_DIRENT(dp);
  574 
  575         if (olsn) {
  576                 dprintf(("[restore 0x%x] ", olsn));
  577 
  578                 while(!(dep->de_flag & DE_END) ) {
  579                         if((dep->de_flag & DE_DOWN) &&
  580                            (olsn == DE_DOWNLSN(dep)))
  581                                          break;
  582                         dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
  583                 }
  584 
  585                 if((dep->de_flag & DE_DOWN) && (olsn == DE_DOWNLSN(dep))) {
  586                         if (dep->de_flag & DE_END)
  587                                 goto blockdone;
  588 
  589                         if (hp->h_no == dep->de_fnode) {
  590                                 dprintf(("[found] "));
  591                                 goto readdone;
  592                         }
  593 
  594                         dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
  595                 } else {
  596                         printf("hpfs_validatetimes: ERROR! oLSN not found\n");
  597                         error = EINVAL;
  598                         goto failed;
  599                 }
  600         }
  601 
  602         olsn = 0;
  603 
  604         while(!(dep->de_flag & DE_END)) {
  605                 if(dep->de_flag & DE_DOWN) {
  606                         lsn = DE_DOWNLSN(dep);
  607                         level++;
  608                         goto dive;
  609                 }
  610 
  611                 if (hp->h_no == dep->de_fnode) {
  612                         dprintf(("[found] "));
  613                         goto readdone;
  614                 }
  615 
  616                 dep = (hpfsdirent_t *)((caddr_t)dep + dep->de_reclen);
  617         }
  618 
  619         if(dep->de_flag & DE_DOWN) {
  620                 dprintf(("[enddive] "));
  621                 lsn = DE_DOWNLSN(dep);
  622                 level++;
  623                 goto dive;
  624         }
  625 
  626 blockdone:
  627         dprintf(("[EOB] "));
  628         olsn = lsn;
  629         lsn = dp->d_parent;
  630         level--;
  631         dprintf(("[level %d] ", level));
  632         if (level > 0)
  633                 goto dive;      /* undive really */
  634 
  635         goto failed;
  636 
  637 readdone:
  638         bcopy(dep->de_name,hp->h_name,dep->de_namelen);
  639         hp->h_name[dep->de_namelen] = '\0';
  640         hp->h_namelen = dep->de_namelen;
  641         hp->h_ctime = dep->de_ctime;
  642         hp->h_atime = dep->de_atime;
  643         hp->h_mtime = dep->de_mtime;
  644         hp->h_flag |= H_PARVALID;
  645 
  646         dprintf(("[readdone]"));
  647 
  648 failed:
  649         dprintf(("\n"));
  650         if (bp != NULL)
  651                 brelse(bp);
  652         if (hp != dhp)
  653                 vput(dvp);
  654 
  655         return (error);
  656 }
  657 
  658 struct timespec
  659 hpfstimetounix (
  660         u_long hptime)
  661 {
  662         struct timespec t;
  663 
  664         t.tv_nsec = 0;
  665         t.tv_sec = hptime;
  666 
  667         return t;
  668 }
  669 
  670 /*
  671  * Write down changes done to parent dir, these are only times for now. 
  672  * hpfsnode have to be locked.
  673  */
  674 int
  675 hpfs_updateparent (
  676         struct hpfsnode *hp)
  677 {
  678         struct hpfsnode *dhp;
  679         struct vnode *dvp;
  680         struct hpfsdirent *dep;
  681         struct buf * bp;
  682         int error;
  683 
  684         dprintf(("hpfs_updateparent(0x%x): \n", hp->h_no));
  685 
  686         if (!(hp->h_flag & H_PARCHANGE))
  687                 return (0);
  688 
  689         if (!(hp->h_flag & H_PARVALID)) {
  690                 error = hpfs_validateparent (hp);
  691                 if (error)
  692                         return (error);
  693         }
  694 
  695         if (hp->h_no == hp->h_fn.fn_parent) {
  696                 dhp = hp;
  697         } else {
  698                 error = VFS_VGET(hp->h_hpmp->hpm_mp, hp->h_fn.fn_parent,
  699                                  LK_EXCLUSIVE, &dvp);
  700                 if (error)
  701                         return (error);
  702                 dhp = VTOHP(dvp);
  703         }
  704 
  705         error = hpfs_genlookupbyname (dhp, hp->h_name, hp->h_namelen,
  706                                         &bp, &dep);
  707         if (error) {
  708                 goto failed;
  709         }
  710 
  711         dep->de_atime = hp->h_atime;
  712         dep->de_mtime = hp->h_mtime;
  713         dep->de_size = hp->h_fn.fn_size;
  714 
  715         bdwrite (bp);
  716 
  717         hp->h_flag &= ~H_PARCHANGE;
  718 
  719         error = 0;
  720 failed:
  721         if (hp != dhp)
  722                 vput(dvp);
  723 
  724         return (0);
  725 }
  726 
  727 /*
  728  * Write down on disk changes done to fnode. hpfsnode have to be locked.
  729  */
  730 int
  731 hpfs_update (
  732         struct hpfsnode *hp)
  733 {
  734         struct buf * bp;
  735 
  736         dprintf(("hpfs_update(0x%x): \n", hp->h_no));
  737 
  738         if (!(hp->h_flag & H_CHANGE))
  739                 return (0);
  740 
  741         bp = getblk(hp->h_devvp, hp->h_no, FNODESIZE, 0, 0, 0);
  742         clrbuf(bp);
  743 
  744         bcopy (&hp->h_fn, bp->b_data, sizeof(struct fnode));
  745         bdwrite (bp);
  746 
  747         hp->h_flag &= ~H_CHANGE;
  748 
  749         if (hp->h_flag & H_PARCHANGE)
  750                 return (hpfs_updateparent(hp));
  751 
  752         return (0);
  753 }
  754 
  755 /*
  756  * Truncate file to specifed size. hpfsnode have to be locked.
  757  */
  758 int
  759 hpfs_truncate (
  760         struct hpfsnode *hp,
  761         u_long size)
  762 {
  763         struct hpfsmount *hpmp = hp->h_hpmp;
  764         lsn_t newblen, oldblen;
  765         int error, pf;
  766 
  767         dprintf(("hpfs_truncate(0x%x, 0x%x -> 0x%lx): ",
  768                 hp->h_no, hp->h_fn.fn_size, size));
  769 
  770         newblen = (size + DEV_BSIZE - 1) >> DEV_BSHIFT;
  771         oldblen = (hp->h_fn.fn_size + DEV_BSIZE - 1) >> DEV_BSHIFT;
  772 
  773         dprintf(("blen: 0x%x -> 0x%x\n", oldblen, newblen));
  774 
  775         error = hpfs_truncatealblk (hpmp, &hp->h_fn.fn_ab, newblen, &pf);
  776         if (error)
  777                 return (error);
  778         if (pf) {
  779                 hp->h_fn.fn_ab.ab_flag = 0;
  780                 hp->h_fn.fn_ab.ab_freecnt = 0x8;
  781                 hp->h_fn.fn_ab.ab_busycnt = 0x0;
  782                 hp->h_fn.fn_ab.ab_freeoff = sizeof(alblk_t);
  783         }
  784 
  785         hp->h_fn.fn_size = size;
  786 
  787         hp->h_flag |= (H_CHANGE | H_PARCHANGE);
  788 
  789         dprintf(("hpfs_truncate: successful\n"));
  790 
  791         return (0);
  792 }
  793 
  794 /*
  795  * Enlarge file to specifed size. hpfsnode have to be locked.
  796  */
  797 int
  798 hpfs_extend (
  799         struct hpfsnode *hp,
  800         u_long size)
  801 {
  802         struct hpfsmount *hpmp = hp->h_hpmp;
  803         lsn_t newblen, oldblen;
  804         int error;
  805 
  806         dprintf(("hpfs_extend(0x%x, 0x%x -> 0x%lx): ",
  807                 hp->h_no, hp->h_fn.fn_size, size));
  808 
  809         if (hpmp->hpm_bavail < 0x10) 
  810                 return (ENOSPC);
  811 
  812         newblen = (size + DEV_BSIZE - 1) >> DEV_BSHIFT;
  813         oldblen = (hp->h_fn.fn_size + DEV_BSIZE - 1) >> DEV_BSHIFT;
  814 
  815         dprintf(("blen: 0x%x -> 0x%x\n", oldblen, newblen));
  816 
  817         error = hpfs_addextent(hpmp, hp, newblen - oldblen);
  818         if (error) {
  819                 printf("hpfs_extend: FAILED TO ADD EXTENT %d\n", error);
  820                 return (error);
  821         }
  822 
  823         hp->h_fn.fn_size = size;
  824 
  825         hp->h_flag |= (H_CHANGE | H_PARCHANGE);
  826 
  827         dprintf(("hpfs_extend: successful\n"));
  828 
  829         return (0);
  830 }
  831 
  832 /*
  833  * Read AlSec structure, and check if magic is valid.
  834  * You don't need to brelse buf on error.
  835  */
  836 int
  837 hpfs_breadstruct (
  838         struct hpfsmount *hpmp,
  839         lsn_t lsn,
  840         u_int len,
  841         u_int32_t magic,
  842         struct buf **bpp)
  843 {
  844         struct buf *bp;
  845         u_int32_t *mp;
  846         int error;
  847 
  848         dprintf(("hpfs_breadstruct: reading at 0x%x\n", lsn));
  849 
  850         *bpp = NULL;
  851 
  852         error = bread(hpmp->hpm_devvp, lsn, len, NOCRED, &bp);
  853         if (error) {
  854                 brelse(bp);
  855                 return (error);
  856         }
  857         mp = (u_int32_t *) bp->b_data;
  858         if (*mp != magic) {
  859                 brelse(bp);
  860                 printf("hpfs_breadstruct: MAGIC DOESN'T MATCH (0x%08x != 0x%08x)\n",
  861                         *mp, magic);
  862                 return (EINVAL);
  863         }
  864 
  865         *bpp = bp;
  866 
  867         return (0);
  868 }
  869 

Cache object: 2788ea1fff839d778802ffe44122c281


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