コード例 #1
0
ファイル: darwin-fs.c プロジェクト: dmlb2000/lustre-release
struct cfs_kern_file *
kern_file_open(const char * filename, int uflags, int mode, int *err)
{
        struct cfs_kern_file    *fp;
        vnode_t         vp;
        int             error;

        fp = (struct cfs_kern_file *)_MALLOC(sizeof(struct cfs_kern_file), M_TEMP, M_WAITOK);
        if (fp == NULL) {
                if (err != NULL)
                        *err = -ENOMEM;
                return NULL;
        }
        fp->f_flags = FFLAGS(uflags);
        fp->f_ctxt = vfs_context_create(NULL);

        if ((error = vnode_open(filename, fp->f_flags, 
                                mode, 0, &vp, fp->f_ctxt))){
                if (err != NULL)
                        *err = -error;
                _FREE(fp, M_TEMP);
        } else {
                if (err != NULL)
                        *err = 0;
                fp->f_vp = vp;
        }

        return fp;
}
コード例 #2
0
RTDECL(int) RTFileOpen(PRTFILE phFile, const char *pszFilename, uint64_t fOpen)
{
    RTFILEINT *pThis = (RTFILEINT *)RTMemAllocZ(sizeof(*pThis));
    if (!pThis)
        return VERR_NO_MEMORY;

    errno_t rc;
    pThis->u32Magic = RTFILE_MAGIC;
    pThis->fOpen    = fOpen;
    pThis->hVfsCtx  = vfs_context_current();
    if (pThis->hVfsCtx != NULL)
    {
        int             fCMode    = (fOpen & RTFILE_O_CREATE_MODE_MASK)
                                  ? (fOpen & RTFILE_O_CREATE_MODE_MASK) >> RTFILE_O_CREATE_MODE_SHIFT
                                  : RT_FILE_PERMISSION;
        int             fVnFlags  = 0; /* VNODE_LOOKUP_XXX */
        int             fOpenMode = 0;
        if (fOpen & RTFILE_O_NON_BLOCK)
            fOpenMode |= O_NONBLOCK;
        if (fOpen & RTFILE_O_WRITE_THROUGH)
            fOpenMode |= O_SYNC;

        /* create/truncate file */
        switch (fOpen & RTFILE_O_ACTION_MASK)
        {
            case RTFILE_O_OPEN:             break;
            case RTFILE_O_OPEN_CREATE:      fOpenMode |= O_CREAT; break;
            case RTFILE_O_CREATE:           fOpenMode |= O_CREAT | O_EXCL; break;
            case RTFILE_O_CREATE_REPLACE:   fOpenMode |= O_CREAT | O_TRUNC; break; /** @todo replacing needs fixing, this is *not* a 1:1 mapping! */
        }
        if (fOpen & RTFILE_O_TRUNCATE)
            fOpenMode |= O_TRUNC;

        switch (fOpen & RTFILE_O_ACCESS_MASK)
        {
            case RTFILE_O_READ:
                fOpenMode |= FREAD;
                break;
            case RTFILE_O_WRITE:
                fOpenMode |= fOpen & RTFILE_O_APPEND ? O_APPEND | FWRITE : FWRITE;
                break;
            case RTFILE_O_READWRITE:
                fOpenMode |= fOpen & RTFILE_O_APPEND ? O_APPEND | FWRITE | FREAD : FWRITE | FREAD;
                break;
            default:
                AssertMsgFailed(("RTFileOpen received an invalid RW value, fOpen=%#x\n", fOpen));
                return VERR_INVALID_PARAMETER;
        }

        pThis->fOpenMode = fOpenMode;
        rc = vnode_open(pszFilename, fOpenMode, fCMode, fVnFlags, &pThis->hVnode, pThis->hVfsCtx);
        if (rc == 0)
        {
            *phFile = pThis;
            return VINF_SUCCESS;
        }

        rc = RTErrConvertFromErrno(rc);
    }
コード例 #3
0
void
vm_swapfile_open(const char *path, vnode_t *vp)
{
	int error = 0;
	vfs_context_t	ctx = vfs_context_current();

	if ((error = vnode_open(path, (O_CREAT | O_TRUNC | FREAD | FWRITE), S_IRUSR | S_IWUSR, 0, vp, ctx))) {
		printf("Failed to open swap file %d\n", error);
		*vp = NULL;
		return;
	}	

	vnode_put(*vp);
}
コード例 #4
0
bool VNodeDiskDeviceClass::setupVNode() {
  int vapError = -1;
  struct vnode_attr vap;

  if (m_vnode != NULL)
    return true;

  vfs_context_t vfsContext = vfs_context_create((vfs_context_t) 0);

  int vnodeError = vnode_open(m_filePath->getCStringNoCopy(), (FREAD | FWRITE), 0, 0,
    &m_vnode, vfsContext);

  if (vnodeError || m_vnode == NULL) {
    IOLog("Error when opening file %s: error %d\n", 
      m_filePath->getCStringNoCopy(), vnodeError);
    goto failure;
  }

  if (!vnode_isreg(m_vnode)) {
    IOLog("Error when opening file %s: not a regular file\n", 
      m_filePath->getCStringNoCopy());
    vnode_close(m_vnode, (FREAD | FWRITE), vfsContext);
    goto failure;
  }

  VATTR_INIT(&vap);
  VATTR_WANTED(&vap, va_data_size);
  vapError = vnode_getattr(m_vnode, &vap, vfsContext);
  if (vapError) {
    IOLog("Error when retrieving vnode's attributes with error code %d\n", vapError);
    goto failure;
  }

  if (vap.va_data_size < m_blockSize * m_blockNum) {
    IOLog("Error file %s is too small, actual size is %llu\n", 
      m_filePath->getCStringNoCopy(), vap.va_data_size);
    goto failure;
  }

  vfs_context_rele(vfsContext);
  return true;

failure:
  vfs_context_rele(vfsContext);
  return false;
}
コード例 #5
0
ファイル: spl-vnode.c プロジェクト: rottegift/spl
int
vn_open(char *pnamep, enum uio_seg seg, int filemode, int createmode,
        struct vnode **vpp, enum create crwhy, mode_t umask)
{
    vfs_context_t vctx;
    int fmode;
    int error;

    fmode = filemode;
    if (crwhy)
        fmode |= O_CREAT;
    // TODO I think this should be 'fmode' instead of 'filemode'
    vctx = vfs_context_create((vfs_context_t)0);
    error = vnode_open(pnamep, filemode, createmode, 0, vpp, vctx);
    (void) vfs_context_rele(vctx);
    //printf("vn_open '%s' -> %d (vp %p)\n", pnamep, error, *vpp);
    return (error);
}
コード例 #6
0
ファイル: FileNVRAM.cpp プロジェクト: Piker-Alpha/FileNVRAM
IOReturn FileNVRAM::write_buffer(char* aBuffer, vfs_context_t aCtx)
{
	IOReturn error = 0;

	int length = (int)strlen(aBuffer);
	
	struct vnode * vp;
	
	if (aCtx)
	{
		if ((error = vnode_open(FILE_NVRAM_PATH, (O_TRUNC | O_CREAT | FWRITE | O_NOFOLLOW), S_IRUSR | S_IWUSR, VNODE_LOOKUP_NOFOLLOW, &vp, aCtx)))
		{
			printf("FileNVRAM.kext: Error, vnode_open(%s) failed with error %d!\n", FILE_NVRAM_PATH, error);
			
			return error;
		}
		else
		{
			if ((error = vnode_isreg(vp)) == VREG)
			{
				if ((error = vn_rdwr(UIO_WRITE, vp, aBuffer, length, 0, UIO_SYSSPACE, IO_NOCACHE|IO_NODELOCKED|IO_UNIT, vfs_context_ucred(aCtx), (int *) 0, vfs_context_proc(aCtx))))
				{
					printf("FileNVRAM.kext: Error, vn_rdwr(%s) failed with error %d!\n", FILE_NVRAM_PATH, error);
				}
				
				if ((error = vnode_close(vp, FWASWRITTEN, aCtx)))
				{
					printf("FileNVRAM.kext: Error, vnode_close(%s) failed with error %d!\n", FILE_NVRAM_PATH, error);
				}
			}
			else
			{
				printf("FileNVRAM.kext: Error, vnode_isreg(%s) failed with error %d!\n", FILE_NVRAM_PATH, error);
			}
		}
	}
	else
	{
		printf("FileNVRAM.kext: aCtx == NULL!\n");
		error = 0xFFFF; // EINVAL;
	}
	
	return error;
}
コード例 #7
0
ファイル: kern_shutdown.c プロジェクト: Algozjb/xnu
static int
sd_openlog(vfs_context_t ctx)
{
	int error = 0;
	struct timeval tv;
	
	/* Open shutdown log */
	if ((error = vnode_open(PROC_SHUTDOWN_LOG, (O_CREAT | FWRITE | O_NOFOLLOW), 0644, 0, &sd_logvp, ctx))) {
		printf("Failed to open %s: error %d\n", PROC_SHUTDOWN_LOG, error);
		sd_logvp = NULLVP;
		return error;
	}

	vnode_setsize(sd_logvp, (off_t)0, 0, ctx);

	/* Write a little header */
	microtime(&tv);
	sd_log(ctx, "Process shutdown log.  Current time is %lu (in seconds).\n\n", tv.tv_sec);

	return 0;
}
コード例 #8
0
bool DldIOShadowFile::initWithFileName( __in char* name, __in size_t nameLength )
{
    assert( preemption_enabled() );
    
    
    if( nameLength > (MAXPATHLEN + sizeof( L'\0' )) ){
        
        DBG_PRINT_ERROR(("length > (MAXPATHLEN + sizeof( L'\\0' ))\n"));
        return false;
    }
    
    
    if( !super::init() ){
        
        DBG_PRINT_ERROR(("super::init() failed\n"));
        return false;
    }
    
    this->rwLock = IORWLockAlloc();
    assert( this->rwLock );
    if( !this->rwLock ){
        
        DBG_PRINT_ERROR(("this->rwLock = IORWLockAlloc() failed\n" ));
        return false;
    }
    
    //
    // set a maximum file size to infinity
    //
    this->maxSize = DLD_IGNR_FSIZE;
    
    //
    // set switch size to 512 MB
    //
    this->switchSize = 0x20000000ll;
    
    this->path = (char*)IOMalloc( nameLength );
    assert( this->path );
    if( !this->path ){
        
        DBG_PRINT_ERROR(("this->path = IOMalloc( %u ) failed\n", (int)nameLength ));
        return false;
    }
    
    this->pathLength = nameLength;
    
    memcpy( this->path, name, nameLength );
    assert( L'\0' == this->path[ this->pathLength - 0x1 ] );
    
    //
    // open or create the file
    //
    errno_t  error;
    vfs_context_t   vfs_context;
    
    vfs_context = vfs_context_create( NULL );
    assert( vfs_context );
    if( !vfs_context )
        return false;
    
    //
    // open or create a file, truncate if the file exists
    //
    error = vnode_open( this->path,
                        O_EXLOCK | O_RDWR | O_CREAT | O_TRUNC | O_SYNC, // fmode
                        0644,// cmode
                        0x0,// flags
                        &this->vnode,
                        vfs_context );
    vfs_context_rele( vfs_context );
    if( error ){
        
        DBG_PRINT_ERROR(("vnode_open() failed with the %u error\n", error));
        return false;
    }
    
    //
    // vn_open returns with both a use_count
    // and an io_count on the found vnode
    //
    
    //
    // mark as an internal non shadowed vnode, use the CreateAndAddIOVnodByBSDVnode
    // as the kauth callback might have not been registered so the vnode open
    // was not seen by the DL driver
    //
    DldIOVnode*  dldVnode;
    dldVnode = DldVnodeHashTable::sVnodesHashTable->CreateAndAddIOVnodByBSDVnode( this->vnode );
    assert( dldVnode );
    if( !dldVnode ){
        
        //
        // we can't use this vnode as will be unable to distinguish
        // the DL internal writes from the user writes this will result
        // in an endless loop
        //
        DBG_PRINT_ERROR(("RetrieveReferencedIOVnodByBSDVnode() failed\n"));
        
        this->release();
        return NULL;
    }
    
    //
    // mark as skipped for log, shadowing and any other operations
    //
    dldVnode->flags.internal = 0x1;
    
    dldVnode->release();
    DLD_DBG_MAKE_POINTER_INVALID( dldVnode );
    
    this->expandFile();
    
    //
    // mark as noncached vnode, writes must be sector aligned!
    //
    //vnode_setnocache( this->vnode );
    
    return true;
}
コード例 #9
0
ファイル: osi_file.c プロジェクト: chanke/openafs-osd
void *
osi_UFSOpen(afs_dcache_id_t *ainode)
{
    struct vnode *vp;
    struct vattr va;
    struct osi_file *afile = NULL;
    extern int cacheDiskType;
    afs_int32 code = 0;
    int dummy;
    char fname[1024];
    struct osi_stat tstat;

    AFS_STATCNT(osi_UFSOpen);
    if (cacheDiskType != AFS_FCACHE_TYPE_UFS) {
	osi_Panic("UFSOpen called for non-UFS cache\n");
    }
    if (!afs_osicred_initialized) {
	/* valid for alpha_osf, SunOS, Ultrix */
	memset(&afs_osi_cred, 0, sizeof(afs_ucred_t));
	afs_osi_cred.cr_ref++;
#ifndef AFS_DARWIN110_ENV
	afs_osi_cred.cr_ngroups = 1;
#endif
	afs_osicred_initialized = 1;
    }
    afile = (struct osi_file *)osi_AllocSmallSpace(sizeof(struct osi_file));
    AFS_GUNLOCK();
#ifdef AFS_CACHE_VNODE_PATH
    if (!ainode->ufs) {
	osi_Panic("No cache inode\n");
    }

    code = vnode_open(ainode->ufs, O_RDWR, 0, 0, &vp, afs_osi_ctxtp);
#else
#ifndef AFS_DARWIN80_ENV
    if (afs_CacheFSType == AFS_APPL_HFS_CACHE)
	code = igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, &ainode->ufs, &vp, &va, &dummy);	/* XXX hfs is broken */
    else if (afs_CacheFSType == AFS_APPL_UFS_CACHE)
#endif
	code =
	    igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, (ino_t) ainode->ufs,
		      &vp, &va, &dummy);
