--- linux/fs/inode.c Tue Dec 11 10:23:08 2001 +++ linux.mt/fs/inode.c Tue Dec 11 23:46:22 2001 @@ -279,24 +279,26 @@ } } +/* + * try_to_sync_unused_list - sync the inodes on the list if i_count is 0 + * @head: the &struct list head pointer to run through + * @nr_inodes: the number of inodes to attempt to sync + */ + static inline int try_to_sync_unused_list(struct list_head *head, int nr_inodes) { - struct list_head *tmp = head; + struct list_head *pos,*psave; struct inode *inode; - while (nr_inodes && (tmp = tmp->prev) != head) { - inode = list_entry(tmp, struct inode, i_list); + list_for_each_safe_r(pos,psave,head) { + + inode = list_entry(pos, struct inode, i_list); if (!atomic_read(&inode->i_count)) { __sync_one(inode, 0); nr_inodes--; - - /* - * __sync_one moved the inode to another list, - * so we have to start looking from the list head. - */ - tmp = head; } + } return nr_inodes; @@ -555,18 +557,13 @@ */ static int invalidate_list(struct list_head *head, struct super_block * sb, struct list_head * dispose) { - struct list_head *next; + struct list_head *pos,*safe; int busy = 0, count = 0; - next = head->next; - for (;;) { - struct list_head * tmp = next; + list_for_each_safe(pos,safe,head) { struct inode * inode; - next = next->next; - if (tmp == head) - break; - inode = list_entry(tmp, struct inode, i_list); + inode = list_entry(pos, struct inode, i_list); if (inode->i_sb != sb) continue; invalidate_inode_buffers(inode); @@ -646,7 +643,7 @@ /* - * This is called with the inode lock held. It searches + * It searches * the in-use for freeable inodes, which are moved to a * temporary list and then placed on the unused list by * dispose_list. @@ -664,30 +661,25 @@ void prune_icache(int goal) { LIST_HEAD(list); - struct list_head *entry, *freeable = &list; + struct list_head *safe,*pos, *freeable = &list; int count; struct inode * inode; spin_lock(&inode_lock); count = 0; - entry = inode_unused.prev; - while (entry != &inode_unused) - { - struct list_head *tmp = entry; - - entry = entry->prev; - inode = INODE(tmp); + list_for_each_safe_r(pos,safe,inode_unused) { + inode = INODE(pos); if (inode->i_state & (I_FREEING|I_CLEAR|I_LOCK)) continue; if (!CAN_UNUSE(inode)) continue; if (atomic_read(&inode->i_count)) continue; - list_del(tmp); + list_del(pos); list_del(&inode->i_hash); INIT_LIST_HEAD(&inode->i_hash); - list_add(tmp, freeable); + list_add(pos, freeable); inode->i_state |= I_FREEING; count++; if (!--goal) @@ -747,25 +739,17 @@ */ static struct inode * find_inode(struct super_block * sb, unsigned long ino, struct list_head *head, find_inode_t find_actor, void *opaque) { - struct list_head *tmp; + struct list_head *pos; struct inode * inode; - tmp = head; - for (;;) { - tmp = tmp->next; - inode = NULL; - if (tmp == head) - break; + list_for_each(pos,head) { inode = list_entry(tmp, struct inode, i_hash); - if (inode->i_ino != ino) - continue; - if (inode->i_sb != sb) - continue; - if (find_actor && !find_actor(inode, ino, opaque)) - continue; - break; + if ((inode->i_ino == ino) && (inode->i_sb == sb) && \ + !(find_actor && !find_actor(inode, ino, opaque))) { + return inode; + } } - return inode; + return NULL; } /* --- linux/include/linux/list.h Thu Nov 22 14:46:19 2001 +++ linux.mt/include/linux/list.h Tue Dec 11 23:24:57 2001 @@ -162,6 +162,25 @@ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) +/** + * list_for_each_r - iterate over a list in reverse + * @pos: the &struct list_head to sue as a loop counter. + * @head: the head of the list. + */ +#define list_for_each_r(pos,head) \ + for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \ + pos = pos->prev, prefetch(pos->prev)) + +/** + * list_for_each_safe_r - iterate over a list in reverse safe against removal of list entry + * @pos: the &struct list_head to use as a loop counter. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe_r(pos, n, head) \ + for (pos = (head)->prev, n = pos->prev; pos != (head); \ + pos = n, n = pos->prev) + #endif /* __KERNEL__ || _LVM_H_INCLUDE */ #endif