int soHandleDIndirect(SOSuperBlock *p_sb, uint32_t nInode, SOInode *p_inode, uint32_t clustInd, uint32_t op, uint32_t *p_outVal) { uint32_t ref_Soffset, ref_Doffset; // reference positions int stat; // function return status control SODataClust *p_dcS, *p_dcD; // pointer to single and double reference data cluster uint32_t nclust; // pointer no cluster number uint32_t i; // auxiliary variable for counting uint32_t clusterref_pos; // cluster reference position if (op > 4) return -EINVAL; // calculate single indirect and double indirect reference position ref_Soffset = (clustInd - N_DIRECT - RPC) / RPC; ref_Doffset = (clustInd - N_DIRECT - RPC) % RPC; switch (op) { case GET: { if (p_inode->i2 == NULL_CLUSTER) { *p_outVal = NULL_CLUSTER; } else { if ((stat = soLoadSngIndRefClust(p_sb->dZoneStart + p_inode->i2 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dcS = soGetSngIndRefClust(); if (p_dcS->info.ref[ref_Soffset] == NULL_CLUSTER) { *p_outVal = NULL_CLUSTER; } else { if ((stat = soLoadDirRefClust(p_sb->dZoneStart + p_dcS->info.ref[ref_Soffset] * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dcD = soGetDirRefClust(); *p_outVal = p_dcD->info.ref[ref_Doffset]; } } return 0; } case ALLOC: { if (p_inode->i2 == NULL_CLUSTER) { if ((stat = soAllocDataCluster(nInode, &nclust)) != 0) return stat; p_inode->i2 = nclust; p_inode->cluCount++; if ((stat = soLoadSngIndRefClust(p_sb->dZoneStart + p_inode->i2 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dcS = soGetSngIndRefClust(); for (i = 0; i < RPC; i++) p_dcS->info.ref[i] = NULL_CLUSTER; if ((stat = soStoreSngIndRefClust()) != 0) return stat; } if ((stat = soLoadSngIndRefClust(p_sb->dZoneStart + p_inode->i2 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dcS = soGetSngIndRefClust(); if (p_dcS->info.ref[ref_Soffset] == NULL_CLUSTER) { if ((stat = soAllocDataCluster(nInode, &nclust)) != 0) return stat; p_dcS->info.ref[ref_Soffset] = nclust; p_inode->cluCount++; if ((stat = soLoadDirRefClust(p_sb->dZoneStart + p_dcS->info.ref[ref_Soffset] * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dcD = soGetDirRefClust(); for (i = 0; i < RPC; i++) p_dcD->info.ref[i] = NULL_CLUSTER; } if ((stat = soLoadDirRefClust(p_sb->dZoneStart + p_dcS->info.ref[ref_Soffset] * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dcD = soGetDirRefClust(); if (p_dcD->info.ref[ref_Doffset] != NULL_CLUSTER) return -EDCARDYIL; if ((stat = soAllocDataCluster(nInode, &nclust)) != 0) return stat; p_dcD->info.ref[ref_Doffset] = *p_outVal = nclust; p_inode->cluCount++; if ((stat = soAttachLogicalCluster(p_sb, nInode, clustInd, p_dcD->info.ref[ref_Doffset])) != 0) return stat; if ((stat = soStoreDirRefClust()) != 0) return stat; if ((stat = soStoreSngIndRefClust()) != 0) return stat; return 0; } case FREE: case FREE_CLEAN: case CLEAN: { if (p_inode->i2 == NULL_CLUSTER) return -EDCNOTIL; if ((stat = soLoadSngIndRefClust(p_sb->dZoneStart + p_inode->i2 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dcS = soGetSngIndRefClust(); if (p_dcS->info.ref[ref_Soffset] == NULL_CLUSTER) return -EDCNOTIL; if ((stat = soLoadDirRefClust(p_sb->dZoneStart + p_dcS->info.ref[ref_Soffset] * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dcD = soGetDirRefClust(); if (p_dcD->info.ref[ref_Doffset] == NULL_CLUSTER) return -EDCNOTIL; if (op != CLEAN) { if ((stat = soFreeDataCluster(p_dcD->info.ref[ref_Doffset]) != 0)) return stat; if (op == FREE) return 0; } if ((stat = soCleanLogicalCluster(p_sb, nInode, p_dcD->info.ref[ref_Doffset])) != 0) return stat; p_dcD->info.ref[ref_Doffset] = NULL_CLUSTER; p_inode->cluCount--; for (clusterref_pos = 0; clusterref_pos < RPC; clusterref_pos++) { if (p_dcD->info.ref[clusterref_pos] != NULL_CLUSTER) break; } if ((stat = soStoreDirRefClust()) != 0) return stat; if (clusterref_pos == RPC) { if ((stat = soFreeDataCluster(p_dcS->info.ref[ref_Soffset])) != 0) return stat; if ((stat = soCleanLogicalCluster(p_sb, nInode, p_dcS->info.ref[ref_Soffset]) != 0)) return stat; p_dcS->info.ref[ref_Soffset] = NULL_CLUSTER; p_inode->cluCount--; if ((stat = soStoreSngIndRefClust()) != 0) return stat; for (clusterref_pos = 0; clusterref_pos < RPC; clusterref_pos++) { if (p_dcS->info.ref[clusterref_pos] != NULL_CLUSTER) break; } if (clusterref_pos == RPC) { if ((stat = soFreeDataCluster(p_inode->i2)) != 0) return stat; if ((stat = soCleanLogicalCluster(p_sb, nInode, p_inode->i2)) != 0) return stat; p_inode->i2 = NULL_CLUSTER; p_inode->cluCount--; return 0; } return 0; } if ((stat = soStoreSngIndRefClust()) != 0) return stat; return 0; } default: { p_outVal = NULL; return -EINVAL; } } return 0; }
int soHandleFileClusters (uint32_t nInode, uint32_t clustIndIn, uint32_t op) { soColorProbe (414, "07;31", "soHandleFileClusters (%"PRIu32", %"PRIu32", %"PRIu32")\n", nInode, clustIndIn, op); SOSuperBlock* p_sb; SOInode inode; SODataClust *clust1, *clust2; uint32_t stat, ind, ref_offset, ref_Soffset, ref_Doffset; if((stat = soLoadSuperBlock())){ return stat; } p_sb = soGetSuperBlock(); if(nInode < 0 || nInode >= p_sb->iTotal){ return -EINVAL; } if(clustIndIn >= MAX_FILE_CLUSTERS){ return -EINVAL; } if(op < 2 || op > 4){ return -EINVAL; } if(op == CLEAN){ if ((stat=soReadInode(&inode,nInode,FDIN))!=0){ return stat; } }else{ if ((stat=soReadInode(&inode,nInode,IUIN))!=0){ return stat; } } /*Referencas Duplamente Indirectas*/ if(inode.i2 != NULL_CLUSTER){ if ((stat = soLoadSngIndRefClust((inode.i2 * BLOCKS_PER_CLUSTER) + p_sb->dZoneStart)) != 0){ return stat; } clust2 = soGetSngIndRefClust(); ind = N_DIRECT + RPC; //tamanho da tabela das referencias simplesmentre indirectas for(;inode.i2 != NULL_CLUSTER && ind < MAX_FILE_CLUSTERS;){ ref_Soffset = (ind - (RPC + N_DIRECT)) / RPC; ref_Doffset = (ind - N_DIRECT - RPC) % RPC; if(clust2->info.ref[ref_Soffset] != NULL_CLUSTER){ if((stat = soLoadDirRefClust((clust2->info.ref[ref_Soffset]* BLOCKS_PER_CLUSTER) + p_sb->dZoneStart)) != 0){ return stat; } clust1 = soGetDirRefClust(); for(; ref_Doffset < RPC; ref_Doffset++, ind++){ if(clust1->info.ref[ref_Doffset] != NULL_CLUSTER && clustIndIn <= ind){ if((stat = soHandleFileCluster(nInode, ind, op, NULL)) != 0){ return stat; } } } }else{ ind += RPC; } } } /*Referencias Simplesmente Indirectas*/ if(inode.i1 != NULL_CLUSTER){ if((stat = soLoadDirRefClust((inode.i1 * BLOCKS_PER_CLUSTER) + p_sb->dZoneStart)) != 0){ return stat; } clust1 = soGetDirRefClust(); ind = N_DIRECT; for(; inode.i1 != NULL_CLUSTER && ind < N_DIRECT + RPC;ind++){ ref_offset = ind - N_DIRECT; if(clust1->info.ref[ref_offset] != NULL_CLUSTER && clustIndIn <= ind){ if((stat = soHandleFileCluster(nInode, ind, op, NULL)) != 0 ){ return stat; } } } } /*Referencias Directas*/ ind = 0; for(; ind < N_DIRECT; ind++){ if(inode.d[ind] != NULL_CLUSTER && clustIndIn <= ind){ if((stat = soHandleFileCluster(nInode, ind, op, NULL)) != 0){ return stat; } } } return 0; }
int soHandleSIndirect(SOSuperBlock *p_sb, uint32_t nInode, SOInode *p_inode, uint32_t clustInd, uint32_t op, uint32_t *p_outVal) { uint32_t ref_offset; // reference position int stat; // function return status control SODataClust *p_dc; // pointer to a data cluster uint32_t nclust; // number of the allocated data cluster called in soAllocDataCluster uint32_t i; // auxiliary variable for counting uint32_t clusterref_pos; // custer reference position if (op > 4) return -EINVAL; // calculate the offset for the single indirect reference // ref_offset = (clustInd - N_DIRECT) % RPC; ref_offset = clustInd - N_DIRECT; switch (op) { case GET: { if (p_inode->i1 == NULL_CLUSTER) { *p_outVal = NULL_CLUSTER; } else { if ((stat = soLoadDirRefClust(p_sb->dZoneStart + p_inode->i1 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dc = soGetDirRefClust(); *p_outVal = p_dc->info.ref[ref_offset]; } return 0; } case ALLOC: { if (p_inode->i1 == NULL_CLUSTER) { if ((stat = soAllocDataCluster(nInode, &nclust)) != 0) return stat; p_inode->i1 = nclust; p_inode->cluCount++; if ((stat = soLoadDirRefClust(p_sb->dZoneStart + p_inode->i1 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dc = soGetDirRefClust(); for (i = 0; i < RPC; i++) p_dc->info.ref[i] = NULL_CLUSTER; if ((stat = soStoreDirRefClust()) != 0) return stat; } if ((stat = soLoadDirRefClust(p_sb->dZoneStart + p_inode->i1 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dc = soGetDirRefClust(); if (p_dc->info.ref[ref_offset] != NULL_CLUSTER) return -EDCARDYIL; if ((stat = soAllocDataCluster(nInode, &nclust)) != 0) return stat; if ((stat = soLoadDirRefClust(p_sb->dZoneStart + p_inode->i1 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dc = soGetDirRefClust(); p_dc->info.ref[ref_offset] = *p_outVal = nclust; p_inode->cluCount++; if ((stat = soStoreDirRefClust()) != 0) return stat; if ((stat = soAttachLogicalCluster(p_sb, nInode, clustInd, p_dc->info.ref[ref_offset])) != 0) return stat; if ((stat = soStoreDirRefClust()) != 0) return stat; //printf("clucount = %u\n", p_inode->cluCount); return 0; } case FREE: case FREE_CLEAN: case CLEAN: { p_outVal = NULL; if (p_inode->i1 == NULL_CLUSTER) return -EDCNOTIL; if ((stat = soLoadDirRefClust(p_sb->dZoneStart + p_inode->i1 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_dc = soGetDirRefClust(); if (p_dc->info.ref[ref_offset] == NULL_CLUSTER) return -EDCNOTIL; if (p_dc->stat != nInode) return -EWGINODENB; if (op != CLEAN) { if ((stat = soFreeDataCluster(p_dc->info.ref[ref_offset])) != 0) return stat; if (op == FREE) return 0; } if ((stat = soCleanLogicalCluster(p_sb, nInode, p_dc->info.ref[ref_offset])) != 0) return stat; p_dc->info.ref[ref_offset] = NULL_CLUSTER; p_inode->cluCount--; for (clusterref_pos = 0; clusterref_pos < RPC; clusterref_pos++) { if (p_dc->info.ref[clusterref_pos] != NULL_CLUSTER) break; } if (clusterref_pos == RPC) { if ((stat = soStoreDirRefClust()) != 0) return stat; if ((stat = soFreeDataCluster(p_inode->i1)) != 0) return stat; if ((stat = soCleanLogicalCluster(p_sb, nInode, p_inode->i1)) != 0) return stat; p_inode->cluCount--; p_inode->i1 = NULL_CLUSTER; return 0; } if ((stat = soStoreDirRefClust()) != 0) return stat; return 0; } default: { p_outVal = NULL; return -EINVAL; } } return -EINVAL; }
int soCleanDataCluster (uint32_t nInode, uint32_t nLClust) { soColorProbe (415, "07;31", "soCleanDataCluster (%"PRIu32", %"PRIu32")\n", nInode, nLClust); int stat, i, j; // stat = error stat of the function; i= auxiliary variable for iterations SOSuperBlock *p_sb; // pointer to the super block SOInode inode; // inode instance to clean the references uint32_t clusterCount = 0; // physical number of the cluster SODataClust *p_clusterS, *p_clusterD; // cluster pointers to direct and indirect references // Load the super block if((stat = soLoadSuperBlock()) != 0) return stat; //get pointer to the super block p_sb = soGetSuperBlock(); //check if inode is in the allowed parameters if(nInode >= p_sb->iTotal) return -EINVAL; //check if nLClust is in allowed parameters if (!(nLClust > 0 && nLClust < p_sb->dZoneTotal)) return -EINVAL; //read nInode data into inode if((stat = soReadInode(&inode, nInode, FDIN)) != 0) return stat; //Direct References for(i = 0; i < N_DIRECT; i++){ if(inode.d[i] != NULL_CLUSTER){ if(inode.d[i] == nLClust){ //if cluster is in d[i] clean it if((stat = soHandleFileCluster(nInode, i, CLEAN, NULL)) != 0) return stat; return 0; } else clusterCount++; } //if we parsed all the clusters in the inode and it's not found if(clusterCount == inode.cluCount) return -EDCINVAL; } //Direct References Cluster //if nLClust is i1 if(inode.i1 == nLClust){ if ((stat = soLoadDirRefClust(p_sb->dZoneStart + inode.i1 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_clusterS = soGetDirRefClust(); //clean all references in i1 for(i = 0; i < RPC; i++){ if(p_clusterS->info.ref[i-N_DIRECT] != NULL_CLUSTER){ if((stat = soHandleFileCluster(nInode, i + N_DIRECT, CLEAN, NULL)) != 0) return stat; } } return 0; } //if nLClust is not i1 it can be any of the RPC else{ if((stat = soLoadDirRefClust(p_sb->dZoneStart + inode.i1 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_clusterS = soGetDirRefClust(); for(i = 0; i < RPC; i++){ if(p_clusterS->info.ref[i] != NULL_CLUSTER){ //if nLCuster is found clean it if(p_clusterS->info.ref[i] == nLClust){ if((stat = soHandleFileCluster(nInode, i + N_DIRECT, CLEAN, NULL)) != 0) return stat; return 0; } else clusterCount++; } //if we parsed all the clusters in the inode and it's not found if(clusterCount == inode.cluCount) return -EDCINVAL; } } //Referencias duplamente indirectas //if nLClust is i2 if(inode.i2 == nLClust){ if ((stat = soLoadSngIndRefClust(p_sb->dZoneStart + inode.i2 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_clusterS = soGetSngIndRefClust(); //clean all clusters in indirect and direct references for(i = 0; i < RPC; i++){ if(p_clusterS->info.ref[i] != NULL_CLUSTER){ if ((stat = soLoadDirRefClust(p_sb->dZoneStart + p_clusterS->info.ref[i] * BLOCKS_PER_CLUSTER)) != 0) return stat; p_clusterD = soGetDirRefClust(); for(j = 0; j < RPC; j++){ if(p_clusterD->info.ref[j] != NULL_CLUSTER) if((stat = soHandleFileCluster(nInode, N_DIRECT + (RPC*(i+1)) + j, CLEAN, NULL)) != 0) return stat; } } } return 0; } //if nLClust is not i2 else{ if ((stat = soLoadSngIndRefClust(p_sb->dZoneStart + inode.i2 * BLOCKS_PER_CLUSTER)) != 0) return stat; p_clusterS = soGetSngIndRefClust(); //parse i2 references for(i = 0; i < RPC; i++){ if(p_clusterS->info.ref[i] != NULL_CLUSTER){ //if nLClust is in direct references if(p_clusterS->info.ref[i] == nLClust){ if ((stat = soLoadDirRefClust(p_sb->dZoneStart + p_clusterS->info.ref[i] * BLOCKS_PER_CLUSTER)) != 0) return stat; p_clusterD = soGetDirRefClust(); //clean all indirect references for the direct reference entry for(j = 0; j < RPC; j++){ if(p_clusterD->info.ref[j] != NULL_CLUSTER) if((stat = soHandleFileCluster(nInode, N_DIRECT + (RPC*(i+1)) + j, CLEAN, NULL)) != 0) return stat; } } //if it's not in the direct references, let's look in all the indirect else{ if ((stat = soLoadDirRefClust(p_sb->dZoneStart + p_clusterS->info.ref[i] * BLOCKS_PER_CLUSTER)) != 0) return stat; p_clusterD = soGetDirRefClust(); //search all the indirect references for each of the direct references for(j = 0; j < RPC; j++){ if(p_clusterD->info.ref[j] != NULL_CLUSTER){ //if nLCluster is found clean it if(p_clusterD->info.ref[j] == nLClust){ if((stat = soHandleFileCluster(nInode, N_DIRECT + (RPC*(i+1)) + j, CLEAN, NULL)) != 0) return stat; return 0; } else clusterCount++; } if(clusterCount == inode.cluCount) return -EDCINVAL; } clusterCount++; } //if we parsed all the clusters in the inode and it's not found if(clusterCount == inode.cluCount) return -EDCINVAL; } } } return 0; }