#ifndef AFS_DARWIN80_ENV
    else
	panic("osi_UFSOpen called before cacheops initialized\n");
#endif
#endif
    AFS_GLOCK();
    if (code) {
	osi_FreeSmallSpace(afile);
	osi_Panic("UFSOpen: igetinode failed");
    }
    afile->vnode = vp;
    afile->offset = 0;
    afile->proc = (int (*)())0;
#ifndef AFS_CACHE_VNODE_PATH
    afile->size = va.va_size;
#else
    code = afs_osi_Stat(afile, &tstat);
    afile->size = tstat.size;
#endif
    return (void *)afile;
}
コード例 #10
0
ファイル: vdev_disk.c プロジェクト: gcracker/zfs
static int
vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
    uint64_t *ashift)
{
	spa_t *spa = vd->vdev_spa;
	vdev_disk_t *dvd = vd->vdev_tsd;
	vnode_t *devvp = NULLVP;
	vfs_context_t context = NULL;
	uint64_t blkcnt;
	uint32_t blksize;
	int fmode = 0;
	int error = 0;
	int isssd;

	/*
	 * We must have a pathname, and it must be absolute.
	 */
	if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') {
		vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
		return (SET_ERROR(EINVAL));
	}

	/*
	 * Reopen the device if it's not currently open. Otherwise,
	 * just update the physical size of the device.
	 */
	if (dvd != NULL) {
	  if (dvd->vd_offline) {
	    /*
	     * If we are opening a device in its offline notify
	     * context, the LDI handle was just closed. Clean
	     * up the LDI event callbacks and free vd->vdev_tsd.
	     */
	    vdev_disk_free(vd);
	  } else {
	    ASSERT(vd->vdev_reopening);
		devvp = dvd->vd_devvp;
	    goto skip_open;
	  }
	}

	/*
	 * Create vd->vdev_tsd.
	 */
	vdev_disk_alloc(vd);
	dvd = vd->vdev_tsd;

	/*
	 * When opening a disk device, we want to preserve the user's original
	 * intent.  We always want to open the device by the path the user gave
	 * us, even if it is one of multiple paths to the same device.  But we
	 * also want to be able to survive disks being removed/recabled.
	 * Therefore the sequence of opening devices is:
	 *
	 * 1. Try opening the device by path.  For legacy pools without the
	 *    'whole_disk' property, attempt to fix the path by appending 's0'.
	 *
	 * 2. If the devid of the device matches the stored value, return
	 *    success.
	 *
	 * 3. Otherwise, the device may have moved.  Try opening the device
	 *    by the devid instead.
	 */
	/* ### APPLE TODO ### */
