I was going through the Linux source code and here I stumbled over this function:
static int check_free_space(struct bsd_acct_struct *acct)
{
    struct kstatfs sbuf;
    if (time_is_after_jiffies(acct->needcheck))
        goto out;
    /* May block */
    if (vfs_statfs(&acct->file->f_path, &sbuf))
        goto out;
    if (acct->active) {
        u64 suspend = sbuf.f_blocks * SUSPEND;
        do_div(suspend, 100);
        if (sbuf.f_bavail <= suspend) {
            acct->active = 0;
            pr_info("Process accounting paused\n");
        }
    } else {
        u64 resume = sbuf.f_blocks * RESUME;
        do_div(resume, 100);
        if (sbuf.f_bavail >= resume) {
            acct->active = 1;
            pr_info("Process accounting resumed\n");
        }
    }
    acct->needcheck = jiffies + ACCT_TIMEOUT*HZ;
out:
    return acct->active;
}
I can't find much sense in Marco's use of goto, especially since it leads to a return statement. Why wasn't the function re-written like this:
static int check_free_space(struct bsd_acct_struct * acct) {
  struct kstatfs sbuf;
  if (time_is_after_jiffies(acct->needcheck) ||
    vfs_statfs( &acct->file->f_path, & sbuf)) {
    //latter may block
    return acct->active;
  }
  if (acct->active) {
    u64 suspend = sbuf.f_blocks * SUSPEND;
    do_div(suspend, 100);
    if (sbuf.f_bavail <= suspend) {
      acct->active = 0;
      pr_info("Process accounting paused\n");
    }
  } else {
    u64 resume = sbuf.f_blocks * RESUME;
    do_div(resume, 100);
    if (sbuf.f_bavail >= resume) {
      acct->active = 1;
      pr_info("Process accounting resumed\n");
    }
  }
  acct->needcheck = jiffies + ACCT_TIMEOUT * HZ;
}
I've been taught that goto could indeed be useful if used to break out of a nested loop or for memory cleanup. Neither of this is a case here, so why did Marco go for the gotos? There must be some kind of valid reason, right?
 
     
    