-1

I'm trying to make a file system in C. I have trouble with this portion of my code when I'm printing my values in the code below:

for (int i = 0; i<NUM_POINTERS; i++) {
            printf("before SB->root[%d]=%d\n", i, SB->root->pointers[i]);
        }
        write_blocks(0, 1, SB);
        for (int i = 0; i<NUM_POINTERS; i++) {
            printf("after SB->root[%d]=%d\n", i, SB->root->pointers[i]);
        }

my write_blocks method:

    int write_blocks(int start_address, int nblocks, void *buffer)
{
    int i, e, s;
    e = 0;
    s = 0;

    void* blockWrite = (void*) malloc(BLOCK_SIZE);

    /*Checks that the data requested is within the range of addresses of the disk*/
    if (start_address + nblocks > MAX_BLOCK)
    {
        printf("out of bound error\n");
        return -1;
    }

    /*Goto where the data is to be written on the disk*/
    fseek(fp, start_address * BLOCK_SIZE, SEEK_SET);

    /*For every block requested*/        
    for (i = 0; i < nblocks; ++i)
    {
        /*Pause until the latency duration is elapsed*/
        usleep(L);

        memcpy(blockWrite, buffer+(i*BLOCK_SIZE), BLOCK_SIZE);
        fwrite(blockWrite, BLOCK_SIZE, 1, fp);
        fflush(fp);
        s++;
    }
    free(blockWrite);

    /*If no failure return the number of blocks written, else return the negative number of failures*/
    if (e == 0)
        return s;
    else
        return e;
}

And here's what gets printed:

before SB->root[0]=1

before SB->root[1]=2

before SB->root[2]=3

before SB->root[3]=4

before SB->root[4]=5

before SB->root[5]=6

before SB->root[6]=7

before SB->root[7]=8

before SB->root[8]=9

before SB->root[9]=10

before SB->root[10]=11

before SB->root[11]=12

before SB->root[12]=13

before SB->root[13]=14

after SB->root[0]=1234344888

after SB->root[1]=32688

after SB->root[2]=3

after SB->root[3]=4

after SB->root[4]=5

after SB->root[5]=6

after SB->root[6]=7

after SB->root[7]=8

after SB->root[8]=9

after SB->root[9]=10

after SB->root[10]=11

after SB->root[11]=12

after SB->root[12]=13

after SB->root[13]=14

I don't understand why my first and second pointer value change?

Some additional information: SB is a superBlock here's my structures:

    typedef struct iNode
{
    int id;
    int size;
    int pointers[NUM_POINTERS];
} iNode;

typedef struct superBlock
{
    int magic_number;
    int block_size;
    int num_blocks;
    int num_inodes;
    iNode *root;
    iNode jNodes[20];
} superBlock;
Community
  • 1
  • 1
Nicky Mirfallah
  • 1,004
  • 4
  • 16
  • 38
  • 1
    The usleep and the comment "Pause until the latency duration is elapsed" raises suspicions. Is there something about this particular filesystem that is asynchronous? Also where does `e` get set? And did you intend to call write_blocks() with constant arguments of 0 and 1? – fearless_fool Apr 09 '17 at 00:37
  • 1
    There's a moderate chance that you've got a pointer to some no longer valid variable space that is being reused by the functions you're calling. I don't think what you show is an MCVE ([MCVE]). – Jonathan Leffler Apr 09 '17 at 01:02
  • Do you do anything else async that might write in memory between these instructions? How do you allocate `SB`? Is the memory shared between processes? Do you have any other threads? – Rad'Val Apr 09 '17 at 02:06
  • The problem happens with void* blockWrite = (void*) malloc(BLOCK_SIZE); If i comment that out it is fine. – Nicky Mirfallah Apr 09 '17 at 02:49
  • this line: `printf("before SB->root[%d]=%d, SB->root[%d]=%d\n", i, SB->root->pointers[i]);` has 4 format specifiers but only 2 parameters, so does not compile. Similar considerations apply to this line: `printf("after SB->root[%d]=%d, SB->root[%d]=%d\n", i, SB->root->pointers[i])` – user3629249 Apr 09 '17 at 03:50
  • when calling any of the heap allocation functions: (malloc, calloc, realloc), 1) the returned value has type `void*` so can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. 2) Always check (!=NULL) the returned value to assure the operation was successful – user3629249 Apr 09 '17 at 03:55
  • error messages should be output to `stderr`, not `stdout`, so this line: `printf("out of bound error\n");` should be: `fprintf( stderr, "out of bound error\n");` – user3629249 Apr 09 '17 at 03:58
  • this line: `fseek(fp, start_address * BLOCK_SIZE, SEEK_SET);` says every access is to be on a block boundary. If `start_address` is very large, then the write could be a VERY large offset into the file. When calling `fseek()`, always check (!= -1) to assure the operation was successful – user3629249 Apr 09 '17 at 04:03
  • the variable `e` is never updated after initially being set to 0. So returning that value will not indicate to the caller what problem occurred. – user3629249 Apr 09 '17 at 04:07
  • the parameter: `start_address` is very misleading. Suggest something like: `startBlockNum` – user3629249 Apr 09 '17 at 04:09
  • How are you allocating and initializing the SB pointer in the first place? – Mahmoud Fayez Apr 09 '17 at 04:58
  • Not the cause of your issue, but the **return type** of `malloc` is `(void *)`, there is NO need for the cast, see: [**Do I cast the result of malloc?**](http://stackoverflow.com/q/605845/995714) – David C. Rankin Apr 09 '17 at 05:27

1 Answers1

1

Is this single threaded? Does the modified SB->root[0,1] contain the data you are trying to write? What is your BLOCK_SIZE?

I suspect the problem is outside of write_blocks(). My best guess would be that you accidentally freed SB somewhere and malloc gave you the same address. After the malloc check (print or debugger) both buffer and blockWrite and make sure they are different and valid.

Unrelated Issues:

  • printf has more % than params
  • You should check the return of malloc
  • e is never set
  • s and i are equal. AKA redundant.
  • Out of bounds error causes a memory leak (since it is after the malloc)
  • usleep is strange perhaps you want fsync?
Richard
  • 241
  • 1
  • 6
  • I am checking SB right after I use the function so no freeing is happening. The write_blocks function is not written by me so I don't care about e not being set – Nicky Mirfallah Apr 09 '17 at 04:29
  • What are the addresses of SB and blockWrite? If the problem was that SB was freed. It would have to have been freed before calling write_blocks. Checking SB doesn't prove that it wasn't freed. In C the pointer sill appears valid after a free. – Richard Apr 10 '17 at 02:15