#ifdef illumos
	if (vd->vdev_devid != NULL) {
		if (ddi_devid_str_decode(vd->vdev_devid, &dvd->vd_devid,
		    &dvd->vd_minor) != 0) {
			vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
			return (SET_ERROR(EINVAL));
		}
	}
#endif

	error = EINVAL;		/* presume failure */

	if (vd->vdev_path != NULL) {

		context = vfs_context_create( spl_vfs_context_kernel() );

		/* Obtain an opened/referenced vnode for the device. */
		if ((error = vnode_open(vd->vdev_path, spa_mode(spa), 0, 0,
								&devvp, context))) {
			goto out;
		}
		if (!vnode_isblk(devvp)) {
			error = ENOTBLK;
			goto out;
		}
		/*
		 * ### APPLE TODO ###
		 * vnode_authorize devvp for KAUTH_VNODE_READ_DATA and
		 * KAUTH_VNODE_WRITE_DATA
		 */

		/*
		 * Disallow opening of a device that is currently in use.
		 * Flush out any old buffers remaining from a previous use.
		 */
		if ((error = vfs_mountedon(devvp))) {
			goto out;
		}
		if (VNOP_FSYNC(devvp, MNT_WAIT, context) != 0) {
			error = ENOTBLK;
			goto out;
		}
		if ((error = buf_invalidateblks(devvp, BUF_WRITE_DATA, 0, 0))) {
			goto out;
		}

	} else {
		goto out;
	}


	int len = MAXPATHLEN;
	if (vn_getpath(devvp, dvd->vd_readlinkname, &len) == 0) {
		dprintf("ZFS: '%s' resolved name is '%s'\n",
			   vd->vdev_path, dvd->vd_readlinkname);
	} else {
		dvd->vd_readlinkname[0] = 0;
	}



