public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Rob Clark <robdclark@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v0 02/20] fs/fat: implement readdir
Date: Fri,  4 Aug 2017 15:31:44 -0400	[thread overview]
Message-ID: <20170804193205.24669-3-robdclark@gmail.com> (raw)
In-Reply-To: <20170804193205.24669-1-robdclark@gmail.com>

Yes, this is super-hacky.  The FAT code is quite ugly, and this doesn't
improve things.  But it doesn't make it significantly worse either.  The
better option would be a massive FAT re-write to get rid of the hacky
way that fat_file_ls() works.  Volunteers welcome.

Signed-off-by: Rob Clark <robdclark@gmail.com>
---
Yeah, not my proudest patch, but there is little that can be done in
fat.c to be proud of short of re-writing it.. which I am not signing
up for.  I don't think it makes things that much worse than it already
is, but if you disagree I still suggest we merge the previous patch,
to enable merging the efi_loader patches that directly or indirectly
depend on it.  At least then we minimize what is not upstream in order
to have a useful UEFI implementation in u-boot.

 fs/fat/fat.c  | 59 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 fs/fs.c       |  2 +-
 include/fat.h |  4 +++-
 3 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 9ad18f96ff..04d8616598 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -14,6 +14,7 @@
 #include <config.h>
 #include <exports.h>
 #include <fat.h>
+#include <fs.h>
 #include <asm/byteorder.h>
 #include <part.h>
 #include <malloc.h>
@@ -575,17 +576,25 @@ static __u8 mkcksum(const char name[8], const char ext[3])
 /*
  * Get the directory entry associated with 'filename' from the directory
  * starting at 'startsect'
+ *
+ * Last two args are only used for dols==LS_READDIR
  */
 __u8 get_dentfromdir_block[MAX_CLUSTSIZE]
 	__aligned(ARCH_DMA_MINALIGN);
 
