struct inode *__iget(register struct super_block *sb, ino_t inr /*,int crossmntp */ ) { int i; register struct inode *inode; register struct inode *empty = NULL; debug3("iget called(%x, %d, %d)\n", sb, inr, 0 /* crossmntp */ ); if (!sb) panic("VFS: iget with sb==NULL"); repeat: inode = inode_block; for (i = NR_INODE; i; i--, inode++) { if (inode->i_dev == sb->s_dev && inode->i_ino == inr) { goto found_it; } } if (!empty) { debug("iget: getting an empty inode...\n"); empty = get_empty_inode(); debug1("iget: got one... (%x)!\n", empty); if (empty) goto repeat; return NULL; } inode = empty; inode->i_sb = sb; inode->i_dev = sb->s_dev; inode->i_ino = inr; inode->i_flags = ((unsigned short int) sb->s_flags); put_last_free(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); } if (empty) iput(empty); return_it: return inode; }
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; }
void iput(register struct inode *inode) { if (inode) { wait_on_inode(inode); if (!inode->i_count) { printk("VFS: iput: trying to free free inode\n"); printk("VFS: device %s, inode %lu, mode=0%07o\n", kdevname(inode->i_rdev), inode->i_ino, inode->i_mode); return; } #ifdef NOT_YET if (inode->i_pipe) wake_up_interruptible(&PIPE_WAIT(*inode)); #endif repeat: if (inode->i_count > 1) { inode->i_count--; return; } wake_up(&inode_wait); #ifdef NOT_YET if (inode->i_pipe) { /* Free up any memory allocated to the pipe */ } #endif if (inode->i_sb) { struct super_operations *sop = inode->i_sb->s_op; if (sop && sop->put_inode) { sop->put_inode(inode); if (!inode->i_nlink) return; } } if (inode->i_dirt) { write_inode(inode); /* we can sleep - so do again */ wait_on_inode(inode); goto repeat; } inode->i_count--; nr_free_inodes++; } return; }
void clear_inode(register struct inode *inode) { wait_on_inode(inode); remove_inode_free(inode); if (inode->i_count) nr_free_inodes++; memset(inode, 0, sizeof(struct inode)); insert_inode_free(inode); }
void iput(register struct inode *inode) { register struct super_operations *sop; if (inode) { wait_on_inode(inode); if (!inode->i_count) { printk("VFS: iput: trying to free free inode\n"); printk("VFS: device %s, inode %lu, mode=0%07o\n", kdevname(inode->i_rdev), inode->i_ino, inode->i_mode); return; } #ifdef NOT_YET if ((inode->i_mode & S_IFMT) == S_IFIFO) wake_up_interruptible(&PIPE_WAIT(*inode)); #endif goto ini_loop; do { write_inode(inode); /* we can sleep - so do again */ wait_on_inode(inode); ini_loop: if (inode->i_count > 1) { inode->i_count--; return; } wake_up(&inode_wait); if (inode->i_sb) { sop = inode->i_sb->s_op; if (sop && sop->put_inode) { sop->put_inode(inode); if (!inode->i_nlink) return; } } } while (inode->i_dirt); inode->i_count--; nr_free_inodes++; } }
void sync_inodes(kdev_t dev) { register struct inode *inode = first_inode; do { if (dev && inode->i_dev != dev) continue; wait_on_inode(inode); if (inode->i_dirt) write_inode(inode); } while ((inode = inode->i_prev) != first_inode); }
/* * This is called by the filesystem to tell us * that the inode is no longer useful. We just * terminate it with extreme prejudice. */ void clear_inode(struct inode *inode) { if (inode->i_nrpages) truncate_inode_pages(inode, 0); wait_on_inode(inode); if (IS_QUOTAINIT(inode)) DQUOT_DROP(inode); if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->clear_inode) inode->i_sb->s_op->clear_inode(inode); inode->i_state = 0; }
struct inode *get_empty_inode(void) { static ino_t ino = 0; register struct inode *inode, *best; int i; repeat: inode = first_inode; best = 0; for (inode = inode_block, i = 0; i < nr_inodes; inode++, i++) { if (!inode->i_count && !inode->i_lock && !inode->i_dirt) { best = inode; break; } } if (!best) { printk("VFS: No free inodes - contact somebody other than Linus\n"); list_inode_status(); sleep_on(&inode_wait); goto repeat; } /* Here we are doing the same checks again. There cannot be a significant * * race condition here - no time has passed */ #if 0 if (inode->i_lock) { wait_on_inode(inode); goto repeat; } if (inode->i_dirt) { write_inode(inode); goto repeat; } if (inode->i_count) goto repeat; #endif clear_inode(inode); inode->i_count = inode->i_nlink = 1; #ifdef BLOAT_FS inode->i_version = ++event; #endif inode->i_sem = 0; inode->i_ino = ++ino; inode->i_dev = 0; nr_free_inodes--; if (nr_free_inodes < 0) { printk("VFS: get_empty_inode: bad free inode count.\n"); nr_free_inodes = 0; } return inode; }
void sync_inodes(kdev_t dev) { register struct inode *inode; register char *pi; inode = first_inode; for (pi = 0; ((int) pi) < nr_inodes * 2; pi++, inode = inode->i_next) { if (dev && inode->i_dev != dev) continue; wait_on_inode(inode); if (inode->i_dirt) write_inode(inode); } }
static void write_inode(register struct inode *inode) { register struct super_block *sb = inode->i_sb; if (inode->i_dirt) { wait_on_inode(inode); if (inode->i_dirt) { if (!sb || !sb->s_op || !sb->s_op->write_inode) inode->i_dirt = 0; else { inode->i_lock = 1; sb->s_op->write_inode(inode); unlock_inode(inode); } } } }
static void write_inode(register struct inode *inode) { register struct super_block *sb = inode->i_sb; if (!inode->i_dirt) return; wait_on_inode(inode); if (!inode->i_dirt) return; if (!sb || !sb->s_op || !sb->s_op->write_inode) { inode->i_dirt = 0; return; } inode->i_lock = 1; sb->s_op->write_inode(inode); unlock_inode(inode); }
static struct inode *get_empty_inode(void) { static ino_t ino = 0; register struct inode *inode; do { inode = first_inode->i_next; do { if (!inode->i_count && !inode->i_dirt && !inode->i_lock) { goto found_empty_inode; } } while ((inode = inode->i_next) != first_inode->i_next); printk("VFS: No free inodes\n"); list_inode_status(); sleep_on(&inode_wait); } while (1); found_empty_inode: /* Here we are doing the same checks again. There cannot be a significant * * race condition here - no time has passed */ #if 0 if (inode->i_lock) { wait_on_inode(inode); goto repeat; } if (inode->i_dirt) { write_inode(inode); goto repeat; } if (inode->i_count) goto repeat; #endif clear_inode(inode); inode->i_count = inode->i_nlink = 1; inode->i_uid = current->euid; #ifdef BLOAT_FS inode->i_version = ++event; #endif inode->i_ino = ++ino; nr_free_inodes--; if (nr_free_inodes < 0) { printk("VFS: get_empty_inode: bad free inode count.\n"); nr_free_inodes = 0; } return inode; }
static void lock_inode(register struct inode *inode) { wait_on_inode(inode); inode->i_lock = 1; }