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

📄 ntfs_vnops.c

📁 NTFS 磁盘系统 加载源代码
💻 C
字号:
#include <sys/param.h>#include <sys/kernel.h>#include <sys/vnode.h>#include <sys/dirent.h>#include <sys/namei.h>#include <sys/mount.h>#include "ntfs.h"#ifdef DEBUG#define DO_DEBUG(x)	x#else#define DO_DEBUG(x)#endif/* Helper */void ntfs_putuser(ntfs_io* dest,void *src,size_t n){	uiomove(src,n,(struct uio*)(dest->param));}/* vnode operations */intntfs_open(ap)	struct vop_open_args /* {		struct vnode *a_vp;		int  a_mode;		struct ucred *a_cred;		struct proc *a_p;	}*/ *ap;{	DO_DEBUG(printk("open\n"));	return 0;}int ntfs_close(ap)	struct vop_close_args /* {		struct vnode *a_vp;		int  a_fflag;		struct ucred *a_cred;		struct proc *a_p;  	} */ *ap;{	DO_DEBUG(printk("close\n"));	return 0;}int ntfs_access(ap)	struct vop_access_args /* {		struct vnode *a_vp;		int  a_mode;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	DO_DEBUG(printk("close\n"));	return 0;}intntfs_getattr(ap)	struct vop_getattr_args /* { 		struct vnode *a_vp;		 struct vattr *a_vap; 		struct ucred *a_cred; 		struct proc *a_p;	} */ *ap;{	ntfs_inode *ino = NTFS_V2INO(ap->a_vp);	struct vattr *vap = ap->a_vap;	ntfs_attribute *si,*data;	vap->va_type = ap->a_vp->v_type;	vap->va_mode = 0;	switch(ap->a_vp->v_type)	{		case VDIR:			vap->va_mode |= S_IFDIR | S_IRUSR | S_IXUSR |			S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;			break;		case VREG:			vap->va_mode |= S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;			break;	}	vap->va_mode &= ~ino->vol->umask;	vap->va_nlink = 1; /* FIXME */	vap->va_uid = ino->vol->uid;	vap->va_gid = ino->vol->gid;	vap->va_fsid = ino->vol->rdev;	vap->va_fileid = ino->i_number;	if((data=ntfs_find_attr(ino,AT_DATA,NULL)))		vap->va_size = DATASIZE(&data->header);	else		vap->va_size = 0;	vap->va_blocksize = ino->vol->clustersize;	si=ntfs_find_attr(ino,AT_STANDARD_INFORMATION,NULL);	if(si)	{		char *attr=si->d.data;#if 0		/* no FPU allowed here */		vap->va_atime.ts_sec = ntfs_ntutc2unixutc(*(long long*)(attr+0x18));		vap->va_mtime.ts_sec = ntfs_ntutc2unixutc(*(long long*)(attr+8));		vap->va_ctime.ts_sec = ntfs_ntutc2unixutc(*(long long*)(attr));#else		vap->va_atime.ts_sec = 0;		vap->va_mtime.ts_sec = 0;		vap->va_ctime.ts_sec = 0;#endif		/* FIXME: ts_nsec */	}	vap->va_gen = 0; /* FIXME */	vap->va_flags = 0;	vap->va_rdev = VNOVAL;	vap->va_bytes = vap->va_size; /* FIXME: allocated size */	vap->va_filerev = VNOVAL;	/* vap->va_vaflags unused */	/* vap->va_spare unused */	return 0;}intntfs_read(ap)	struct vop_read_args /* {		struct vnode *a_vp;		struct uio *a_uio;		int a_ioflag;		struct ucred *a_cred;	} */ *ap;{	int error=0,ret;	struct uio *uio = ap->a_uio;	struct ntfs_inode *ino = NTFS_V2INO(ap->a_vp);	ntfs_io io;	/* no data requested */	if(uio->uio_resid==0)		return 0;	if(uio->uio_offset<0)		return EINVAL;	/* reading directories is not supported */	if(ap->a_vp->v_type == VDIR)		return EISDIR;	if(!ino || !ntfs_find_attr(ino,AT_DATA,0))		return EINVAL;	/* move data */	io.fn_put=ntfs_putuser;	io.fn_get=0;	io.param=uio;	ret=ntfs_read_attr(ino,AT_DATA,0,uio->uio_offset,&io,uio->uio_resid);	if(ret<0)		return EINVAL;	return error;}/* later: ioctl *//* later select *//* later: mmap *//* later: seek */intntfs_readdir(ap)	struct vop_readdir_args /* {		struct vnode *a_vp;		struct uio *a_uio;		struct ucred *a_cred;		int *a_eofflag;		u_int *a_cookies;		int a_ncookies;	} */ *ap;       {#define ITEM_SIZE 2040	int error=0;	struct ntfs_inode *ino = NTFS_V2INO(ap->a_vp);	struct uio *uio = ap->a_uio;	char *item;	struct dirent *entry;	long long offs;	printf("readdir %x offset %x\n", ino->i_number, uio->uio_offset);	/* dir checking should have been done */	/* cookies not supported */	if(ap->a_eofflag || ap->a_cookies || ap->a_ncookies)	{		printf("ntfs: cookies not supported\n");		return EOPNOTSUPP;	}	item=ntfs_malloc(ITEM_SIZE);	entry=ntfs_malloc(sizeof(struct dirent));	entry->d_reclen=sizeof(struct dirent);	/* check buffer size */	/* fake .. */	if(uio->uio_offset == 0)	{		printf("returning ..\n");		entry->d_fileno=5; /* FIXME */		entry->d_type=DT_DIR;		entry->d_namlen=2;		strcpy(entry->d_name,"..");		offs=-2;	}else if(uio->uio_offset==-2 && ino->i_number!=FILE_ROOT){		printf("returning .\n");		/* return ., position on first entry */		offs=0;		entry->d_fileno=5; /* FIXME */		entry->d_namlen=1;		strcpy(entry->d_name,".");		ntfs_getdir_byposition(ino,&offs,item);	}else{		/* proceed to first entry for root */		if(uio->uio_offset==-2)		{			printf("advancing to first entry\n");			offs=0;			ntfs_getdir_byposition(ino,&offs,item);			printf("entry is %x\n",offs);			uio->uio_offset=offs;		}		offs=uio->uio_offset;		printf("advancing to next entry after %x\n",offs);		/* proceed to the next entry, find the current entry */		if(!ntfs_getdir_byposition(ino,&offs,item))		{			printf("getdir failed, position is %x\n",offs);			uio->uio_offset=offs;			ntfs_free(item);			ntfs_free(entry);			return 0;		}		uio->uio_offset=offs;		printf("position is now %x\n",offs);		entry->d_namlen=min((unsigned char)*(item+0x50),MAXNAMLEN);		ntfs_uni2ascii(entry->d_name,item+0x52,entry->d_namlen);		/* dcache? */	}	printf("returning data\n");	error=uiomove(entry,sizeof(struct dirent),uio);	uio->uio_offset=offs;	ntfs_free(item);	ntfs_free(entry);	return error;}intntfs_lookup(ap)	struct vop_lookup_args /* {		struct vnode *a_dvp;		struct vnode **a_vpp;		struct componentname *a_cnp;	} */ *ap; {	int error=0;	struct ntfs_inode *dir = NTFS_V2INO(ap->a_dvp);	struct componentname *cnp = ap->a_cnp;	char *item=0;	printf("Looking up %s in %d\n", cnp->cn_nameptr, dir->i_number);	if(ap->a_dvp->v_type != VDIR)		return ENOTDIR;	switch(cnp->cn_nameiop)	{		case CREATE:case RENAME:case DELETE:		printf("not supported\n");		return EOPNOTSUPP;	}	/* check credentials */	/* check name cache */	/* check .,.. */	item=ntfs_malloc(ITEM_SIZE);	/* ntfs_getdir will place the directory entry into item,	   and the first long long is the MFT record number */	if(ntfs_getdir_byname(dir,cnp->cn_nameptr,cnp->cn_namelen,item))	{		error=VFS_VGET(ap->a_dvp->v_mount,*(int*)item,ap->a_vpp);		if(error)		{			ntfs_free(item);			return error;		}		if(!(cnp->cn_flags & LOCKPARENT) || !(cnp->cn_flags & ISLASTCN))			VOP_UNLOCK(ap->a_dvp);		/* cache put*/	}else		error=ENOENT;	ntfs_free(item);	return error;}		/* later: readlink *//* TODO: abortop *//* TODO: lock *//* TODO: unlock */intntfs_islocked(ap)	struct vop_islocked_args /* {		struct vnode *a_vp;	} */ *ap;{	/* FIXME: real locking */	return 0;}/* later: strategy */intntfs_reclaim(ap)	struct vop_reclaim_args /* {		struct vnode *a_vp;	} */ *ap;{	struct ntfs_inode *ino=ap->a_vp->v_data;	if(!ino)		return EINVAL;	printf("ntfs_reclaim %x\n",ino->i_number);	LIST_REMOVE(ino,h_next);	/* cache purge */	if(ino->i_number!=FILE_MFT)	{		ntfs_clear_inode(ino);		ntfs_free(ino);	}	ap->a_vp->v_data=0;	return 0;}int (**ntfs_vnodeop_p)();struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = {	{ &vop_default_desc, vn_default_error },        	{ &vop_open_desc, ntfs_open },	{ &vop_close_desc, ntfs_close },	{ &vop_access_desc, ntfs_access },	{ &vop_getattr_desc, ntfs_getattr },	{ &vop_readdir_desc, ntfs_readdir },	{ &vop_lookup_desc, ntfs_lookup },	{ &vop_read_desc, ntfs_read },	{ &vop_islocked_desc, ntfs_islocked },	{ &vop_reclaim_desc, ntfs_reclaim },	{ (struct vnodeop_desc *)NULL, (int (*)())NULL }};struct vnodeopv_desc ntfs_vnodeop_opv_desc =	{ &ntfs_vnodeop_p, ntfs_vnodeop_entries };VNODEOP_SET(ntfs_vnodeop_opv_desc);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -