int soAttachLogicalCluster(SOSuperBlock *p_sb, uint32_t nInode, uint32_t clustInd, uint32_t nLClust) { int stat; // function return control uint32_t ind_prev, ind_next; // logical cluster number of adjacent clusters SODataClust dc, dc_prev, dc_next; // data clusters to be updated /* temos de verificar se o prev está bem ligado e se o next tambem esta bem ligado */ if (clustInd == 0) { ind_prev = NULL_CLUSTER; } else { if ((stat = soHandleFileCluster(nInode, clustInd - 1, GET, &ind_prev)) != 0) { return 0; } if (ind_prev != NULL_CLUSTER) { if ((stat = soReadCacheCluster(p_sb->dZoneStart + ind_prev * BLOCKS_PER_CLUSTER, &dc_prev)) != 0) { return stat; } } } if (clustInd == MAX_FILE_CLUSTERS) { ind_next = NULL_CLUSTER; } else { if ((stat = soHandleFileCluster(nInode, clustInd + 1, GET, &ind_next)) !=0 ) { return 0; } if (ind_next != NULL_CLUSTER) { if ((stat = soReadCacheCluster(p_sb->dZoneStart + ind_next * BLOCKS_PER_CLUSTER, &dc_next)) != 0) { return stat; } } } if ((ind_prev != NULL_CLUSTER || ind_next != NULL_CLUSTER)) { if ((stat = soReadCacheCluster(p_sb->dZoneStart + nLClust * BLOCKS_PER_CLUSTER, &dc)) != 0) { return stat; } if (ind_prev != NULL_CLUSTER) { dc.prev = ind_prev; dc_prev.next = nLClust; if ((stat = soWriteCacheCluster(p_sb->dZoneStart + ind_prev * BLOCKS_PER_CLUSTER, &dc_prev)) != 0) { return stat; } } if (ind_next != NULL_CLUSTER) { dc.next = ind_next; dc_next.prev = nLClust; if ((stat = soWriteCacheCluster(p_sb->dZoneStart + ind_next * BLOCKS_PER_CLUSTER, &dc_next)) !=0 ) { return stat; } } if ((stat = soWriteCacheCluster(p_sb->dZoneStart + nLClust * BLOCKS_PER_CLUSTER, &dc)) != 0) { return stat; } } return 0; }
int soReadFileCluster (uint32_t nInode, uint32_t clustInd, SODataClust *buff) { soColorProbe (411, "07;31", "soReadFileCluster (%"PRIu32", %"PRIu32", %p)\n", nInode, clustInd, buff); int stat, i; SOSuperBlock *p_sb; SODataClust cluster; uint32_t numDC, nFClust; if( (stat = soLoadSuperBlock()) != 0){ return stat; } p_sb = soGetSuperBlock(); if(nInode >= p_sb->iTotal){ return -EINVAL; } if(buff == NULL){ return -EINVAL; } if(clustInd >= MAX_FILE_CLUSTERS){ return -EINVAL; } if((stat = soHandleFileCluster(nInode, clustInd, GET, &numDC)) != 0){ return stat; } if(numDC == NULL_CLUSTER){ for(i = 0; i < BSLPC; i++) { buff->info.data[i] = '\0'; } } else{ nFClust = p_sb->dZoneStart + numDC * BLOCKS_PER_CLUSTER; if( (stat = soReadCacheCluster(nFClust, &cluster)) != 0){ return stat; } memcpy(buff, &cluster, sizeof(SODataClust)); if((stat = soWriteCacheCluster(nFClust, &cluster)) != 0){ return stat; } } if( (stat = soStoreSuperBlock()) != 0){ return stat; } 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 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; }