mark struct file that had write access grabbed by open()
new flag in ->f_mode - FMODE_WRITER. Set by do_dentry_open() in case when it has grabbed write access, checked by __fput() to decide whether it wants to drop the sucker. Allows to stop bothering with mnt_clone_write() in alloc_file(), along with fewer special_file() checks. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									0ccb286346
								
							
						
					
					
						commit
						83f936c75e
					
				| @ -177,43 +177,12 @@ struct file *alloc_file(struct path *path, fmode_t mode, | ||||
| 	file->f_mapping = path->dentry->d_inode->i_mapping; | ||||
| 	file->f_mode = mode; | ||||
| 	file->f_op = fop; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * These mounts don't really matter in practice | ||||
| 	 * for r/o bind mounts.  They aren't userspace- | ||||
| 	 * visible.  We do this for consistency, and so | ||||
| 	 * that we can do debugging checks at __fput() | ||||
| 	 */ | ||||
| 	if ((mode & FMODE_WRITE) && !special_file(path->dentry->d_inode->i_mode)) { | ||||
| 		WARN_ON(mnt_clone_write(path->mnt)); | ||||
| 	} | ||||
| 	if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) | ||||
| 		i_readcount_inc(path->dentry->d_inode); | ||||
| 	return file; | ||||
| } | ||||
| EXPORT_SYMBOL(alloc_file); | ||||
| 
 | ||||
| /**
 | ||||
|  * drop_file_write_access - give up ability to write to a file | ||||
|  * @file: the file to which we will stop writing | ||||
|  * | ||||
|  * This is a central place which will give up the ability | ||||
|  * to write to @file, along with access to write through | ||||
|  * its vfsmount. | ||||
|  */ | ||||
| static void drop_file_write_access(struct file *file) | ||||
| { | ||||
| 	struct vfsmount *mnt = file->f_path.mnt; | ||||
| 	struct dentry *dentry = file->f_path.dentry; | ||||
| 	struct inode *inode = dentry->d_inode; | ||||
| 
 | ||||
| 	if (special_file(inode->i_mode)) | ||||
| 		return; | ||||
| 
 | ||||
| 	put_write_access(inode); | ||||
| 	__mnt_drop_write(mnt); | ||||
| } | ||||
| 
 | ||||
| /* the real guts of fput() - releasing the last reference to file
 | ||||
|  */ | ||||
| static void __fput(struct file *file) | ||||
| @ -248,8 +217,10 @@ static void __fput(struct file *file) | ||||
| 	put_pid(file->f_owner.pid); | ||||
| 	if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) | ||||
| 		i_readcount_dec(inode); | ||||
| 	if (file->f_mode & FMODE_WRITE) | ||||
| 		drop_file_write_access(file); | ||||
| 	if (file->f_mode & FMODE_WRITER) { | ||||
| 		put_write_access(inode); | ||||
| 		__mnt_drop_write(mnt); | ||||
| 	} | ||||
| 	file->f_path.dentry = NULL; | ||||
| 	file->f_path.mnt = NULL; | ||||
| 	file->f_inode = NULL; | ||||
|  | ||||
| @ -414,9 +414,7 @@ EXPORT_SYMBOL_GPL(mnt_clone_write); | ||||
|  */ | ||||
| int __mnt_want_write_file(struct file *file) | ||||
| { | ||||
| 	struct inode *inode = file_inode(file); | ||||
| 
 | ||||
| 	if (!(file->f_mode & FMODE_WRITE) || special_file(inode->i_mode)) | ||||
| 	if (!(file->f_mode & FMODE_WRITER)) | ||||
| 		return __mnt_want_write(file->f_path.mnt); | ||||
| 	else | ||||
| 		return mnt_clone_write(file->f_path.mnt); | ||||
|  | ||||
| @ -670,6 +670,7 @@ static int do_dentry_open(struct file *f, | ||||
| 			put_write_access(inode); | ||||
| 			goto cleanup_file; | ||||
| 		} | ||||
| 		f->f_mode |= FMODE_WRITER; | ||||
| 	} | ||||
| 
 | ||||
| 	f->f_mapping = inode->i_mapping; | ||||
| @ -715,11 +716,9 @@ static int do_dentry_open(struct file *f, | ||||
| 
 | ||||
| cleanup_all: | ||||
| 	fops_put(f->f_op); | ||||
| 	if (f->f_mode & FMODE_WRITE) { | ||||
| 		if (!special_file(inode->i_mode)) { | ||||
| 			put_write_access(inode); | ||||
| 			__mnt_drop_write(f->f_path.mnt); | ||||
| 		} | ||||
| 	if (f->f_mode & FMODE_WRITER) { | ||||
| 		put_write_access(inode); | ||||
| 		__mnt_drop_write(f->f_path.mnt); | ||||
| 	} | ||||
| cleanup_file: | ||||
| 	path_put(&f->f_path); | ||||
|  | ||||
| @ -125,6 +125,8 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, | ||||
| 
 | ||||
| /* File needs atomic accesses to f_pos */ | ||||
| #define FMODE_ATOMIC_POS	((__force fmode_t)0x8000) | ||||
| /* Write access to underlying fs */ | ||||
| #define FMODE_WRITER		((__force fmode_t)0x10000) | ||||
| 
 | ||||
| /* File was opened by fanotify and shouldn't generate fanotify events */ | ||||
| #define FMODE_NONOTIFY		((__force fmode_t)0x1000000) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user