diff options
author | semenu <semenu@FreeBSD.org> | 1999-04-20 21:06:44 +0000 |
---|---|---|
committer | semenu <semenu@FreeBSD.org> | 1999-04-20 21:06:44 +0000 |
commit | 42e01703dca788bba764956ba12647f3dcdd7ec9 (patch) | |
tree | 94575bff8659b4709ed4f7205ce68df7fce0790e /sys/fs/ntfs/ntfs_vfsops.c | |
parent | c8cbbb76c7dbcc506d7786d8a80159d227b2cf4c (diff) | |
download | FreeBSD-src-42e01703dca788bba764956ba12647f3dcdd7ec9.zip FreeBSD-src-42e01703dca788bba764956ba12647f3dcdd7ec9.tar.gz |
Removed annoying messaged during boot,added some check
before mounting (should help to do not mount extended partitions:-).
Fixed problem with hanging while unmounting busy fs.
And (the most important) added some locks to prevent
simulaneous access to kernel structures!
Diffstat (limited to 'sys/fs/ntfs/ntfs_vfsops.c')
-rw-r--r-- | sys/fs/ntfs/ntfs_vfsops.c | 225 |
1 files changed, 136 insertions, 89 deletions
diff --git a/sys/fs/ntfs/ntfs_vfsops.c b/sys/fs/ntfs/ntfs_vfsops.c index a371319..7d1f91d 100644 --- a/sys/fs/ntfs/ntfs_vfsops.c +++ b/sys/fs/ntfs/ntfs_vfsops.c @@ -102,13 +102,6 @@ static int ntfs_init () #endif { - static first=1; - - if(!first) return (0); - first = 1; - - printf("ntfs_init(): \n"); - ntfs_nthashinit(); return 0; @@ -384,6 +377,12 @@ ntfs_mountfs(devvp, mp, argsp, p) brelse( bp ); bp = NULL; + if (strncmp(ntmp->ntm_bootfile.bf_sysid, NTFS_BBID, NTFS_BBIDLEN)) { + error = EINVAL; + printf("ntfs_mountfs: invalid boot block\n"); + goto out; + } + { int8_t cpr = ntmp->ntm_mftrecsz; if( cpr > 0 ) @@ -391,11 +390,11 @@ ntfs_mountfs(devvp, mp, argsp, p) else ntmp->ntm_bpmftrec = (1 << (-cpr)) / ntmp->ntm_bps; } - printf("ntfs_mountfs(): bps: %d, spc: %d, media: %x, mftrecsz: %d (%d sects)\n", + dprintf(("ntfs_mountfs(): bps: %d, spc: %d, media: %x, mftrecsz: %d (%d sects)\n", ntmp->ntm_bps,ntmp->ntm_spc,ntmp->ntm_bootfile.bf_media, - ntmp->ntm_mftrecsz,ntmp->ntm_bpmftrec); - printf("ntfs_mountfs(): mftcn: 0x%x|0x%x\n", - (u_int32_t)ntmp->ntm_mftcn,(u_int32_t)ntmp->ntm_mftmirrcn); + ntmp->ntm_mftrecsz,ntmp->ntm_bpmftrec)); + dprintf(("ntfs_mountfs(): mftcn: 0x%x|0x%x\n", + (u_int32_t)ntmp->ntm_mftcn,(u_int32_t)ntmp->ntm_mftmirrcn)); ntmp->ntm_mountp = mp; ntmp->ntm_dev = dev; @@ -406,51 +405,64 @@ ntfs_mountfs(devvp, mp, argsp, p) ntmp->ntm_flag = argsp->flag; mp->mnt_data = (qaddr_t)ntmp; - printf("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n", + dprintf(("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n", (ntmp->ntm_flag & NTFS_MFLAG_CASEINS)?"insens.":"sens.", (ntmp->ntm_flag & NTFS_MFLAG_ALLNAMES)?" allnames,":"", - ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode); + ntmp->ntm_uid, ntmp->ntm_gid, ntmp->ntm_mode)); - printf("ntfs_mountfs(): reading system nodes...\n"); + /* + * We read in some system nodes to do not allow + * reclaim them and to have everytime access to them. + */ { - i = NTFS_MFTINO; - error = VFS_VGET(mp, i, &(ntmp->ntm_sysvn[i])); - if(error) - goto out1; - VREF(ntmp->ntm_sysvn[i]); - vput(ntmp->ntm_sysvn[i]); - i = NTFS_ROOTINO; - error = VFS_VGET(mp, i, &(ntmp->ntm_sysvn[i])); - if(error) - goto out1; - VREF(ntmp->ntm_sysvn[i]); - vput(ntmp->ntm_sysvn[i]); + int pi[3] = { NTFS_MFTINO, NTFS_ROOTINO, NTFS_BITMAPINO }; + for (i=0; i<3; i++) { + error = VFS_VGET(mp, pi[i], &(ntmp->ntm_sysvn[pi[i]])); + if(error) + goto out1; + ntmp->ntm_sysvn[pi[i]]->v_flag |= VSYSTEM; + VREF(ntmp->ntm_sysvn[pi[i]]); + vput(ntmp->ntm_sysvn[pi[i]]); + } } - MALLOC( ntmp->ntm_upcase, wchar *, 65536 * sizeof(wchar), + /* + * Read in WHOLE lowcase -> upcase translation + * file. + */ + MALLOC(ntmp->ntm_upcase, wchar *, 65536 * sizeof(wchar), M_NTFSMNT, M_WAITOK); - printf("ntfs_mountfs(): opening $UpCase\n"); - error = VFS_VGET(mp, NTFS_UPCASEINO, &vp ); + error = VFS_VGET(mp, NTFS_UPCASEINO, &vp); if(error) goto out1; - printf("ntfs_mountfs(): reading $UpCase\n"); - error = ntfs_readattr( ntmp, VTONT(vp), NTFS_A_DATA, NULL, + error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL, 0, 65536*sizeof(wchar), ntmp->ntm_upcase); - printf("ntfs_mountfs(): closing $UpCase\n"); vput(vp); if(error) goto out1; + /* + * Scan $BitMap and count free clusters + */ + error = ntfs_calccfree(ntmp, &ntmp->ntm_cfree); + if(error) + goto out1; + + /* + * Read and translate to internal format attribute + * definition file. + */ { int num,j; struct attrdef ad; - printf("ntfs_mountfs(): opening $AttrDef\n"); + /* Open $AttrDef */ error = VFS_VGET(mp, NTFS_ATTRDEFINO, &vp ); if(error) goto out1; + /* Count valid entries */ for(num=0;;num++) { error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL, @@ -461,14 +473,15 @@ ntfs_mountfs(devvp, mp, argsp, p) if (ad.ad_name[0] == 0) break; } - printf("ntfs_mountfs(): reading %d attrdefs\n",num); + /* Alloc memory for attribute definitions */ MALLOC(ntmp->ntm_ad, struct ntvattrdef *, num * sizeof(struct ntvattrdef), M_NTFSMNT, M_WAITOK); ntmp->ntm_adnum = num; + /* Read them and translate */ for(i=0;i<num;i++){ error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL, @@ -482,11 +495,8 @@ ntfs_mountfs(devvp, mp, argsp, p) } while(ad.ad_name[j++]); ntmp->ntm_ad[i].ad_namelen = j - 1; ntmp->ntm_ad[i].ad_type = ad.ad_type; - printf("ntfs_mountfs(): attribute: %s, type: 0x%x\n", - ntmp->ntm_ad[i].ad_name, - ntmp->ntm_ad[i].ad_type); } - printf("ntfs_mountfs(): closing $AttrDef\n"); + vput(vp); } @@ -504,9 +514,14 @@ ntfs_mountfs(devvp, mp, argsp, p) devvp->v_specflags |= SI_MOUNTEDON; #endif return (0); + out1: for(i=0;i<NTFS_SYSNODESNUM;i++) if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]); + + if (vflush(mp,NULLVP,0)) + printf("ntfs_mountfs: vflush failed\n"); + out: #if __FreeBSD_version >= 300000 devvp->v_specmountpoint = NULL; @@ -525,7 +540,6 @@ ntfs_start ( int flags, struct proc *p ) { - printf("\nntfs_start():\n"); return (0); } @@ -538,24 +552,33 @@ ntfs_unmount( register struct ntfsmount *ntmp; int error, ronly = 0, flags, i; - printf("ntfs_unmount: unmounting...\n"); + dprintf(("ntfs_unmount: unmounting...\n")); ntmp = VFSTONTFS(mp); flags = 0; if(mntflags & MNT_FORCE) flags |= FORCECLOSE; - printf("ntfs_unmount: vflushing...\n"); + dprintf(("ntfs_unmount: vflushing...\n")); error = vflush(mp,NULLVP,flags | SKIPSYSTEM); if (error) { printf("ntfs_unmount: vflush failed: %d\n",error); return (error); } + + /* Check if only system vnodes are rest */ + for(i=0;i<NTFS_SYSNODESNUM;i++) + if((ntmp->ntm_sysvn[i]) && + (ntmp->ntm_sysvn[i]->v_usecount > 1)) return (EBUSY); + + /* Derefernce all system vnodes */ for(i=0;i<NTFS_SYSNODESNUM;i++) if(ntmp->ntm_sysvn[i]) vrele(ntmp->ntm_sysvn[i]); + + /* vflush system vnodes */ error = vflush(mp,NULLVP,flags); if (error) - printf("ntfs_unmount: vflush failed: %d\n",error); + printf("ntfs_unmount: vflush failed(sysnodes): %d\n",error); #if __FreeBSD_version >= 300000 ntmp->ntm_devvp->v_specmountpoint = NULL; @@ -573,7 +596,7 @@ ntfs_unmount( vrele(ntmp->ntm_devvp); - printf("ntfs_umount: freeing memory...\n"); + dprintf(("ntfs_umount: freeing memory...\n")); mp->mnt_data = (qaddr_t)0; mp->mnt_flag &= ~MNT_LOCAL; FREE(ntmp->ntm_ad, M_NTFSMNT); @@ -614,47 +637,55 @@ ntfs_quotactl ( return EOPNOTSUPP; } -static int -ntfs_statfs( - struct mount *mp, - struct statfs *sbp, - struct proc *p) +int +ntfs_calccfree( + struct ntfsmount *ntmp, + cn_t *cfreep) { - struct ntfsmount *ntmp = VFSTONTFS(mp); - u_int64_t mftsize,mftallocated,bmsize,bmallocated; struct vnode *vp; - int error,j,i; u_int8_t *tmp; + int j, error; + long cfree = 0; + size_t bmsize, i; - dprintf(("ntfs_statfs():")); - - ntfs_filesize(ntmp, VTOF(ntmp->ntm_sysvn[NTFS_MFTINO]), - &mftsize, &mftallocated); - - error = VFS_VGET(mp, NTFS_BITMAPINO, &vp); - if(error) - return (error); + vp = ntmp->ntm_sysvn[NTFS_BITMAPINO]; - ntfs_filesize(ntmp, VTOF(vp), &bmsize, &bmallocated); + bmsize = VTOF(vp)->f_size; - MALLOC(tmp, u_int8_t *, bmsize,M_TEMP, M_WAITOK); + MALLOC(tmp, u_int8_t *, bmsize, M_TEMP, M_WAITOK); error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL, 0, bmsize, tmp); if(error) { FREE(tmp, M_TEMP); - vput(vp); return (error); } - vput(vp); - sbp->f_bfree = 0; for(i=0;i<bmsize;i++) for(j=0;j<8;j++) - if(~tmp[i] & (1 << j)) sbp->f_bfree++; + if(~tmp[i] & (1 << j)) cfree++; FREE(tmp, M_TEMP); + *cfreep = cfree; + + return(0); +} + +static int +ntfs_statfs( + struct mount *mp, + struct statfs *sbp, + struct proc *p) +{ + struct ntfsmount *ntmp = VFSTONTFS(mp); + u_int64_t mftsize,mftallocated; + + dprintf(("ntfs_statfs():\n")); + + mftsize = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_size; + mftallocated = VTOF(ntmp->ntm_sysvn[NTFS_MFTINO])->f_allocated; + #if __FreeBSD_version >= 300000 sbp->f_type = mp->mnt_vfc->vfc_typenum; #else @@ -663,7 +694,7 @@ ntfs_statfs( sbp->f_bsize = ntmp->ntm_bps; sbp->f_iosize = ntmp->ntm_bps * ntmp->ntm_spc; sbp->f_blocks = ntmp->ntm_bootfile.bf_spv; - sbp->f_bfree = sbp->f_bavail = ntfs_cntobn(sbp->f_bfree); + sbp->f_bfree = sbp->f_bavail = ntfs_cntobn(ntmp->ntm_cfree); sbp->f_ffree = sbp->f_bfree / ntmp->ntm_bpmftrec; sbp->f_files = mftallocated / ntfs_bntob(ntmp->ntm_bpmftrec) + sbp->f_ffree; @@ -746,41 +777,63 @@ ntfs_vgetex( *vpp = NULL; /* Get ntnode */ - error = ntfs_ntget(ntmp, ino, &ip); + error = ntfs_ntlookup(ntmp, ino, &ip); if (error) { printf("ntfs_vget: ntfs_ntget failed\n"); return (error); } + /* It may be not initialized fully, so force load it */ + if (!(flags & VG_DONTLOADIN) && !(ip->i_flag & IN_LOADED)) { + error = ntfs_loadntnode(ntmp, ip); + if(error) { + printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %d\n", + ip->i_number); + ntfs_ntput(ip); + return (error); + } + } + error = ntfs_fget(ntmp, ip, attrtype, attrname, &fp); if (error) { printf("ntfs_vget: ntfs_fget failed\n"); - ntfs_ntrele(ip); + ntfs_ntput(ip); return (error); } + if (!(flags & VG_DONTVALIDFN) && !(fp->f_flag & FN_VALID)) { + if ((ip->i_frflag & NTFS_FRFLAG_DIR) && + (fp->f_attrtype == 0x80 && fp->f_attrname == NULL)) { + fp->f_type = VDIR; + } else if(flags & VG_EXT) { + fp->f_type = VNON; + + fp->f_size =fp->f_allocated = 0; + } else { + fp->f_type = VREG; + + error = ntfs_filesize(ntmp, fp, + &fp->f_size, &fp->f_allocated); + if (error) { + ntfs_ntput(ip); + return (error); + } + } + + fp->f_flag |= FN_VALID; + } + if (FTOV(fp)) { vget(FTOV(fp), lkflags, p); *vpp = FTOV(fp); - ntfs_ntrele(ip); + ntfs_ntput(ip); return (0); } - /* It may be not initialized fully, so force load it */ - if (!(flags & VG_DONTLOAD) && !(ip->i_flag & IN_LOADED)) { - error = ntfs_loadntnode(ntmp, ip); - if(error) { - printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO: %d\n", - ip->i_number); - ntfs_ntrele(ip); - return (error); - } - } - error = getnewvnode(VT_NTFS, ntmp->ntm_mountp, ntfs_vnodeop_p, &vp); if(error) { ntfs_frele(fp); - ntfs_ntrele(ip); + ntfs_ntput(ip); return (error); } dprintf(("ntfs_vget: vnode: %p for ntnode: %d\n", vp,ino)); @@ -788,18 +841,12 @@ ntfs_vgetex( lockinit(&fp->f_lock, PINOD, "fnode", 0, 0); fp->f_vp = vp; vp->v_data = fp; - - if (ip->i_frflag & NTFS_FRFLAG_DIR) - vp->v_type = fp->f_type = VDIR; - else - vp->v_type = fp->f_type = VREG; + vp->v_type = fp->f_type; if (ino == NTFS_ROOTINO) vp->v_flag |= VROOT; - if (ino < NTFS_SYSNODESNUM) - vp->v_flag |= VSYSTEM; - ntfs_ntrele(ip); + ntfs_ntput(ip); if (lkflags & LK_TYPE_MASK) { error = vn_lock(vp, lkflags, p); |