Пример #1
0
/* returns 0 on success, errno on failure */
int
ReallyWrite(DirHandle * file, int block, char *data)
{
    FdHandle_t *fdP;
    extern int VolumeChanged;
    int code;
    ssize_t nBytes;

    errno = 0;

    fdP = IH_OPEN(file->dirh_handle);
    if (fdP == NULL) {
	code = errno;
	return code;
    }
    if (FDH_SEEK(fdP, ((afs_foff_t)block) * AFS_PAGESIZE, SEEK_SET) < 0) {
	code = errno;
	FDH_REALLYCLOSE(fdP);
	return code;
    }
    nBytes = FDH_WRITE(fdP, data, (afs_fsize_t) AFS_PAGESIZE);
    if (nBytes != AFS_PAGESIZE) {
	if (nBytes < 0)
	    code = errno;
	else
	    code = EIO;
	FDH_REALLYCLOSE(fdP);
	return code;
    }
    FDH_CLOSE(fdP);
    VolumeChanged = 1;
    return 0;
}
Пример #2
0
/* returns 0 on success, errno on failure */
int
ReallyWrite(DirHandle * file, int block, char *data)
{
    ssize_t count;
    FdHandle_t *fdP;
    afs_ino_str_t stmp;

    fdP = IH_OPEN(file->dirh_handle);
    if (fdP == NULL) {
	ViceLog(0,
		("ReallyWrite(): open failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(stmp,
						       file->dirh_handle->
						       ih_ino), errno));
	lpErrno = errno;
	return 0;
    }
    if ((count = FDH_PWRITE(fdP, data, PAGESIZE, ((afs_foff_t)block) * PAGESIZE)) != PAGESIZE) {
	ViceLog(0,
		("ReallyWrite(): write failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(stmp,
						       file->dirh_handle->
						       ih_ino), errno));
	lpCount = count;
	lpErrno = errno;
	FDH_REALLYCLOSE(fdP);
	return 0;
    }
    FDH_CLOSE(fdP);
    return 0;
}
Пример #3
0
/* Close all cached file descriptors for this inode. */
int
ih_reallyclose(IHandle_t * ihP)
{
    if (!ihP)
	return 0;

    IH_LOCK;
    ihP->ih_refcnt++;   /* must not disappear over unlock */
    if (ihP->ih_synced) {
	FdHandle_t *fdP;
        ihP->ih_synced = 0;
	IH_UNLOCK;

	fdP = IH_OPEN(ihP);
	if (fdP) {
	    OS_SYNC(fdP->fd_fd);
	    FDH_CLOSE(fdP);
	}

	IH_LOCK;
    }

    osi_Assert(ihP->ih_refcnt > 0);

    ih_fdclose(ihP);

    if (ihP->ih_refcnt > 1)
	ihP->ih_refcnt--;
    else
	_ih_release_r(ihP);

    IH_UNLOCK;
    return 0;
}
Пример #4
0
/* returns 0 on success, errno on failure */
int
ReallyRead(DirHandle * file, int block, char *data)
{
    FdHandle_t *fdP;
    int code;
    errno = 0;
    fdP = IH_OPEN(file->dirh_handle);
    if (fdP == NULL) {
	code = errno;
	return code;
    }
    if (FDH_SEEK(fdP, block * AFS_PAGESIZE, SEEK_SET) < 0) {
	code = errno;
	FDH_REALLYCLOSE(fdP);
	return code;
    }
    code = FDH_READ(fdP, data, (afs_fsize_t) AFS_PAGESIZE);
    if (code != AFS_PAGESIZE) {
	if (code < 0)
	    code = errno;
	else
	    code = EIO;
	FDH_REALLYCLOSE(fdP);
	return code;
    }
    FDH_CLOSE(fdP);
    return 0;
}
Пример #5
0
/* returns 0 on success, errno on failure */
int
ReallyRead(DirHandle * file, int block, char *data)
{
    FdHandle_t *fdP;
    int code;
    ssize_t nBytes;
    errno = 0;
    fdP = IH_OPEN(file->dirh_handle);
    if (fdP == NULL) {
	code = errno;
	return code;
    }
    nBytes = FDH_PREAD(fdP, data, (afs_fsize_t) AFS_PAGESIZE,
                       ((afs_foff_t)block) * AFS_PAGESIZE);
    if (nBytes != AFS_PAGESIZE) {
	if (nBytes < 0)
	    code = errno;
	else
	    code = EIO;
	FDH_REALLYCLOSE(fdP);
	return code;
    }
    FDH_CLOSE(fdP);
    return 0;
}
Пример #6
0
void
ih_sync_all(void) {

    int ihash;

    IH_LOCK;
    for (ihash = 0; ihash < I_HANDLE_HASH_SIZE; ihash++) {
	IHandle_t *ihP, *ihPnext;

	ihP = ihashTable[ihash].ihash_head;
	if (ihP)
	    ihP->ih_refcnt++;	/* must not disappear over unlock */
	for (; ihP; ihP = ihPnext) {
	    
	    if (ihP->ih_synced) {
		FdHandle_t *fdP;

		ihP->ih_synced = 0;
		IH_UNLOCK;

		fdP = IH_OPEN(ihP);
		if (fdP) { 
		    OS_SYNC(fdP->fd_fd);
		    FDH_CLOSE(fdP);
		}

	  	IH_LOCK;
	    }

	    /* when decrementing the refcount, the ihandle might disappear
	       and we might not even be able to proceed to the next one.
	       Hence the gymnastics putting a hold on the next one already */
	    ihPnext = ihP->ih_next;
	    if (ihPnext) ihPnext->ih_refcnt++;

	    if (ihP->ih_refcnt > 1) {
		ihP->ih_refcnt--;
	    } else {
		IH_UNLOCK;
		ih_release(ihP);
		IH_LOCK;
	    }

	}
    }
    IH_UNLOCK;
}
Пример #7
0
/* Sync an inode to disk if its handle isn't NULL */
int
ih_condsync(IHandle_t * ihP)
{
    int code;
    FdHandle_t *fdP;

    if (!ihP)
	return 0;

    fdP = IH_OPEN(ihP);
    if (fdP == NULL)
	return -1;

    code = FDH_SYNC(fdP);
    FDH_CLOSE(fdP);

    return code;
}
Пример #8
0
/* returns 0 on success, errno on failure */
int
ReallyRead(DirHandle * file, int block, char *data)
{
    int code;
    FdHandle_t *fdP;

    fdP = IH_OPEN(file->dirh_handle);
    if (fdP == NULL) {
	code = errno;
	ViceLog(0,
		("ReallyRead(): open failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(NULL,
						       file->dirh_handle->
						       ih_ino), code));
	return code;
    }
    if (FDH_SEEK(fdP, block * PAGESIZE, SEEK_SET) < 0) {
	code = errno;
	ViceLog(0,
		("ReallyRead(): lseek failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(NULL,
						       file->dirh_handle->
						       ih_ino), code));
	FDH_REALLYCLOSE(fdP);
	return code;
    }
    code = FDH_READ(fdP, data, PAGESIZE);
    if (code != PAGESIZE) {
	if (code < 0)
	    code = errno;
	else
	    code = EIO;
	ViceLog(0,
		("ReallyRead(): read failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(NULL,
						       file->dirh_handle->
						       ih_ino), code));
	FDH_REALLYCLOSE(fdP);
	return code;
    }
    FDH_CLOSE(fdP);
    return 0;

}
Пример #9
0
/* returns 0 on success, errno on failure */
int
ReallyWrite(DirHandle * file, int block, char *data)
{
    afs_int32 count;
    FdHandle_t *fdP;

    fdP = IH_OPEN(file->dirh_handle);
    if (fdP == NULL) {
	ViceLog(0,
		("ReallyWrite(): open failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(NULL,
						       file->dirh_handle->
						       ih_ino), errno));
	lpErrno = errno;
	return 0;
    }
    if (FDH_SEEK(fdP, block * PAGESIZE, SEEK_SET) < 0) {
	ViceLog(0,
		("ReallyWrite(): lseek failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(NULL,
						       file->dirh_handle->
						       ih_ino), errno));
	lpErrno = errno;
	FDH_REALLYCLOSE(fdP);
	return 0;
    }
    if ((count = FDH_WRITE(fdP, data, PAGESIZE)) != PAGESIZE) {
	ViceLog(0,
		("ReallyWrite(): write failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(NULL,
						       file->dirh_handle->
						       ih_ino), errno));
	lpCount = count;
	lpErrno = errno;
	FDH_REALLYCLOSE(fdP);
	return 0;
    }
    FDH_CLOSE(fdP);
    return 0;
}
Пример #10
0
/* returns 0 on success, errno on failure */
int
ReallyRead(DirHandle * file, int block, char *data)
{
    int code;
    ssize_t rdlen;
    FdHandle_t *fdP;
    afs_ino_str_t stmp;

    fdP = IH_OPEN(file->dirh_handle);
    if (fdP == NULL) {
	code = errno;
	ViceLog(0,
		("ReallyRead(): open failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(stmp,
						       file->dirh_handle->
						       ih_ino), code));
	return code;
    }
    rdlen = FDH_PREAD(fdP, data, PAGESIZE, ((afs_foff_t)block) * PAGESIZE);
    if (rdlen != PAGESIZE) {
	if (rdlen < 0)
	    code = errno;
	else
	    code = EIO;
	ViceLog(0,
		("ReallyRead(): read failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(stmp,
						       file->dirh_handle->
						       ih_ino), code));
	FDH_REALLYCLOSE(fdP);
	return code;
    }
    FDH_CLOSE(fdP);
    return 0;

}
Пример #11
0
static int
DumpVnode(int dumpfd, struct VnodeDiskObject *v, int volid, int vnodeNumber,
	  int dumpEverything, struct Volume *vp)
{
    int code = 0;
    IHandle_t *ihP;
    FdHandle_t *fdP;

    if (verbose)
	fprintf(stderr, "dumping vnode %d\n", vnodeNumber);

    if (!v || v->type == vNull)
	return code;
    if (!code)
	code = DumpDouble(dumpfd, D_VNODE, vnodeNumber, v->uniquifier);
    if (!dumpEverything)
	return code;
    if (!code)
	code = DumpByte(dumpfd, 't', (byte) v->type);
    if (!code)
	code = DumpShort(dumpfd, 'l', v->linkCount);	/* May not need this */
    if (!code)
	code = DumpInt32(dumpfd, 'v', v->dataVersion);
    if (!code)
	code = DumpInt32(dumpfd, 'm', v->unixModifyTime);
    if (!code)
	code = DumpInt32(dumpfd, 'a', v->author);
    if (!code)
	code = DumpInt32(dumpfd, 'o', v->owner);
    if (!code && v->group)
	code = DumpInt32(dumpfd, 'g', v->group);	/* default group is 0 */
    if (!code)
	code = DumpShort(dumpfd, 'b', v->modeBits);
    if (!code)
	code = DumpInt32(dumpfd, 'p', v->parent);
    if (!code)
	code = DumpInt32(dumpfd, 's', v->serverModifyTime);
    if (v->type == vDirectory) {
	acl_HtonACL(VVnodeDiskACL(v));
	if (!code)
	    code =
		DumpByteString(dumpfd, 'A', (byte *) VVnodeDiskACL(v),
			       VAclDiskSize(v));
    }

    if (VNDISK_GET_INO(v)) {
	IH_INIT(ihP, V_device(vp), V_parentId(vp), VNDISK_GET_INO(v));
	fdP = IH_OPEN(ihP);
	if (fdP == NULL) {
	    fprintf(stderr,
		    "Unable to open inode %s for vnode %u (volume %i); not dumped, error %d\n",
		    PrintInode(NULL, VNDISK_GET_INO(v)), vnodeNumber, volid,
		    errno);
	}
	else
	{
		if (verbose)
		    fprintf(stderr, "about to dump inode %s for vnode %u\n",
			    PrintInode(NULL, VNDISK_GET_INO(v)), vnodeNumber);
		code = DumpFile(dumpfd, vnodeNumber, fdP, v);
		FDH_CLOSE(fdP);
	}
	IH_RELEASE(ihP);
    }

    if (verbose)
	fprintf(stderr, "done dumping vnode %d\n", vnodeNumber);
    return code;
}
Пример #12
0
Volume *
VCreateVolume_r(Error * ec, char *partname, VolumeId volumeId, VolumeId parentId)
{				/* Should be the same as volumeId if there is
				 * no parent */
    VolumeDiskData vol;
    int i, rc;
    char headerName[VMAXPATHLEN], volumePath[VMAXPATHLEN];
    Device device;
    struct DiskPartition64 *partition;
    struct VolumeDiskHeader diskHeader;
    IHandle_t *handle;
    FdHandle_t *fdP;
    Inode nearInode AFS_UNUSED = 0;
    char *part, *name;
    struct stat st;
    struct VolumeHeader tempHeader;
    struct afs_inode_info stuff[MAXINODETYPE];
    afs_ino_str_t stmp;
# ifdef AFS_DEMAND_ATTACH_FS
    int locktype = 0;
# endif /* AFS_DEMAND_ATTACH_FS */

    init_inode_info(&tempHeader, stuff);

    *ec = 0;
    memset(&vol, 0, sizeof(vol));
    vol.id = volumeId;
    vol.parentId = parentId;
    vol.copyDate = time(0);	/* The only date which really means when this
				 * @i(instance) of this volume was created.
				 * Creation date does not mean this */

    /* Initialize handle for error case below. */
    handle = NULL;

    /* Verify that the parition is valid before writing to it. */
    if (!(partition = VGetPartition_r(partname, 0))) {
	Log("VCreateVolume: partition %s is not in service.\n", partname);
	*ec = VNOVOL;
	return NULL;
    }
#if	defined(NEARINODE_HINT)
    nearInodeHash(volumeId, nearInode);
    nearInode %= partition->f_files;
#endif
    VGetVolumePath(ec, vol.id, &part, &name);
    if (*ec == VNOVOL || !strcmp(partition->name, part)) {
	/* this case is ok */
    } else {
	/* return EXDEV if it's a clone to an alternate partition
	 * otherwise assume it's a move */
	if (vol.parentId != vol.id) {
	    *ec = EXDEV;
	    return NULL;
	}
    }
    *ec = 0;

# ifdef AFS_DEMAND_ATTACH_FS
    /* volume doesn't exist yet, but we must lock it to try to prevent something
     * else from reading it when we're e.g. half way through creating it (or
     * something tries to create the same volume at the same time) */
    locktype = VVolLockType(V_VOLUPD, 1);
    rc = VLockVolumeByIdNB(volumeId, partition, locktype);
    if (rc) {
	Log("VCreateVolume: vol %lu already locked by someone else\n",
	    afs_printable_uint32_lu(volumeId));
	*ec = VNOVOL;
	return NULL;
    }
# else /* AFS_DEMAND_ATTACH_FS */
    VLockPartition_r(partname);
# endif /* !AFS_DEMAND_ATTACH_FS */

    memset(&tempHeader, 0, sizeof(tempHeader));
    tempHeader.stamp.magic = VOLUMEHEADERMAGIC;
    tempHeader.stamp.version = VOLUMEHEADERVERSION;
    tempHeader.id = vol.id;
    tempHeader.parent = vol.parentId;
    vol.stamp.magic = VOLUMEINFOMAGIC;
    vol.stamp.version = VOLUMEINFOVERSION;
    vol.destroyMe = DESTROY_ME;
    snprintf(headerName, sizeof headerName, VFORMAT,
	     afs_printable_VolumeId_lu(vol.id));
    snprintf(volumePath, sizeof volumePath, "%s" OS_DIRSEP "%s",
	     VPartitionPath(partition), headerName);
    rc = stat(volumePath, &st);
    if (rc == 0 || errno != ENOENT) {
	if (rc == 0) {
	    Log("VCreateVolume: Header file %s already exists!\n",
		volumePath);
	    *ec = VVOLEXISTS;
	} else {
	    Log("VCreateVolume: Error %d trying to stat header file %s\n",
	        errno, volumePath);
	    *ec = VNOVOL;
	}
	goto bad_noheader;
    }
    device = partition->device;

    for (i = 0; i < MAXINODETYPE; i++) {
	struct afs_inode_info *p = &stuff[i];
	if (p->obsolete)
	    continue;
#ifdef AFS_NAMEI_ENV
	*(p->inode) =
	    IH_CREATE(NULL, device, VPartitionPath(partition), nearInode,
		      (p->inodeType == VI_LINKTABLE) ? vol.parentId : vol.id,
		      INODESPECIAL, p->inodeType, vol.parentId);
	if (!(VALID_INO(*(p->inode)))) {
	    if (errno == EEXIST && (p->inodeType == VI_LINKTABLE)) {
		/* Increment the reference count instead. */
		IHandle_t *lh;
		int code;

		*(p->inode) = namei_MakeSpecIno(vol.parentId, VI_LINKTABLE);
		IH_INIT(lh, device, parentId, *(p->inode));
		fdP = IH_OPEN(lh);
		if (fdP == NULL) {
		    IH_RELEASE(lh);
		    goto bad;
		}
		code = IH_INC(lh, *(p->inode), parentId);
		FDH_REALLYCLOSE(fdP);
		IH_RELEASE(lh);
		if (code < 0)
		    goto bad;
		continue;
	    }
	}
#else
	*(p->inode) =
	    IH_CREATE(NULL, device, VPartitionPath(partition), nearInode,
		      vol.id, INODESPECIAL, p->inodeType, vol.parentId);
#endif

	if (!VALID_INO(*(p->inode))) {
	    Log("VCreateVolume:  Problem creating %s file associated with volume header %s\n", p->description, volumePath);
	  bad:
	    if (handle)
		IH_RELEASE(handle);
	    RemoveInodes(stuff, device, vol.parentId, vol.id);
	    if (!*ec) {
		*ec = VNOVOL;
	    }
	    VDestroyVolumeDiskHeader(partition, volumeId, parentId);
	  bad_noheader:
# ifdef AFS_DEMAND_ATTACH_FS
	    if (locktype) {
		VUnlockVolumeById(volumeId, partition);
	    }
# endif /* AFS_DEMAND_ATTACH_FS */
	    return NULL;
	}
	IH_INIT(handle, device, vol.parentId, *(p->inode));
	fdP = IH_OPEN(handle);
	if (fdP == NULL) {
	    Log("VCreateVolume:  Problem iopen inode %s (err=%d)\n",
		PrintInode(stmp, *(p->inode)), errno);
	    goto bad;
	}
	if (FDH_PWRITE(fdP, (char *)&p->stamp, sizeof(p->stamp), 0) !=
	    sizeof(p->stamp)) {
	    Log("VCreateVolume:  Problem writing to inode %s (err=%d)\n",
		PrintInode(stmp, *(p->inode)), errno);
	    FDH_REALLYCLOSE(fdP);
	    goto bad;
	}
	FDH_REALLYCLOSE(fdP);
	IH_RELEASE(handle);
	nearInode = *(p->inode);
    }

    IH_INIT(handle, device, vol.parentId, tempHeader.volumeInfo);
    fdP = IH_OPEN(handle);
    if (fdP == NULL) {
	Log("VCreateVolume:  Problem iopen inode %s (err=%d)\n",
	    PrintInode(stmp, tempHeader.volumeInfo), errno);
	goto bad;
    }
    if (FDH_PWRITE(fdP, (char *)&vol, sizeof(vol), 0) != sizeof(vol)) {
	Log("VCreateVolume:  Problem writing to  inode %s (err=%d)\n",
	    PrintInode(stmp, tempHeader.volumeInfo), errno);
	FDH_REALLYCLOSE(fdP);
	goto bad;
    }
    FDH_CLOSE(fdP);
    IH_RELEASE(handle);

    VolumeHeaderToDisk(&diskHeader, &tempHeader);
    rc = VCreateVolumeDiskHeader(&diskHeader, partition);
    if (rc) {
	Log("VCreateVolume: Error %d trying to write volume header for "
	    "volume %" AFS_VOLID_FMT " on partition %s; volume not created\n", rc,
	    afs_printable_VolumeId_lu(vol.id), VPartitionPath(partition));
	if (rc == EEXIST) {
	    *ec = VVOLEXISTS;
	}
	goto bad;
    }

# ifdef AFS_DEMAND_ATTACH_FS
    if (locktype) {
	VUnlockVolumeById(volumeId, partition);
    }
# endif /* AFS_DEMAND_ATTACH_FS */
    return (VAttachVolumeByName_r(ec, partname, headerName, V_SECRETLY));
}