/* 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; }
/* 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; }
/* 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; }
/* 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; }
/* 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; }
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; }
/* 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; }
/* 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; }
/* 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; }
/* 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; }
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; }
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)); }