if (!od->is_upper && ovl_path_type(dentry) == OVL_PATH_MERGE) {
                struct inode *inode = file_inode(file);
 
-               mutex_lock(&inode->i_mutex);
                realfile = od->upperfile;
                if (!realfile) {
                        struct path upperpath;
 
                        ovl_path_upper(dentry, &upperpath);
                        realfile = ovl_path_open(&upperpath, O_RDONLY);
-                       if (IS_ERR(realfile)) {
-                               mutex_unlock(&inode->i_mutex);
-                               return PTR_ERR(realfile);
+                       mutex_lock(&inode->i_mutex);
+                       if (!od->upperfile) {
+                               if (IS_ERR(realfile)) {
+                                       mutex_unlock(&inode->i_mutex);
+                                       return PTR_ERR(realfile);
+                               }
+                               od->upperfile = realfile;
+                       } else {
+                               /* somebody has beaten us to it */
+                               if (!IS_ERR(realfile))
+                                       fput(realfile);
+                               realfile = od->upperfile;
                        }
-                       od->upperfile = realfile;
+                       mutex_unlock(&inode->i_mutex);
                }
-               mutex_unlock(&inode->i_mutex);
        }
 
        return vfs_fsync_range(realfile, start, end, datasync);