skip_open:
	/*
	 * Determine the actual size of the device.
	 */
	if (VNOP_IOCTL(devvp, DKIOCGETBLOCKSIZE, (caddr_t)&blksize, 0,
	    context) != 0 ||
	    VNOP_IOCTL(devvp, DKIOCGETBLOCKCOUNT, (caddr_t)&blkcnt, 0,
	    context) != 0) {
		error = EINVAL;
		goto out;
	}

	*psize = blkcnt * (uint64_t)blksize;
	*max_psize = *psize;

	dvd->vd_ashift = highbit(blksize) - 1;
	dprintf("vdev_disk: Device %p ashift set to %d\n", devvp,
	    dvd->vd_ashift);


	*ashift = highbit(MAX(blksize, SPA_MINBLOCKSIZE)) - 1;

	/*
	 *  ### APPLE TODO ###
	 */
#ifdef illumos
	if (vd->vdev_wholedisk == 1) {
		int wce = 1;
		if (error == 0) {
			/*
			 * If we have the capability to expand, we'd have
			 * found out via success from DKIOCGMEDIAINFO{,EXT}.
			 * Adjust max_psize upward accordingly since we know
			 * we own the whole disk now.
			 */
			*max_psize = capacity * blksz;
		}

		/*
		 * Since we own the whole disk, try to enable disk write
		 * caching.  We ignore errors because it's OK if we can't do it.
		 */
		(void) ldi_ioctl(dvd->vd_lh, DKIOCSETWCE, (intptr_t)&wce,
		    FKIOCTL, kcred, NULL);
	}
