@@ -89,32 +89,19 @@ static int ovl_change_flags(struct file *file, unsigned int flags)
89
89
return 0 ;
90
90
}
91
91
92
- static int ovl_real_fdget_meta (const struct file * file , struct fd * real ,
93
- bool allow_meta )
92
+ static int ovl_real_fdget_path (const struct file * file , struct fd * real ,
93
+ struct path * realpath )
94
94
{
95
- struct dentry * dentry = file_dentry (file );
96
95
struct file * realfile = file -> private_data ;
97
- struct path realpath ;
98
- int err ;
99
96
100
97
real -> word = (unsigned long )realfile ;
101
98
102
- if (allow_meta ) {
103
- ovl_path_real (dentry , & realpath );
104
- } else {
105
- /* lazy lookup and verify of lowerdata */
106
- err = ovl_verify_lowerdata (dentry );
107
- if (err )
108
- return err ;
109
-
110
- ovl_path_realdata (dentry , & realpath );
111
- }
112
- if (!realpath .dentry )
99
+ if (WARN_ON_ONCE (!realpath -> dentry ))
113
100
return - EIO ;
114
101
115
102
/* Has it been copied up since we'd opened it? */
116
- if (unlikely (file_inode (realfile ) != d_inode (realpath . dentry ))) {
117
- struct file * f = ovl_open_realfile (file , & realpath );
103
+ if (unlikely (file_inode (realfile ) != d_inode (realpath -> dentry ))) {
104
+ struct file * f = ovl_open_realfile (file , realpath );
118
105
if (IS_ERR (f ))
119
106
return PTR_ERR (f );
120
107
real -> word = (unsigned long )f | FDPUT_FPUT ;
@@ -130,15 +117,26 @@ static int ovl_real_fdget_meta(const struct file *file, struct fd *real,
130
117
131
118
static int ovl_real_fdget (const struct file * file , struct fd * real )
132
119
{
133
- if (d_is_dir (file_dentry (file ))) {
120
+ struct dentry * dentry = file_dentry (file );
121
+ struct path realpath ;
122
+ int err ;
123
+
124
+ if (d_is_dir (dentry )) {
134
125
struct file * f = ovl_dir_real_file (file , false);
135
126
if (IS_ERR (f ))
136
127
return PTR_ERR (f );
137
128
real -> word = (unsigned long )f ;
138
129
return 0 ;
139
130
}
140
131
141
- return ovl_real_fdget_meta (file , real , false);
132
+ /* lazy lookup and verify of lowerdata */
133
+ err = ovl_verify_lowerdata (dentry );
134
+ if (err )
135
+ return err ;
136
+
137
+ ovl_path_realdata (dentry , & realpath );
138
+
139
+ return ovl_real_fdget_path (file , real , & realpath );
142
140
}
143
141
144
142
static int ovl_open (struct inode * inode , struct file * file )
@@ -396,6 +394,9 @@ static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
396
394
397
395
static int ovl_fsync (struct file * file , loff_t start , loff_t end , int datasync )
398
396
{
397
+ struct dentry * dentry = file_dentry (file );
398
+ enum ovl_path_type type ;
399
+ struct path upperpath ;
399
400
struct fd real ;
400
401
const struct cred * old_cred ;
401
402
int ret ;
@@ -404,16 +405,19 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
404
405
if (ret <= 0 )
405
406
return ret ;
406
407
407
- ret = ovl_real_fdget_meta (file , & real , !datasync );
408
+ /* Don't sync lower file for fear of receiving EROFS error */
409
+ type = ovl_path_type (dentry );
410
+ if (!OVL_TYPE_UPPER (type ) || (datasync && OVL_TYPE_MERGE (type )))
411
+ return 0 ;
412
+
413
+ ovl_path_upper (dentry , & upperpath );
414
+ ret = ovl_real_fdget_path (file , & real , & upperpath );
408
415
if (ret )
409
416
return ret ;
410
417
411
- /* Don't sync lower file for fear of receiving EROFS error */
412
- if (file_inode (fd_file (real )) == ovl_inode_upper (file_inode (file ))) {
413
- old_cred = ovl_override_creds (file_inode (file )-> i_sb );
414
- ret = vfs_fsync_range (fd_file (real ), start , end , datasync );
415
- ovl_revert_creds (old_cred );
416
- }
418
+ old_cred = ovl_override_creds (file_inode (file )-> i_sb );
419
+ ret = vfs_fsync_range (fd_file (real ), start , end , datasync );
420
+ ovl_revert_creds (old_cred );
417
421
418
422
fdput (real );
419
423
0 commit comments