-static dir_entry *get_dentfromdir(fsdata *mydata, int startsect,
-				  char *filename, dir_entry *retdent,
-				  int dols)
+static dir_entry *get_dentfromdir(fsdata *mydata, char *filename,
+				  dir_entry *retdent, int dols,
+				  loff_t pos, struct fs_dirent *d)
 {
 	__u16 prevcksum = 0xffff;
 	__u32 curclust = START(retdent);
 	int files = 0, dirs = 0;
+	int readdir = 0;
+
+	if (dols == LS_READDIR) {
+		readdir = 1;
+		dols = 0;
+	}
 
 	debug("get_dentfromdir: %s\n", filename);
 
@@ -618,7 +627,7 @@ static dir_entry *get_dentfromdir(fsdata *mydata, int startsect,
 					get_vfatname(mydata, curclust,
 						     get_dentfromdir_block,
 						     dentptr, l_name);
-					if (dols) {
+					if (dols || readdir) {
 						int isdir;
 						char dirc;
 						int doit = 0;
@@ -637,7 +646,14 @@ static dir_entry *get_dentfromdir(fsdata *mydata, int startsect,
 							}
 						}
 						if (doit) {
-							if (dirc == ' ') {
+							if (readdir) {
+								if ((dirs + files - 1) == pos) {
+									strcpy(d->name, l_name);
+									if (!isdir)
+										d->size = FAT2CPU32(dentptr->size);
+									return NULL;
+								}
+							} else if (dirc == ' ') {
 								printf(" %8u   %s%c\n",
 								       FAT2CPU32(dentptr->size),
 									l_name,
@@ -676,7 +692,7 @@ static dir_entry *get_dentfromdir(fsdata *mydata, int startsect,
 			}
 
 			get_name(dentptr, s_name);
-			if (dols) {
+			if (dols || readdir) {
 				int isdir = (dentptr->attr & ATTR_DIR);
 				char dirc;
 				int doit = 0;
@@ -694,7 +710,14 @@ static dir_entry *get_dentfromdir(fsdata *mydata, int startsect,
 				}
 
 				if (doit) {
-					if (dirc == ' ') {
+					if (readdir) {
+						if ((dirs + files - 1) == pos) {
+							strcpy(d->name, s_name);
+							if (!isdir)
+								d->size = FAT2CPU32(dentptr->size);
+							return NULL;
+						}
+					} else if (dirc == ' ') {
 						printf(" %8u   %s%c\n",
 						       FAT2CPU32(dentptr->size),
 							s_name, dirc);
@@ -825,7 +848,7 @@ int do_fat_read_at(const char *filename, loff_t pos, void *buffer,
 	__u32 cursect;
 	int idx, isdir = 0;
 	int files = 0, dirs = 0;
-	int ret = -1;
+	int ret = (dols == LS_READDIR) ? -ENOTDIR : -1;
 	int firsttime;
 	__u32 root_cluster = 0;
 	__u32 read_blk;
@@ -906,7 +929,8 @@ root_reparse:
 		if (!dols)
 			goto exit;
 
-		dols = LS_ROOT;
+		if (dols == LS_YES)
+			dols = LS_ROOT;
 	} else if ((idx = dirdelim(fnamecopy)) >= 0) {
 		isdir = 1;
 		fnamecopy[idx] = '\0';
@@ -1151,8 +1175,6 @@ rootdir_done:
 	firsttime = 1;
 
 	while (isdir) {
-		int startsect = mydata->data_begin
-			+ START(dentptr) * mydata->clust_size;
 		dir_entry dent;
 		char *nextname = NULL;
 
@@ -1177,10 +1199,14 @@ rootdir_done:
 			}
 		}
 
-		if (get_dentfromdir(mydata, startsect, subname, dentptr,
-				     isdir ? 0 : dols) == NULL) {
+		if (get_dentfromdir(mydata, subname, dentptr,
+				    isdir ? 0 : dols, pos, buffer) == NULL) {
 			if (dols && !isdir)
 				*size = 0;
+			if (dols == LS_READDIR) {
+				struct fs_dirent *dent = buffer;
+				ret = dent->name[0] ? 0 : -ENOENT;
+			}
 			goto exit;
 		}
 
@@ -1353,6 +1379,13 @@ int fat_read_file(const char *filename, void *buf, loff_t offset, loff_t len,
 	return ret;
 }
 
+int fat_readdir(const char *filename, loff_t offset, struct fs_dirent *dent)
+{
+	loff_t actread;
+	return do_fat_read_at(filename, offset, dent, sizeof(*dent),
+			      LS_READDIR, 0, &actread);
+}
+
 void fat_close(void)
 {
 }
diff --git a/fs/fs.c b/fs/fs.c
index 5ac4226ece..42a028a6ce 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -119,7 +119,7 @@ static struct fstype_info fstypes[] = {
 		.write = fs_write_unsupported,
 #endif
 		.uuid = fs_uuid_unsupported,
-		.readdir = fs_readdir_unsupported,
+		.readdir = fat_readdir,
 	},
 #endif
 #ifdef CONFIG_FS_EXT4
diff --git a/include/fat.h b/include/fat.h
index 71879f01ca..0ef3f5be16 100644
--- a/include/fat.h
+++ b/include/fat.h
@@ -61,8 +61,8 @@
 /* Flags telling whether we should read a file or list a directory */
 #define LS_NO		0
 #define LS_YES		1
-#define LS_DIR		1
 #define LS_ROOT		2
+#define LS_READDIR	3	/* read directory entry at specified offset */
 
 #define ISDIRDELIM(c)	((c) == '/' || (c) == '\\')
 
@@ -210,5 +210,7 @@ int file_fat_write(const char *filename, void *buf, loff_t offset, loff_t len,
 		   loff_t *actwrite);
 int fat_read_file(const char *filename, void *buf, loff_t offset, loff_t len,
 		  loff_t *actread);
+struct fs_dirent;
+int fat_readdir(const char *filename, loff_t offset, struct fs_dirent *dir);
 void fat_close(void);
 #endif /* _FAT_H_ */
-- 
2.13.0

  parent reply	other threads:[~2017-08-04 19:31 UTC|newest]

Thread overview: 116+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-04 19:31 [U-Boot] [PATCH v0 00/20] enough UEFI for standard distro boot Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 01/20] fs: add fs_readdir() Rob Clark
2017-08-07 18:19   ` Brüns, Stefan
2017-08-07 19:11     ` Rob Clark
2017-08-04 19:31 ` Rob Clark [this message]
2017-08-04 19:31 ` [U-Boot] [PATCH v0 03/20] short-wchar Rob Clark
2017-08-04 20:28   ` Heinrich Schuchardt
2017-08-04 20:36     ` Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 04/20] part: extract MBR signature from partitions Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 05/20] efi: add some more device path structures Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 06/20] common: add some utf16 handling helpers Rob Clark
2017-08-06  5:17   ` Simon Glass
2017-08-08 22:50   ` [U-Boot] [U-Boot, v0, " Heinrich Schuchardt
2017-08-08 23:21     ` Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 07/20] vsprintf.c: add wide string (%ls) support Rob Clark
2017-08-08 22:03   ` [U-Boot] [U-Boot, v0, " Heinrich Schuchardt
2017-08-08 22:44     ` Rob Clark
2017-08-08 23:08       ` Heinrich Schuchardt
2017-08-08 23:20         ` Alexander Graf
2017-08-08 23:39         ` Rob Clark
2017-08-08 23:55           ` Alexander Graf
2017-08-09  0:14             ` Rob Clark
2017-08-09  1:14               ` Rob Clark
2017-08-09 11:27               ` Tom Rini
2017-08-10  2:16                 ` rick at andestech.com
2017-08-09  8:50           ` Peter Robinson
2017-08-08 22:52     ` Rob Clark
2017-08-09 13:38     ` Rob Clark
2017-08-09 13:48       ` Alexander Graf
2017-08-09 14:35         ` Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 08/20] efi_loader: add back optional efi_handler::open() Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 09/20] efi_loader: add device-path utils Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 10/20] efi_loader: drop redundant efi_device_path_protocol Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 11/20] efi_loader: add guidstr helper Rob Clark
2017-08-05 19:33   ` Heinrich Schuchardt
2017-08-05 19:56     ` Rob Clark
2017-08-05 20:18       ` Heinrich Schuchardt
2017-08-04 19:31 ` [U-Boot] [PATCH v0 12/20] efi_loader: flesh out device-path to text Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 13/20] efi_loader: use proper device-paths for partitions Rob Clark
2017-08-04 20:41   ` Mark Kettenis
2017-08-04 20:57     ` Rob Clark
2017-08-05 14:01       ` Mark Kettenis
2017-08-05 14:19         ` Rob Clark
2017-08-05 14:28         ` Mark Kettenis
2017-08-05 14:35           ` Rob Clark
2017-08-05 15:08             ` Mark Kettenis
2017-08-05 15:22               ` Rob Clark
2017-08-05 16:02                 ` Heinrich Schuchardt
2017-08-05 16:13                   ` Rob Clark
2017-08-05 15:10             ` Heinrich Schuchardt
2017-08-05 15:24               ` Rob Clark
2017-08-05 15:36                 ` Rob Clark
2017-08-06 13:16                   ` Mark Kettenis
2017-08-06 14:17                     ` Rob Clark
2017-08-06 14:26                       ` Rob Clark
2017-08-06 14:28                     ` Mark Kettenis
2017-08-06 14:45                       ` Rob Clark
2017-08-06 15:34                         ` Rob Clark
2017-08-06 16:00                           ` Heinrich Schuchardt
2017-08-06 16:14                           ` Jonathan Gray
2017-08-06 17:28                           ` Mark Kettenis
2017-08-06 17:49                             ` Rob Clark
2017-08-06 18:13                               ` Peter Robinson
2017-08-06 18:21                               ` Mark Kettenis
2017-08-06 18:37                                 ` Mark Kettenis
2017-08-06 18:47                                   ` Rob Clark
2017-08-06 18:53                                     ` Rob Clark
2017-08-06 18:41                                 ` Rob Clark
2017-08-07 15:47                           ` Jonathan Gray
2017-08-07 16:16                             ` Rob Clark
2017-08-08  1:36                               ` Jonathan Gray
2017-08-05 14:28         ` Rob Clark
2017-08-06 12:53           ` Mark Kettenis
2017-08-07 17:32     ` Peter Jones
2017-08-04 19:31 ` [U-Boot] [PATCH v0 14/20] efi_loader: use proper device-paths for net Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 15/20] efi_loader: refactor boot device and loaded_image handling Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 16/20] efi_loader: add file/filesys support Rob Clark
2017-08-04 19:31 ` [U-Boot] [PATCH v0 17/20] efi_loader: support load_image() from a file-path Rob Clark
2017-08-04 19:32 ` [U-Boot] [PATCH v0 18/20] efi_loader: make pool allocations cacheline aligned Rob Clark
2017-08-04 19:32 ` [U-Boot] [PATCH v0 19/20] efi_loader: efi variable support Rob Clark
2017-08-06  5:17   ` Simon Glass
2017-08-04 19:32 ` [U-Boot] [PATCH v0 20/20] efi_loader: add bootmgr Rob Clark
2017-08-04 20:06   ` Heinrich Schuchardt
2017-08-04 20:28     ` Rob Clark
2017-08-04 20:29       ` Rob Clark
2017-08-04 22:46       ` Peter Jones
2017-08-05 15:58 ` [U-Boot] [PATCH v0 21/20] efi_loader: hack for archs that cannot do unaligned accesses Rob Clark
2017-08-05 16:12   ` Heinrich Schuchardt
2017-08-05 16:16     ` Rob Clark
2017-08-05 16:19       ` Rob Clark
2017-08-05 16:26         ` Heinrich Schuchardt
2017-08-05 16:46           ` Rob Clark
2017-08-05 16:52       ` Heinrich Schuchardt
2017-08-05 17:06         ` Rob Clark
2017-08-05 18:43           ` Rob Clark
2017-08-05 20:05             ` Heinrich Schuchardt
2017-08-05 20:31               ` Rob Clark
2017-08-07 20:19                 ` Alexander Graf
2017-08-07 21:14                   ` Mark Kettenis
2017-08-07 22:18                     ` Rob Clark
2017-08-08  6:52                       ` Alexander Graf
2017-08-08  8:11                         ` Ard Biesheuvel
2017-08-08 11:32                           ` Leif Lindholm
2017-08-08 12:01                             ` Rob Clark
2017-08-08 12:39                               ` Leif Lindholm
2017-08-08  9:27                         ` Rob Clark
2017-08-08 12:26                       ` Mark Kettenis
2017-08-08 12:54                         ` Rob Clark
2017-08-08 13:33                           ` Mark Kettenis
2017-08-08 14:03                             ` Rob Clark
2017-08-08 14:10                               ` Rob Clark
2017-08-08 18:20                               ` Rob Clark
2017-08-07 16:56           ` Rob Clark
2017-08-07 17:15         ` Peter Jones
2017-08-10  1:32 ` [U-Boot] [PATCH v0 00/20] enough UEFI for standard distro boot Tom Rini
2017-08-10 10:41   ` Rob Clark

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170804193205.24669-3-robdclark@gmail.com \
    --to=robdclark@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox