diff options
Diffstat (limited to 'fs/proc/inode.c')
| -rw-r--r-- | fs/proc/inode.c | 28 | 
1 files changed, 20 insertions, 8 deletions
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 9f8ef9b7674..0adbc02d60e 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -35,7 +35,7 @@ static void proc_evict_inode(struct inode *inode)  	const struct proc_ns_operations *ns_ops;  	void *ns; -	truncate_inode_pages(&inode->i_data, 0); +	truncate_inode_pages_final(&inode->i_data);  	clear_inode(inode);  	/* Stop tracking associated processes */ @@ -47,7 +47,7 @@ static void proc_evict_inode(struct inode *inode)  		pde_put(de);  	head = PROC_I(inode)->sysctl;  	if (head) { -		rcu_assign_pointer(PROC_I(inode)->sysctl, NULL); +		RCU_INIT_POINTER(PROC_I(inode)->sysctl, NULL);  		sysctl_head_put(head);  	}  	/* Release any associated namespace */ @@ -285,15 +285,27 @@ static int proc_reg_mmap(struct file *file, struct vm_area_struct *vma)  	return rv;  } -static unsigned long proc_reg_get_unmapped_area(struct file *file, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) +static unsigned long +proc_reg_get_unmapped_area(struct file *file, unsigned long orig_addr, +			   unsigned long len, unsigned long pgoff, +			   unsigned long flags)  {  	struct proc_dir_entry *pde = PDE(file_inode(file)); -	int rv = -EIO; -	unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); +	unsigned long rv = -EIO; +  	if (use_pde(pde)) { -		get_unmapped_area = pde->proc_fops->get_unmapped_area; -		if (get_unmapped_area) -			rv = get_unmapped_area(file, orig_addr, len, pgoff, flags); +		typeof(proc_reg_get_unmapped_area) *get_area; + +		get_area = pde->proc_fops->get_unmapped_area; +#ifdef CONFIG_MMU +		if (!get_area) +			get_area = current->mm->get_unmapped_area; +#endif + +		if (get_area) +			rv = get_area(file, orig_addr, len, pgoff, flags); +		else +			rv = orig_addr;  		unuse_pde(pde);  	}  	return rv;  | 
