Tuesday, October 31, 2006
The good, the bad, and the velmu
If globals are bad and goto is bad and Linux is good, then how explain this function from the Linux kernel? And why would anyone ever pass in a global as a function parameter?
static int check_free_space(struct file *file)
{
struct kstatfs sbuf;}
int res;
int act;
sector_t resume;
sector_t suspend;
spin_lock(&acct_globals.lock);
res = acct_globals.active;
if (!file || !acct_globals.needcheck)
goto out;
spin_unlock(&acct_globals.lock);
/* May block */
if (vfs_statfs(file->f_dentry, &sbuf))
return res;
suspend = sbuf.f_blocks * SUSPEND;
resume = sbuf.f_blocks * RESUME;
sector_div(suspend, 100);
sector_div(resume, 100);
if (sbuf.f_bavail <= suspend)
act = -1;
else if (sbuf.f_bavail >= resume)
act = 1;
else
act = 0;
/*
* If some joker switched acct_globals.file under
* us we'ld better be
* silent and _not_ touch anything.
*/
spin_lock(&acct_globals.lock);
if (file != acct_globals.file) {
if (act)
res = act>0;
goto out;
}
if (acct_globals.active) {
if (act < active =" 0;"> 0) {
acct_globals.active = 1;
printk(KERN_INFO "Process accounting resumed\n");
}
}
del_timer(&acct_globals.timer);
acct_globals.needcheck = 0;
acct_globals.timer.expires = jiffies + ACCT_TIMEOUT*HZ;
add_timer(&acct_globals.timer);
res = acct_globals.active;
out:
spin_unlock(&acct_globals.lock);
return res;