diff options
Diffstat (limited to 'fs/file.c')
| -rw-r--r-- | fs/file.c | 28 | 
1 files changed, 24 insertions, 4 deletions
diff --git a/fs/file.c b/fs/file.c index 3da91a112bab..a364e1a9b7e8 100644 --- a/fs/file.c +++ b/fs/file.c @@ -642,7 +642,9 @@ out_unlock:  EXPORT_SYMBOL(__close_fd); /* for ksys_close() */  /* - * variant of __close_fd that gets a ref on the file for later fput + * variant of __close_fd that gets a ref on the file for later fput. + * The caller must ensure that filp_close() called on the file, and then + * an fput().   */  int __close_fd_get_file(unsigned int fd, struct file **res)  { @@ -662,7 +664,7 @@ int __close_fd_get_file(unsigned int fd, struct file **res)  	spin_unlock(&files->file_lock);  	get_file(file);  	*res = file; -	return filp_close(file, files); +	return 0;  out_unlock:  	spin_unlock(&files->file_lock); @@ -706,9 +708,9 @@ void do_close_on_exec(struct files_struct *files)  	spin_unlock(&files->file_lock);  } -static struct file *__fget(unsigned int fd, fmode_t mask, unsigned int refs) +static struct file *__fget_files(struct files_struct *files, unsigned int fd, +				 fmode_t mask, unsigned int refs)  { -	struct files_struct *files = current->files;  	struct file *file;  	rcu_read_lock(); @@ -729,6 +731,12 @@ loop:  	return file;  } +static inline struct file *__fget(unsigned int fd, fmode_t mask, +				  unsigned int refs) +{ +	return __fget_files(current->files, fd, mask, refs); +} +  struct file *fget_many(unsigned int fd, unsigned int refs)  {  	return __fget(fd, FMODE_PATH, refs); @@ -746,6 +754,18 @@ struct file *fget_raw(unsigned int fd)  }  EXPORT_SYMBOL(fget_raw); +struct file *fget_task(struct task_struct *task, unsigned int fd) +{ +	struct file *file = NULL; + +	task_lock(task); +	if (task->files) +		file = __fget_files(task->files, fd, 0, 1); +	task_unlock(task); + +	return file; +} +  /*   * Lightweight file lookup - no refcnt increment if fd table isn't shared.   *  |