static struct buffer_head *get_free_buffer(void) { register struct buffer_head *bh; for (;;) { bh = bh_lru; do { #ifdef CONFIG_FS_EXTERNAL_BUFFER if (bh->b_count == 0 && !bh->b_dirty && !bh->b_lock && !bh->b_data) #else if (bh->b_count == 0 && !bh->b_dirty && !bh->b_lock) #endif { put_last_lru(bh); return bh; } } while((bh = bh->b_next_lru) != NULL); #if 0 fsync_dev(0); /* This causes a sleep until another process brelse's */ sleep_on(&bufwait); #endif sync_buffers(0, 0); } }
struct inode *__iget(register struct super_block *sb, ino_t inr /*,int crossmntp */ ) { register struct inode *inode; debug3("iget called(%x, %d, %d)\n", sb, inr, 0 /* crossmntp */ ); if (!sb) panic("VFS: iget with sb==NULL"); repeat: do { inode = first_inode; do { if (inode->i_dev == sb->s_dev && inode->i_ino == inr) goto found_it; } while ((inode = inode->i_prev) != first_inode); debug("iget: getting an empty inode...\n"); } while (!(inode = get_empty_inode())); debug1("iget: got one... (%x)!\n", empty); inode->i_sb = sb; inode->i_dev = sb->s_dev; inode->i_flags = ((unsigned short int) sb->s_flags); inode->i_ino = inr; put_last_lru(inode); debug("iget: Reading inode\n"); read_inode(inode); debug("iget: Read it\n"); goto return_it; found_it: if (!inode->i_count) nr_free_inodes--; inode->i_count++; wait_on_inode(inode); if (inode->i_dev != sb->s_dev || inode->i_ino != inr) { printk("Whee.. inode changed from under us. Tell _.\n"); iput(inode); goto repeat; } if ( /* crossmntp && */ inode->i_mount) { struct inode *tmp = inode->i_mount; tmp->i_count++; iput(inode); inode = tmp; wait_on_inode(inode); } return_it: return inode; }
struct buffer_head *getblk(kdev_t dev, block_t block) { register struct buffer_head *bh; /* If there are too many dirty buffers, we wake up the update process * now so as to ensure that there are still clean buffers available * for user processes to use (and dirty) */ do { bh = get_hash_table(dev, block); if (bh != NULL) { if (buffer_clean(bh) && buffer_uptodate(bh)) put_last_lru(bh); return bh; } /* I think the following check is redundant * So I will remove it for now */ } while(find_buffer(dev, block)); /* * Create a buffer for this job. */ bh = get_free_buffer(); /* OK, FINALLY we know that this buffer is the only one of its kind, * and that it's unused (b_count=0), unlocked (buffer_locked=0), and clean */ bh->b_count = 1; bh->b_dirty = 0; bh->b_lock = 0; bh->b_uptodate = 0; bh->b_dev = dev; bh->b_blocknr = block; bh->b_seg = kernel_ds; return bh; }