aboutsummaryrefslogtreecommitdiffstats
path: root/fs/file_table.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/file_table.c')
-rw-r--r--fs/file_table.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/fs/file_table.c b/fs/file_table.c
index 3f73eb1f195a..71efc7000226 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -199,6 +199,17 @@ int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry,
199 file->f_mapping = dentry->d_inode->i_mapping; 199 file->f_mapping = dentry->d_inode->i_mapping;
200 file->f_mode = mode; 200 file->f_mode = mode;
201 file->f_op = fop; 201 file->f_op = fop;
202
203 /*
204 * These mounts don't really matter in practice
205 * for r/o bind mounts. They aren't userspace-
206 * visible. We do this for consistency, and so
207 * that we can do debugging checks at __fput()
208 */
209 if ((mode & FMODE_WRITE) && !special_file(dentry->d_inode->i_mode)) {
210 error = mnt_want_write(mnt);
211 WARN_ON(error);
212 }
202 return error; 213 return error;
203} 214}
204EXPORT_SYMBOL(init_file); 215EXPORT_SYMBOL(init_file);
@@ -221,10 +232,13 @@ EXPORT_SYMBOL(fput);
221 */ 232 */
222void drop_file_write_access(struct file *file) 233void drop_file_write_access(struct file *file)
223{ 234{
235 struct vfsmount *mnt = file->f_path.mnt;
224 struct dentry *dentry = file->f_path.dentry; 236 struct dentry *dentry = file->f_path.dentry;
225 struct inode *inode = dentry->d_inode; 237 struct inode *inode = dentry->d_inode;
226 238
227 put_write_access(inode); 239 put_write_access(inode);
240 if (!special_file(inode->i_mode))
241 mnt_drop_write(mnt);
228} 242}
229EXPORT_SYMBOL_GPL(drop_file_write_access); 243EXPORT_SYMBOL_GPL(drop_file_write_access);
230 244