aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeinrich Schuchardt2019-04-06 16:27:34 +0200
committerHeinrich Schuchardt2019-04-07 14:17:06 +0200
commitcb0c2a7430788b4cd13d303a02a021bb53e3db4b (patch)
tree1c0ab2039fdef487b1b6131e62370fbc30a6db23
parent19b2d895fb16f4c22e19125c84e3616c35e9ded7 (diff)
efi_loader: correct file creation
The EFI shell expects that after opening a file with EFI_FILE_MODE_CREATE GetInfo() succeeds. Up to now we do not actually create the file when method Open() of the EFI_FILE_PROTOCOL is called. If method Open() of the EFI_FILE_PROTOCOL is called with EFI_FILE_MODE_CREATE and the file does not yet exist, call fs_write() with a buffer size of zero to actually create the file. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
-rw-r--r--lib/efi_loader/efi_file.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c
index be3e55f4d87..e7ea2466fe4 100644
--- a/lib/efi_loader/efi_file.c
+++ b/lib/efi_loader/efi_file.c
@@ -135,6 +135,25 @@ static int sanitize_path(char *path)
}
/**
+ * efi_create_file() - create file or directory
+ *
+ * @fh: file handle
+ * @attributes: attributes for newly created file
+ * Returns: 0 for success
+ */
+static int efi_create_file(struct file_handle *fh, u64 attributes)
+{
+ loff_t actwrite;
+ void *buffer = &actwrite;
+
+ if (attributes & EFI_FILE_DIRECTORY)
+ return fs_mkdir(fh->path);
+ else
+ return fs_write(fh->path, map_to_sysmem(buffer), 0, 0,
+ &actwrite);
+}
+
+/**
* file_open() - open a file handle
*
* @fs: file system
@@ -176,6 +195,7 @@ static struct efi_file_handle *file_open(struct file_system *fs,
if (parent) {
char *p = fh->path;
+ int exists;
if (plen > 0) {
strcpy(p, parent->path);
@@ -192,18 +212,17 @@ static struct efi_file_handle *file_open(struct file_system *fs,
if (set_blk_dev(fh))
goto error;
- if ((mode & EFI_FILE_MODE_CREATE) &&
- (attributes & EFI_FILE_DIRECTORY)) {
- if (fs_mkdir(fh->path))
- goto error;
- } else if (!((mode & EFI_FILE_MODE_CREATE) ||
- fs_exists(fh->path)))
- goto error;
-
+ exists = fs_exists(fh->path);
/* fs_exists() calls fs_close(), so open file system again */
if (set_blk_dev(fh))
goto error;
+ if (!exists) {
+ if (!(mode & EFI_FILE_MODE_CREATE) ||
+ efi_create_file(fh, attributes))
+ goto error;
+ }
+
/* figure out if file is a directory: */
fh->isdir = is_dir(fh);
} else {