⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntfs_vfsops.c

📁 一个linux下NTFS文件格式源代码
💻 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 + -