0

For one of my CS classes we are creating a mini EXT2 file system. In this program I have to make the functions mkdir and creat. In both these functions we call a function called iput which looks like this:

int iput(MINODE *mip)
{
  // dispose of minode pointed by mip
  // Code in Chapter 11.7.2
  INODE *ip;
  int i, block, offset; 
  char buf[BLKSIZE];
  if (mip==0)
  {
    return;
  }
  mip->refCount--;
  printf("mip->refcount = %d\n", mip->refCount);
  if (mip->refCount > 0)
  {
    return 0;
  }
  if (mip->dirty == 0)
  {
    return 0;
  } 
  // dec refCount by 1
  // still has user
  // no need to write back
  // write INODE back to disk
  block = (mip->ino - 1) / 8 + inode_start; 
  offset = (mip->ino - 1) % 8;
  // get block containing this inode
  get_block(mip->dev, block, buf);
  printf("get block works in iput\n");
  ip = (INODE *)buf + offset; // ip points at INODE
  *ip = mip->inode; // copy INODE to inode in block 
  put_block(mip->dev, block, buf); // write back to disk 
  printf("put block works in iput\n");
  //midalloc(mip); // 
  mip->refCount = 0;
  return 1;
} 

Minode is just a struct wrapper that holds an inode inside it, along with other variables. Here is the code for my creat function:

int my_creat(MINODE *pip, char *name)
{
  MINODE *mip;
  int ino = ialloc(pip->dev);
  int bno = balloc(pip->dev);

  mip = iget(dev,ino);
  INODE *ip = &mip->inode;
  ip->i_mode = 0x81A4;
  ip->i_uid = running->uid;
  ip->i_gid = running->gid;
  ip->i_size = 0;
  ip->i_links_count = 1;
  ip->i_atime = time(0L);
  ip->i_ctime = time(0L);
  ip->i_mtime = time(0L);
  ip->i_blocks = 2;
  ip->i_block[0] = bno;
  for (int i = 1; i < 15; i++)
  {
    ip->i_block[i] = 0;
  }
  mip->dirty = 1;
  iput(mip);
  char buf[BLKSIZE];

  dp = (DIR *)buf;
  dp->inode = ino;
  strncpy(dp->name, ".", 1);
  dp->name_len = 1;
  dp->rec_len = 12;

  char *cp;
  cp = buf + 12;
  dp = (DIR*)cp;
  dp->inode = pip->ino;
  dp->name_len = 2;
  strncpy(dp->name, "..", 2);
  dp->rec_len = BLKSIZE - 12;
  put_block(pip->dev,bno,buf);
  enter_name(pip,ino,name);
}

And here is the code for my mkdir function:

int mymkdir(MINODE *pip, char *name)
{
  MINODE *mip;
  int ino = ialloc(pip->dev);
  int bno = balloc(pip->dev);
  printf("bno inside mymkdir = %d\n", bno);
  printf("ino inside mymkdir = %d\n", ino);
  char buf[BLKSIZE];
  mip = iget(dev,ino);
  printf("goes over iget again\n");
  INODE *ip = &mip->inode;
  ip->i_mode = 0x41ED;
  ip->i_uid = running->uid;
  ip->i_gid = running->gid;
  ip->i_size = BLKSIZE;
  ip->i_links_count = 2;
  ip->i_atime = time(0L);
  ip->i_ctime = time(0L);
  ip->i_mtime = time(0L);
  ip->i_blocks = 2;
  ip->i_block[0] = bno;
  for (int i = 1; i < 15; i++)
  {
    ip->i_block[i] = 0;
  }
  mip->dirty = 1;
  iput(mip);
  printf("goes over iput");
 

  dp = (DIR *)buf;
  dp->inode = ino;
  strncpy(dp->name, ".", 1);
  dp->name_len = 1;
  dp->rec_len = 12;
  char *cp;
  cp += dp->rec_len;
  dp = (DIR*)cp;
  dp->inode = pip->ino;
  dp->name_len = 2;
  strncpy(dp->name, "..",2);
  dp->rec_len = BLKSIZE - 12;
  put_block(pip->dev,bno,buf);
  enter_name(pip,ino,name);
}

They are virtually the exact same, but for whatever reason after calling iput in mkdir it crashes and gives me a segmentation fault error, however that does not happen in my creat function. This makes no sense as they are virtually the exact same functions and thus one shouldn't be working if the other isn't working too. Also, they are in the same file, mkdir_creat.c, but the iput function is inside a different C file, and im running it through the linux terminal by using gcc main.c mkdir_creat.c etc. Any help on to why the mkdir function is giving a segmentation fault error would be much appreciated! Thank you!

  • If you have learned how to use a debugger yet, then now is the perfect time. With a debugger you can catch crashes as they happen, and locate where in your code it happens as well as be alt to examine variable and their variables at the time of the crash. – Some programmer dude Dec 09 '20 at 07:14
  • Also, unless the crash happens in some part of the code that is 100% unique to `mkdir` then you probably have the same problem in `creat`, it's just that the *undefined behavior* leading to the crash manifests in some other way in the `creat` function. – Some programmer dude Dec 09 '20 at 07:15
  • `-fsanitize=address` can find the cause of these kinds of problems. – ikegami Dec 09 '20 at 07:16
  • @ikegami how do i use -fsanitize=address? – Daniel Lichtchouk Dec 09 '20 at 07:28
  • It's a gcc (and clang?) option. – ikegami Dec 09 '20 at 07:29
  • While talking about GCC options, always enable more warnings from the compiler. The compiler can detect many problems that aren't errors according to the C specification, but still can lead to problems. I suggest you add at least the `-Wall` flag when building. And treat all warnings as errors that must be fixed. So your command to build could look like `gcc -g -Wall -fsanitize=address mkdir_creat.c -o mkdir_creat` (or similar, depending on other flags and source files and libraries you build with). The `-g` option is to add debug information. – Some programmer dude Dec 09 '20 at 07:34
  • Also on the subject of warnings and warning-flags, I personally always build with *at least* `-Wall -Wextra -Wpedantic`. And for debug-builds I also add `-Werror` to turn all warnings into actual errors. – Some programmer dude Dec 09 '20 at 07:35

0 Answers0