X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fhugetlbfs%2Finode.c;h=7a006cc6e1c242f73bee8650c768761c3b0e5400;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=6e7aeff355afe50685269b23b5b1a7574ba3639f;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 6e7aeff35..7a006cc6e 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -105,6 +105,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; + unsigned long start_addr; if (len & ~HPAGE_MASK) return -EINVAL; @@ -119,12 +120,25 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, return addr; } - addr = ALIGN(mm->free_area_cache, HPAGE_SIZE); + start_addr = mm->free_area_cache; + +full_search: + addr = ALIGN(start_addr, HPAGE_SIZE); for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { /* At this point: (!vma || addr < vma->vm_end). */ - if (TASK_SIZE - len < addr) + if (TASK_SIZE - len < addr) { + /* + * Start a new search - just in case we missed + * some holes. + */ + if (start_addr != TASK_UNMAPPED_BASE) { + start_addr = TASK_UNMAPPED_BASE; + goto full_search; + } return -ENOMEM; + } + if (!vma || addr + len <= vma->vm_start) return addr; addr = ALIGN(vma->vm_end, HPAGE_SIZE); @@ -154,7 +168,7 @@ static int hugetlbfs_commit_write(struct file *file, return -EINVAL; } -void huge_pagevec_release(struct pagevec *pvec) +static void huge_pagevec_release(struct pagevec *pvec) { int i; @@ -164,7 +178,7 @@ void huge_pagevec_release(struct pagevec *pvec) pagevec_reinit(pvec); } -void truncate_huge_page(struct page *page) +static void truncate_huge_page(struct page *page) { clear_page_dirty(page); ClearPageUptodate(page); @@ -172,7 +186,7 @@ void truncate_huge_page(struct page *page) put_page(page); } -void truncate_hugepages(struct address_space *mapping, loff_t lstart) +static void truncate_hugepages(struct address_space *mapping, loff_t lstart) { const pgoff_t start = lstart >> HPAGE_SHIFT; struct pagevec pvec; @@ -211,6 +225,7 @@ static void hugetlbfs_delete_inode(struct inode *inode) hlist_del_init(&inode->i_hash); list_del_init(&inode->i_list); + list_del_init(&inode->i_sb_list); inode->i_state |= I_FREEING; inodes_stat.nr_inodes--; spin_unlock(&inode_lock); @@ -253,6 +268,7 @@ static void hugetlbfs_forget_inode(struct inode *inode) hlist_del_init(&inode->i_hash); out_truncate: list_del_init(&inode->i_list); + list_del_init(&inode->i_sb_list); inode->i_state |= I_FREEING; inodes_stat.nr_inodes--; spin_unlock(&inode_lock); @@ -479,7 +495,7 @@ static int hugetlbfs_symlink(struct inode *dir, /* * For direct-IO reads into hugetlb pages */ -int hugetlbfs_set_page_dirty(struct page *page) +static int hugetlbfs_set_page_dirty(struct page *page) { return 0; } @@ -656,6 +672,7 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) sb->s_blocksize_bits = HPAGE_SHIFT; sb->s_magic = HUGETLBFS_MAGIC; sb->s_op = &hugetlbfs_ops; + sb->s_time_gran = 1; inode = hugetlbfs_get_inode(sb, config.uid, config.gid, S_IFDIR | config.mode, 0); if (!inode) @@ -720,7 +737,7 @@ static struct vfsmount *hugetlbfs_vfsmount; */ static unsigned long hugetlbfs_counter(void) { - static spinlock_t lock = SPIN_LOCK_UNLOCKED; + static DEFINE_SPINLOCK(lock); static unsigned long counter; unsigned long ret;