#endif

	/*
	 * Clear the nowritecache bit, so that on a vdev_reopen() we will
	 * try again.
	 */
	vd->vdev_nowritecache = B_FALSE;

	/* Inform the ZIO pipeline that we are non-rotational */
	vd->vdev_nonrot = B_FALSE;
	if (VNOP_IOCTL(devvp, DKIOCISSOLIDSTATE, (caddr_t)&isssd, 0,
				   context) == 0) {
		if (isssd)
			vd->vdev_nonrot = B_TRUE;
	}
	dprintf("ZFS: vdev_disk(%s) isSSD %d\n", vd->vdev_path ? vd->vdev_path : "",
			isssd);

	dvd->vd_devvp = devvp;
out:
	if (error) {
	  if (devvp) {
			vnode_close(devvp, fmode, context);
			dvd->vd_devvp = NULL;
	  }
		vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
	}
	if (context)
		(void) vfs_context_rele(context);

	if (error) printf("ZFS: vdev_disk_open('%s') failed error %d\n",
					  vd->vdev_path ? vd->vdev_path : "", error);
	return (error);
}
コード例 #11
0
ファイル: vdev_disk.c プロジェクト: awesome/zfs
static int
vdev_disk_open(vdev_t *vd, uint64_t *size, uint64_t *max_size, uint64_t *ashift)
{
	vdev_disk_t *dvd = NULL;
	vnode_t *devvp = NULLVP;
	vfs_context_t context = NULL;
	uint64_t blkcnt;
	uint32_t blksize;
	int fmode = 0;
	int error = 0;

	/*
	 * We must have a pathname, and it must be absolute.
	 */
	if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') {
		vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
		return (EINVAL);
	}

	dvd = kmem_zalloc(sizeof (vdev_disk_t), KM_SLEEP);
    if (dvd == NULL)
        return ENOMEM;

	/*
	 * When opening a disk device, we want to preserve the user's original
	 * intent.  We always want to open the device by the path the user gave
	 * us, even if it is one of multiple paths to the save device.  But we
	 * also want to be able to survive disks being removed/recabled.
	 * Therefore the sequence of opening devices is:
	 *
	 * 1. Try opening the device by path.  For legacy pools without the
	 *    'whole_disk' property, attempt to fix the path by appending 's0'.
	 *
	 * 2. If the devid of the device matches the stored value, return
	 *    success.
	 *
	 * 3. Otherwise, the device may have moved.  Try opening the device
	 *    by the devid instead.
	 *
	 */

	/* ### APPLE TODO ### */
	/* ddi_devid_str_decode */

	context = vfs_context_create((vfs_context_t)0);

	/* Obtain an opened/referenced vnode for the device. */
	error = vnode_open(vd->vdev_path, spa_mode(vd->vdev_spa), 0, 0, &devvp, context);
	if (error) {
		goto out;
	}

	if (!vnode_isblk(devvp)) {
		error = ENOTBLK;
		goto out;
	}

	/* ### APPLE TODO ### */
	/* vnode_authorize devvp for KAUTH_VNODE_READ_DATA and
	 * KAUTH_VNODE_WRITE_DATA
	 */

	/*
	 * Disallow opening of a device that is currently in use.
	 * Flush out any old buffers remaining from a previous use.
	 */
	if ((error = vfs_mountedon(devvp))) {
		goto out;
	}
	if (VNOP_FSYNC(devvp, MNT_WAIT, context) != 0) {
		error = ENOTBLK;
		goto out;
	}
	if ((error = buf_invalidateblks(devvp, BUF_WRITE_DATA, 0, 0))) {
		goto out;
	}

	/*
	 * Determine the actual size of the device.
	 */
	if (VNOP_IOCTL(devvp, DKIOCGETBLOCKSIZE, (caddr_t)&blksize, 0, context)
	       	!= 0 || VNOP_IOCTL(devvp, DKIOCGETBLOCKCOUNT, (caddr_t)&blkcnt,
		0, context) != 0) {

		error = EINVAL;
		goto out;
	}
	*size = blkcnt * (uint64_t)blksize;

	/*
	 *  ### APPLE TODO ###
	 * If we own the whole disk, try to enable disk write caching.
	 */

	/*
	 * Take the device's minimum transfer size into account.
	 */
	*ashift = highbit(MAX(blksize, SPA_MINBLOCKSIZE)) - 1;

    /*
     * Setting the vdev_ashift did in fact break the pool for import
     * on ZEVO. This puts the logic into question. It appears that vdev_top
     * will also then change. It then panics in space_map from metaslab_alloc
     */
    //vd->vdev_ashift = *ashift;
    dvd->vd_ashift = *ashift;


	/*
	 * Clear the nowritecache bit, so that on a vdev_reopen() we will
	 * try again.
	 */
	vd->vdev_nowritecache = B_FALSE;
	vd->vdev_tsd = dvd;
	dvd->vd_devvp = devvp;
