📄 ntfs_vfsops.c
字号:
#include <sys/param.h>#include <sys/kernel.h>#include <sys/mount.h>#include <sys/vnode.h>#include <sys/namei.h>#include <sys/systm.h>#include <sys/fcntl.h>#include <miscfs/specfs/specdev.h>/* sysctl.h instead */#include <sys/proc.h>#include "ntfstypes.h"#include "struct.h"#include "macros.h"#include "util.h"#include "support.h"#include "super.h"#include "inode.h"/* XXX */#define VT_NTFS VT_MSDOSFS#define MOUNT_NTFS MOUNT_MSDOSextern int (**ntfs_vnodeop_p)();int ntfs_statfs(struct mount *mp,struct statfs *sbp,struct proc *p);/* VFS operations */int ntfs_mount(mp, path, data, ndp, p) struct mount *mp; char *path; caddr_t data; struct nameidata *ndp; /* Will be recycled */ struct proc *p;{ char *devpath; int size,error,i; struct vnode *devvp; dev_t dev; struct buf *bp0=0; struct buf *mft_bp=0; int ronly; int needclose=0; ntfs_volume *vol=0; /* copy arguments*/ devpath = (char*)data; if((mp->mnt_flag & MNT_RDONLY) == 0) return EROFS; ronly=1; /* locate and investigate mount device */ NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, devpath, p); if((error=namei(ndp))){ printf("lookup of device failed\n"); return error; } devvp = ndp->ni_vp; if(devvp->v_type != VBLK){ printf("Not a block device\n"); vrele(devvp); return ENOTBLK; } if(major(devvp->v_rdev) >= nblkdev) { printf("no driver for block device\n"); vrele(devvp); return ENXIO; } dev = devvp->v_rdev; error=vfs_mountedon(devvp); if(error){ printf("Already mounted\n"); return error; } if(vcount(devvp)>1) return EBUSY; error=vinvalbuf(devvp, V_SAVE, p->p_ucred,p,0,0); if(error){ printf("could not invalidate buffers\n"); return error; } /* read boot record */ error = VOP_OPEN(devvp, ronly ? FREAD : FREAD | FWRITE, FSCRED, p); if(error) return error; needclose = 1; /* Need DIOCGPART ? */ error = bread(devvp, 0, 512, NOCRED, &bp0); if(error) goto error_exit; bp0->b_flags |= B_AGE; if(!IS_NTFS_VOLUME(bp0->b_data)){ printf("Not an NTFS volume\n"); error=EINVAL; goto error_exit; } /* allocate ntfs structure */ vol=ntfs_malloc(sizeof(ntfs_volume)); NTFS_MNT(vol)=mp; NTFS_MNT2VOL(mp)=vol; vol->rdev=dev; vol->devvp=devvp; /* FIXME: get uid etc from mount options */ vol->uid=0; vol->gid=0; vol->umask=0; vol->ngt=ngt_nt; vol->nct=nct_utf8; ntfs_init_volume(vol, bp0->b_data); brelse(bp0); bp0=0; /* FIXME: inithash */ vol->inode_hash=ntfs_malloc(sizeof(struct ntfs_head)); LIST_INIT(vol->inode_hash); if(vol->blocksize!=512) { printf("Cannot handle blocks of size %d\n",vol->blocksize); goto error_exit; } /* Allocate MFT record 0 */ vol->mft=ntfs_malloc(max(vol->mft_recordsize,vol->clustersize)); /* read the MFT record 0 */ for(i=0;i<max(vol->mft_clusters_per_record,1);i++){ error = bread(devvp, (vol->mft_cluster+i)*vol->clusterfactor, vol->mft_recordsize, NOCRED, &mft_bp); if(error) goto error_exit; memcpy(vol->mft+i*vol->clustersize,mft_bp->b_data, vol->mft_recordsize); mft_bp->b_flags |= B_AGE; brelse(mft_bp); mft_bp=0; } if(!ntfs_check_mft_record(vol,vol->mft)){ printf("Invalid MFT record 0\n"); goto error_exit; } if(ntfs_load_special_files(vol)){ printf("Error reading initial files\n"); goto error_exit; } /* fill mp: stat, maxsymlinklen, flag(LOCAL) */ copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN-1, &size); mp->mnt_stat.f_mntonname[size]='\0'; copyinstr(devpath, mp->mnt_stat.f_mntfromname, MNAMELEN-1, &size); mp->mnt_stat.f_mntfromname[size]='\0'; mp->mnt_stat.f_fsid.val[0]=(long)dev; mp->mnt_stat.f_fsid.val[1]=MOUNT_NTFS; mp->mnt_flag |= MNT_LOCAL; ntfs_statfs(mp, &mp->mnt_stat, p); return 0;error_exit: if(bp0) brelse(bp0); if(mft_bp) brelse(mft_bp); if(needclose) VOP_CLOSE(devvp, ronly ? FREAD : FREAD | FWRITE, NOCRED, p); if(vol && vol->mft) ntfs_free(vol->mft); if(vol) ntfs_free(vol); return error;}intntfs_start(mp,mntflags,p) struct mount *mp; int mntflags; struct proc *p;{ return 0;}intntfs_unmount(mp, mntflags, p) struct mount *mp; int mntflags; struct proc *p;{ int error=0; int flags=0; ntfs_volume *vol=NTFS_MNT2VOL(mp); if (mntflags & MNT_FORCE) { /* check ntfs_doforce */; flags |= FORCECLOSE; } /* flush mp */ error = vflush(mp, NULLVP, flags); if(error) return error; /* close+release device */ error = VOP_CLOSE(vol->devvp, FREAD, NOCRED, p); vrele(vol->devvp); vol->devvp=0; /* free ntfs structure */ ntfs_release_volume(vol); ntfs_free(vol); mp->mnt_data = 0; mp->mnt_flag &= ~MNT_LOCAL; return error;}intntfs_root(mp, vpp) struct mount *mp; struct vnode **vpp;{ struct vnode *nvp; int error; error = VFS_VGET(mp, (ino_t)FILE_ROOT, &nvp); if(error) return error; *vpp = nvp; return 0;}intntfs_quotactl(mp, cmd, uid, arg, p) struct mount *mp; int cmd; uid_t uid; caddr_t arg; struct proc *p;{ printf("quotactl\n"); return EOPNOTSUPP;}intntfs_statfs(mp, sbp, p) struct mount *mp; struct statfs *sbp; struct proc *p;{ /* FIXME: some should be filled at mount time, some are not filled */ sbp->f_type=MOUNT_NTFS; sbp->f_flags=0; sbp->f_bsize=512; /*XXX*/ sbp->f_iosize=512; sbp->f_blocks=1; sbp->f_bfree=1; sbp->f_bavail=0; sbp->f_files=1; sbp->f_ffree=0; return 0;}intntfs_sync(mp, waitfor, cred, p) struct mount *mp; int waitfor; struct ucred *cred; struct proc *p;{ return 0;}intntfs_vget(mp, inum, vpp) struct mount *mp; ino_t inum; struct vnode **vpp;{ struct vnode *vp; ntfs_inode *it; ntfs_volume *vol; ntfs_inode *inode; int error; vol=NTFS_MNT2VOL(mp);retry: for(it=vol->inode_hash->lh_first;it;it=it->h_next.le_next) { if(it->i_number==inum) break; } if(it) { if(vget(it->vp,0)) goto retry; *vpp=it->vp; return 0; } error = getnewvnode(VT_NTFS, mp, ntfs_vnodeop_p, &vp); if(error) { printf("error getting new vnode for %x\n",inum); *vpp=0; return error; } /* malloc into vp->v_data */ switch(inum) { case FILE_MFT: inode=vol->mft_ino; break; default: inode=(ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode)); if(!inode || ntfs_init_inode(inode,vol,inum)==-1) { printf("NTFS: Error loading inode %x\n",inum); *vpp=0; return EINVAL; } } /* Tie 'em together */ vp->v_data=inode; inode->vp=vp; /* we need to return it locked */ VOP_LOCK(vp); /* special device and fifo suppport */ /* file type */ if(ntfs_find_attr(inode,vol->at_data,0)) { vp->v_type=VREG; }else if(ntfs_find_attr(inode,vol->at_index_root,"$I30")) { vp->v_type=VDIR; }else /* should not happen */ vp->v_type=VNON; if(inum==FILE_ROOT) vp->v_flag |= VROOT; LIST_INSERT_HEAD(vol->inode_hash,inode,h_next); *vpp = vp; return 0;}intntfs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) struct mount *mp; struct fid *fhp; struct mbuf *nam; struct vnode **vpp; int *exflagsp; struct ucred **credanonp;{ printf("fhtovp\n"); return EOPNOTSUPP;}intntfs_vptofh(mp, fhp) struct vnode *mp; struct fid *fhp;{ printf("vptofh\n"); return EOPNOTSUPP;}intntfs_init(){ printf("ntfs_init\n"); return 0;}struct vfsops ntfs_vfsops = { ntfs_mount, ntfs_start, ntfs_unmount, ntfs_root, ntfs_quotactl, ntfs_statfs, ntfs_sync, ntfs_vget, ntfs_fhtovp, ntfs_vptofh, ntfs_init,};VFS_SET(ntfs_vfsops, ntfs, -1, VFCF_READONLY|VFCF_UNICODE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -