@@ -1071,6 +1071,66 @@ static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs,
1071
1071
return err ;
1072
1072
}
1073
1073
1074
+ /*
1075
+ * Returns 1 if RENAME_WHITEOUT is supported, 0 if not supported and
1076
+ * negative values if error is encountered.
1077
+ */
1078
+ static int ovl_check_rename_whiteout (struct dentry * workdir )
1079
+ {
1080
+ struct inode * dir = d_inode (workdir );
1081
+ struct dentry * temp ;
1082
+ struct dentry * dest ;
1083
+ struct dentry * whiteout ;
1084
+ struct name_snapshot name ;
1085
+ int err ;
1086
+
1087
+ inode_lock_nested (dir , I_MUTEX_PARENT );
1088
+
1089
+ temp = ovl_create_temp (workdir , OVL_CATTR (S_IFREG | 0 ));
1090
+ err = PTR_ERR (temp );
1091
+ if (IS_ERR (temp ))
1092
+ goto out_unlock ;
1093
+
1094
+ dest = ovl_lookup_temp (workdir );
1095
+ err = PTR_ERR (dest );
1096
+ if (IS_ERR (dest )) {
1097
+ dput (temp );
1098
+ goto out_unlock ;
1099
+ }
1100
+
1101
+ /* Name is inline and stable - using snapshot as a copy helper */
1102
+ take_dentry_name_snapshot (& name , temp );
1103
+ err = ovl_do_rename (dir , temp , dir , dest , RENAME_WHITEOUT );
1104
+ if (err ) {
1105
+ if (err == - EINVAL )
1106
+ err = 0 ;
1107
+ goto cleanup_temp ;
1108
+ }
1109
+
1110
+ whiteout = lookup_one_len (name .name .name , workdir , name .name .len );
1111
+ err = PTR_ERR (whiteout );
1112
+ if (IS_ERR (whiteout ))
1113
+ goto cleanup_temp ;
1114
+
1115
+ err = ovl_is_whiteout (whiteout );
1116
+
1117
+ /* Best effort cleanup of whiteout and temp file */
1118
+ if (err )
1119
+ ovl_cleanup (dir , whiteout );
1120
+ dput (whiteout );
1121
+
1122
+ cleanup_temp :
1123
+ ovl_cleanup (dir , temp );
1124
+ release_dentry_name_snapshot (& name );
1125
+ dput (temp );
1126
+ dput (dest );
1127
+
1128
+ out_unlock :
1129
+ inode_unlock (dir );
1130
+
1131
+ return err ;
1132
+ }
1133
+
1074
1134
static int ovl_make_workdir (struct super_block * sb , struct ovl_fs * ofs ,
1075
1135
struct path * workpath )
1076
1136
{
@@ -1116,6 +1176,15 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
1116
1176
else
1117
1177
pr_warn ("upper fs does not support tmpfile.\n" );
1118
1178
1179
+
1180
+ /* Check if upper/work fs supports RENAME_WHITEOUT */
1181
+ err = ovl_check_rename_whiteout (ofs -> workdir );
1182
+ if (err < 0 )
1183
+ goto out ;
1184
+
1185
+ if (!err )
1186
+ pr_warn ("upper fs does not support RENAME_WHITEOUT.\n" );
1187
+
1119
1188
/*
1120
1189
* Check if upper/work fs supports trusted.overlay.* xattr
1121
1190
*/
0 commit comments