示例#1
0
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;
}
示例#2
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;
}
示例#3
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;
}
示例#4
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;
}