@@ -119,16 +119,14 @@ static bool ovl_is_real_file(const struct file *realfile,
119119 return file_inode (realfile ) == d_inode (realpath -> dentry );
120120}
121121
122- static int ovl_real_fdget_path ( const struct file * file , struct fd * real ,
123- struct path * realpath )
122+ static struct file * ovl_real_file_path ( const struct file * file ,
123+ struct path * realpath )
124124{
125125 struct ovl_file * of = file -> private_data ;
126126 struct file * realfile = of -> realfile ;
127127
128- real -> word = 0 ;
129-
130128 if (WARN_ON_ONCE (!realpath -> dentry ))
131- return - EIO ;
129+ return ERR_PTR ( - EIO ) ;
132130
133131 /*
134132 * If the realfile that we want is not where the data used to be at
@@ -143,7 +141,7 @@ static int ovl_real_fdget_path(const struct file *file, struct fd *real,
143141 if (!upperfile ) { /* Nobody opened upperfile yet */
144142 upperfile = ovl_open_realfile (file , realpath );
145143 if (IS_ERR (upperfile ))
146- return PTR_ERR ( upperfile ) ;
144+ return upperfile ;
147145
148146 /* Store the upperfile for later */
149147 old = cmpxchg_release (& of -> upperfile , NULL , upperfile );
@@ -157,41 +155,54 @@ static int ovl_real_fdget_path(const struct file *file, struct fd *real,
157155 * been corrupting the upper layer.
158156 */
159157 if (WARN_ON_ONCE (!ovl_is_real_file (upperfile , realpath )))
160- return - EIO ;
158+ return ERR_PTR ( - EIO ) ;
161159
162160 realfile = upperfile ;
163161 }
164162
165163 /* Did the flags change since open? */
166- if (unlikely ((file -> f_flags ^ realfile -> f_flags ) & ~OVL_OPEN_FLAGS ))
167- return ovl_change_flags (realfile , file -> f_flags );
164+ if (unlikely ((file -> f_flags ^ realfile -> f_flags ) & ~OVL_OPEN_FLAGS )) {
165+ int err = ovl_change_flags (realfile , file -> f_flags );
168166
169- real -> word = (unsigned long )realfile ;
170- return 0 ;
167+ if (err )
168+ return ERR_PTR (err );
169+ }
170+
171+ return realfile ;
171172}
172173
173- static int ovl_real_fdget ( const struct file * file , struct fd * real )
174+ static struct file * ovl_real_file ( const struct file * file )
174175{
175176 struct dentry * dentry = file_dentry (file );
176177 struct path realpath ;
177178 int err ;
178179
179180 if (d_is_dir (dentry )) {
180181 struct file * f = ovl_dir_real_file (file , false);
181- if ( IS_ERR ( f ))
182- return PTR_ERR ( f );
183- real -> word = ( unsigned long ) f ;
184- return 0 ;
182+
183+ if ( WARN_ON_ONCE (! f ))
184+ return ERR_PTR ( - EIO ) ;
185+ return f ;
185186 }
186187
187188 /* lazy lookup and verify of lowerdata */
188189 err = ovl_verify_lowerdata (dentry );
189190 if (err )
190- return err ;
191+ return ERR_PTR ( err ) ;
191192
192193 ovl_path_realdata (dentry , & realpath );
193194
194- return ovl_real_fdget_path (file , real , & realpath );
195+ return ovl_real_file_path (file , & realpath );
196+ }
197+
198+ static int ovl_real_fdget (const struct file * file , struct fd * real )
199+ {
200+ struct file * f = ovl_real_file (file );
201+
202+ if (IS_ERR (f ))
203+ return PTR_ERR (f );
204+ real -> word = (unsigned long )f ;
205+ return 0 ;
195206}
196207
197208static int ovl_open (struct inode * inode , struct file * file )
@@ -458,7 +469,7 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
458469 struct dentry * dentry = file_dentry (file );
459470 enum ovl_path_type type ;
460471 struct path upperpath ;
461- struct fd real ;
472+ struct file * upperfile ;
462473 const struct cred * old_cred ;
463474 int ret ;
464475
@@ -472,16 +483,14 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
472483 return 0 ;
473484
474485 ovl_path_upper (dentry , & upperpath );
475- ret = ovl_real_fdget_path (file , & real , & upperpath );
476- if (ret )
477- return ret ;
486+ upperfile = ovl_real_file_path (file , & upperpath );
487+ if (IS_ERR ( upperfile ) )
488+ return PTR_ERR ( upperfile ) ;
478489
479490 old_cred = ovl_override_creds (file_inode (file )-> i_sb );
480- ret = vfs_fsync_range (fd_file ( real ) , start , end , datasync );
491+ ret = vfs_fsync_range (upperfile , start , end , datasync );
481492 ovl_revert_creds (old_cred );
482493
483- fdput (real );
484-
485494 return ret ;
486495}
487496
0 commit comments