out:
	if (error) {
		if (devvp)
			vnode_close(devvp, fmode, context);
		if (dvd)
			kmem_free(dvd, sizeof (vdev_disk_t));

		/*
		 * Since the open has failed, vd->vdev_tsd should
		 * be NULL when we get here, signaling to the
		 * rest of the spa not to try and reopen or close this device
		 */
		vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
	}
	if (context) {
		(void) vfs_context_rele(context);
	}
	return (error);
}
コード例 #12
0
ファイル: FileNVRAM.cpp プロジェクト: Piker-Alpha/FileNVRAM
IOReturn FileNVRAM::read_buffer(char** aBuffer, uint64_t* aLength, vfs_context_t aCtx)
{
	IOReturn error = 0;

	struct vnode * vp;
	struct vnode_attr va;

	if (aCtx)
	{
		if ((error = vnode_open(FILE_NVRAM_PATH, (O_RDONLY | FREAD | O_NOFOLLOW), S_IRUSR, VNODE_LOOKUP_NOFOLLOW, &vp, aCtx)))
		{
			printf("failed opening vnode at path %s, errno %d\n", FILE_NVRAM_PATH, error);
			
			return error;
		}
		else
		{
			if ((error = vnode_isreg(vp)) == VREG)
			{
				VATTR_INIT(&va);
				VATTR_WANTED(&va, va_data_size);	/* size in bytes of the fork managed by current vnode */

				// Determine size of vnode
				if ((error = vnode_getattr(vp, &va, aCtx)))
				{
					printf("FileNVRAM.kext: Error, failed to determine file size of %s, errno %d.\n", FILE_NVRAM_PATH, error);
				}
				else
				{
					if (aLength)
					{
						*aLength = va.va_data_size;
					}
					
					*aBuffer = (char *)IOMalloc((size_t)va.va_data_size);
					int len = (int)va.va_data_size;
					
					if ((error = vn_rdwr(UIO_READ, vp, *aBuffer, len, 0, UIO_SYSSPACE, IO_NOCACHE|IO_NODELOCKED|IO_UNIT, vfs_context_ucred(aCtx), (int *) 0, vfs_context_proc(aCtx))))
					{
						printf("FileNVRAM.kext: Error, writing to vnode(%s) failed with error %d!\n", FILE_NVRAM_PATH, error);
					}
				}
				
				if ((error = vnode_close(vp, 0, aCtx)))
				{
					printf("FileNVRAM.kext: Error, vnode_close(%s) failed with error %d!\n", FILE_NVRAM_PATH, error);
				}
			}
			else
			{
				printf("FileNVRAM.kext: Error, vnode_isreg(%s) failed with error %d!\n", FILE_NVRAM_PATH, error);
			}
		}
	}
	else
	{
		printf("FileNVRAM.kext: aCtx == NULL!\n");
		error = 0xFFFF; // EINVAL;
	}
	
	return error;
}
コード例 #13
0
ファイル: kern_symfile.c プロジェクト: Algozjb/xnu
struct kern_direct_file_io_ref_t *
kern_open_file_for_direct_io(const char * name, 
			     kern_get_file_extents_callback_t callback, 
			     void * callback_ref,
			     dev_t * partition_device_result,
			     dev_t * image_device_result,
                             uint64_t * partitionbase_result,
                             uint64_t * maxiocount_result,
                             uint32_t * oflags,
                             off_t offset,
                             caddr_t addr,
                             vm_size_t len)
{
    struct kern_direct_file_io_ref_t * ref;

    proc_t			p;
    struct vnode_attr		va;
    int				error;
    off_t			f_offset;
    uint64_t                    fileblk;
    size_t                      filechunk;
    uint64_t                    physoffset;
    dev_t			device;
    dev_t			target = 0;
    int			        isssd = 0;
    uint32_t                    flags = 0;
    uint32_t			blksize;
    off_t 			maxiocount, count;
    boolean_t                   locked = FALSE;

    int (*do_ioctl)(void * p1, void * p2, u_long theIoctl, caddr_t result);
    void * p1 = NULL;
    void * p2 = NULL;

    error = EFAULT;

    ref = (struct kern_direct_file_io_ref_t *) kalloc(sizeof(struct kern_direct_file_io_ref_t));
    if (!ref)
    {
	error = EFAULT;
    	goto out;
    }

    bzero(ref, sizeof(*ref));
    p = kernproc;
    ref->ctx = vfs_context_create(vfs_context_current());

    if ((error = vnode_open(name, (O_CREAT | FWRITE), (0), 0, &ref->vp, ref->ctx)))
        goto out;

    if (addr && len)
    {
	if ((error = kern_write_file(ref, offset, addr, len)))
	    goto out;
    }

    VATTR_INIT(&va);
    VATTR_WANTED(&va, va_rdev);
    VATTR_WANTED(&va, va_fsid);
    VATTR_WANTED(&va, va_data_size);
    VATTR_WANTED(&va, va_nlink);
    error = EFAULT;
    if (vnode_getattr(ref->vp, &va, ref->ctx))
    	goto out;

    kprintf("vp va_rdev major %d minor %d\n", major(va.va_rdev), minor(va.va_rdev));
    kprintf("vp va_fsid major %d minor %d\n", major(va.va_fsid), minor(va.va_fsid));
    kprintf("vp size %qd\n", va.va_data_size);

    if (ref->vp->v_type == VREG)
    {
	/* Don't dump files with links. */
	if (va.va_nlink != 1)
	    goto out;

        device = va.va_fsid;
        p1 = &device;
        p2 = p;
        do_ioctl = &file_ioctl;
    }
    else if ((ref->vp->v_type == VBLK) || (ref->vp->v_type == VCHR))
    {
	/* Partition. */
        device = va.va_rdev;

        p1 = ref->vp;
        p2 = ref->ctx;
        do_ioctl = &device_ioctl;
    }
    else
    {
	/* Don't dump to non-regular files. */
	error = EFAULT;
        goto out;
    }
    ref->device = device;

    // get block size

    error = do_ioctl(p1, p2, DKIOCGETBLOCKSIZE, (caddr_t) &ref->blksize);
    if (error)
        goto out;

    if (ref->vp->v_type == VREG)
        ref->filelength = va.va_data_size;
    else
    {
        error = do_ioctl(p1, p2, DKIOCGETBLOCKCOUNT, (caddr_t) &fileblk);
        if (error)
            goto out;
	ref->filelength = fileblk * ref->blksize;    
    }

    // pin logical extents

    error = kern_ioctl_file_extents(ref, _DKIOCCSPINEXTENT, 0, ref->filelength);
    if (error && (ENOTTY != error)) goto out;
    ref->pinned = (error == 0);

    // generate the block list

    error = do_ioctl(p1, p2, DKIOCLOCKPHYSICALEXTENTS, NULL);
    if (error)
        goto out;
    locked = TRUE;

    f_offset = 0;
    while (f_offset < ref->filelength) 
    {
        if (ref->vp->v_type == VREG)
        {
            filechunk = 1*1024*1024*1024;
            daddr64_t blkno;

            error = VNOP_BLOCKMAP(ref->vp, f_offset, filechunk, &blkno, &filechunk, NULL, 0, NULL);
            if (error)
                goto out;

            fileblk = blkno * ref->blksize;
        }
        else if ((ref->vp->v_type == VBLK) || (ref->vp->v_type == VCHR))
        {
            fileblk = f_offset;
            filechunk = f_offset ? 0 : ref->filelength;
        }

        physoffset = 0;
        while (physoffset < filechunk)
        {
            dk_physical_extent_t getphysreq;
            bzero(&getphysreq, sizeof(getphysreq));

            getphysreq.offset = fileblk + physoffset;
            getphysreq.length = (filechunk - physoffset);
            error = do_ioctl(p1, p2, DKIOCGETPHYSICALEXTENT, (caddr_t) &getphysreq);
            if (error)
                goto out;
            if (!target)
            {
                target = getphysreq.dev;
            }
            else if (target != getphysreq.dev)
            {
                error = ENOTSUP;
                goto out;
            }
            callback(callback_ref, getphysreq.offset, getphysreq.length);
            physoffset += getphysreq.length;
        }
        f_offset += filechunk;
    }
    callback(callback_ref, 0ULL, 0ULL);

    if (ref->vp->v_type == VREG)
        p1 = &target;

    // get partition base

    error = do_ioctl(p1, p2, DKIOCGETBASE, (caddr_t) partitionbase_result);
    if (error)
        goto out;

    // get block size & constraints

    error = do_ioctl(p1, p2, DKIOCGETBLOCKSIZE, (caddr_t) &blksize);
    if (error)
        goto out;

    maxiocount = 1*1024*1024*1024;

    error = do_ioctl(p1, p2, DKIOCGETMAXBLOCKCOUNTREAD, (caddr_t) &count);
    if (error)
        count = 0;
    count *= blksize;
    if (count && (count < maxiocount))
        maxiocount = count;

    error = do_ioctl(p1, p2, DKIOCGETMAXBLOCKCOUNTWRITE, (caddr_t) &count);
    if (error)
        count = 0;
    count *= blksize;
    if (count && (count < maxiocount))
        maxiocount = count;

    error = do_ioctl(p1, p2, DKIOCGETMAXBYTECOUNTREAD, (caddr_t) &count);
    if (error)
        count = 0;
    if (count && (count < maxiocount))
        maxiocount = count;

    error = do_ioctl(p1, p2, DKIOCGETMAXBYTECOUNTWRITE, (caddr_t) &count);
    if (error)
        count = 0;
    if (count && (count < maxiocount))
        maxiocount = count;

    error = do_ioctl(p1, p2, DKIOCGETMAXSEGMENTBYTECOUNTREAD, (caddr_t) &count);
    if (error)
        count = 0;
    if (count && (count < maxiocount))
        maxiocount = count;

    error = do_ioctl(p1, p2, DKIOCGETMAXSEGMENTBYTECOUNTWRITE, (caddr_t) &count);
    if (error)
        count = 0;
    if (count && (count < maxiocount))
        maxiocount = count;

    kprintf("max io 0x%qx bytes\n", maxiocount);
    if (maxiocount_result)
        *maxiocount_result = maxiocount;

    error = do_ioctl(p1, p2, DKIOCISSOLIDSTATE, (caddr_t)&isssd);
    if (!error && isssd)
        flags |= kIOHibernateOptionSSD;

    if (partition_device_result)
        *partition_device_result = device;
    if (image_device_result)
        *image_device_result = target;
    if (flags)
        *oflags = flags;

out:
    kprintf("kern_open_file_for_direct_io(%d)\n", error);

    if (error && locked)
    {
        p1 = &device;
        (void) do_ioctl(p1, p2, DKIOCUNLOCKPHYSICALEXTENTS, NULL);
    }

    if (error && ref)
    {
	if (ref->vp)
	{
	    vnode_close(ref->vp, FWRITE, ref->ctx);
	    ref->vp = NULLVP;
	}
	vfs_context_rele(ref->ctx);
	kfree(ref, sizeof(struct kern_direct_file_io_ref_t));
	ref = NULL;
    }
    return(ref);
}