Skip to contentSkip to conversation

fs: add symlink and readlink support

PATCH Superseded Jean-Christophe PLAGNIOL-VILLARD 2 participants 3 messages Sep 3, 2012 – Sep 4, 2012 VFS

v3 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v3 cover fs: add symlink and readlink support

HI,

v4:
drop the mounted path added to absolute symlink

v3:
- fix support
mkdir mymount
mount -t ramfs none mymount/
ln /env/boot/net /mymount/link

- addres comments

v2:
addres comments

please pull
The following changes since commit b77300ac6c6bbbc7eac774ff0076c7c05d39735f:

command/mount: add autodetection support (2012-08-21 18:53:00 +0800)

are available in the git repository at:

git://git.jcrosoft.org/barebox.git tags/fs-symlink

for you to fetch changes up to 9919df3e6c53db0edca9f0a9297b7a9e335575de:

defautenv: add support of symlink (2012-09-03 22:46:05 +0800)

----------------------------------------------------------------
fs: add symlink and readlink support

This patch series introduce the support of symlink and readlink at

1) vfs level

2) libc API
- symlink
- readlink

3) commands
- ln
- readlink

3) filesystem
- ramfs
- nfs
- envfs

----------------------------------------------------------------
Jean-Christophe PLAGNIOL-VILLARD (18):
fs: add readlink support
fs: rename stat to lstat as we implement lstat
fs: add symlink support
fs: implement stat
fs: open: add symlink support
fs: introduce get_mounted_path to get the path where a file is mounted
ramfs: add symlink and readlink support
nfs: add readlink support
test: add -L support to test if it's a symbolic link
command: add readlink support
command: add ln support
ls: add symlink support to -l
dirname: add -V option to return only path related to the mountpoint
recursive_action: add ACTION_FOLLOWLINKS support
envfs: introduce version major and minor
envfs: add support of variable inode size
envfs: add support of symlink
defautenv: add support of symlink

 MAKEALL                |    1 +
 commands/Kconfig       |   10 ++++++++
 commands/Makefile      |    2 ++
 commands/dirname.c     |   24 +++++++++++++++---
 commands/ln.c          |   51 +++++++++++++++++++++++++++++++++++++++
 commands/ls.c          |   31 ++++++++++++++++--------
 commands/readlink.c    |   80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 commands/test.c        |   11 +++++++--
 common/Makefile        |    2 +-
 common/environment.c   |  150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
 fs/fs.c                |  223 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 fs/nfs.c               |   86 ++++++++++++++++++++++++++++++++++++++++++++---------------------
 fs/ramfs.c             |   61 +++++++++++++++++++++++++++++++++++++++++-----
 include/envfs.h        |   15 ++++++++++--
 include/fs.h           |   12 +++++++++
 include/libbb.h        |    2 +-
 lib/recursive_action.c |    7 +++++-
 scripts/bareboxenv.c   |    2 +-
 18 files changed, 670 insertions(+), 100 deletions(-)
 create mode 100644 commands/ln.c
 create mode 100644 commands/readlink.c

Best Regards,
J.

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

#1 lore raw

PATCH v4 1/18 fs: add readlink support

---
 fs/fs.c      |   37 +++++++++++++++++++++++++++++++++++++
 include/fs.h |    5 +++++
 2 files changed, 42 insertions(+)
fs/fs.c +37 -0
index 8ab1a3a..2320c3c 100644
@@ -890,6 +890,43 @@ int close(int fd)
 }
 EXPORT_SYMBOL(close);
 
+int readlink(const char *pathname, char *buf, size_t bufsiz)
+{
+	struct fs_driver_d *fsdrv;
+	struct fs_device_d *fsdev;
+	char *p = normalise_path(pathname);
+	char *freep = p;
+	int ret;
+
+	ret = path_check_prereq(pathname, S_IFLNK);
+	if (ret)
+		goto out;
+
+	fsdev = get_fs_device_and_root_path(&p);
+	if (!fsdev) {
+		ret = -ENODEV;
+		goto out;
+	}
+	fsdrv = fsdev->driver;
+
+	if (fsdrv->readlink)
+		ret = fsdrv->readlink(&fsdev->dev, p, buf, bufsiz);
+	else
+		ret = -ENOSYS;
+
+	if (ret)
+		goto out;
+
+out:
+	free(freep);
+
+	if (ret)
+		errno = -ret;
+
+	return ret;
+}
+EXPORT_SYMBOL(readlink);
+
 static int fs_match(struct device_d *dev, struct driver_d *drv)
 {
 	return strcmp(dev->name, drv->name) ? -1 : 0;
include/fs.h +5 -0
index 22470e6..96fe9be 100644
@@ -51,6 +51,9 @@ struct fs_driver_d {
 	/* Truncate a file to given size */
 	int (*truncate)(struct device_d *dev, FILE *f, ulong size);
 
+	int (*readlink)(struct device_d *dev, const char *pathname, char *name,
+			size_t size);
+
 	int (*open)(struct device_d *dev, FILE *f, const char *pathname);
 	int (*close)(struct device_d *dev, FILE *f);
 	int (*read)(struct device_d *dev, FILE *f, void *buf, size_t size);
@@ -129,6 +132,8 @@ DIR *opendir(const char *pathname);
 struct dirent *readdir(DIR *dir);
 int closedir(DIR *dir);
 
+int readlink(const char *path, char *buf, size_t bufsiz);
+
 int mount (const char *device, const char *fsname, const char *path);
 int umount(const char *pathname);
 
Signature · 7 lines
1.7.10.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#2 lore raw
In reply to Jean-Christophe PLAGNIOL-VILLARD
Quoted 16 lines · Jean-Christophe PLAGNIOL-VILLARD

HI,

v4:
drop the mounted path added to absolute symlink

v3:
- fix support
mkdir mymount
mount -t ramfs none mymount/
ln /env/boot/net /mymount/link

- addres comments

v2:
addres comments

Quoted 8 lines

please pull
The following changes since commit b77300ac6c6bbbc7eac774ff0076c7c05d39735f:

command/mount: add autodetection support (2012-08-21 18:53:00 +0800)

are available in the git repository at:

git://git.jcrosoft.org/barebox.git tags/fs-symlink

It gets better. Now we still have:

# ln bla link
# ln bla link
# ls -l
lrwxrwxrwx          3 link -> bla
lrwxrwxrwx          3 link -> bla
# ln a b
# rmdir b
unable to handle NULL pointer dereference at address 0x00000008
pc : [<a7f25fd0>]    lr : [<a7f25fb4>]
sp : a6eff948  ip : 00000003  fp : 00000000
r10: a6ffbddc  r9 : 00000000  r8 : 00000002
r7 : 00000000  r6 : 00000000  r5 : a6fe0e98  r4 : a6ffbb44
r3 : 00000000  r2 : 00000000  r1 : a6ffbdc7  r0 : 00000000
Flags: nZCv  IRQs off  FIQs off  Mode SVC_32
[<a7f25fd0>] (ramfs_rmdir+0x48/0x78) from [<a7f28660>] (rmdir+0x5c/0x88)
[<a7f28660>] (rmdir+0x5c/0x88) from [<a7f18628>] (do_rmdir+0x28/0x6c)
[<a7f18628>] (do_rmdir+0x28/0x6c) from [<a7f050b4>] (execute_command+0x38/0x7c)
[<a7f050b4>] (execute_command+0x38/0x7c) from [<a7f01efc>] (run_list_real+0x8dc/0x9dc)
[<a7f01efc>] (run_list_real+0x8dc/0x9dc) from [<a7f02144>] (parse_stream_outer+0x148/0x238)
[<a7f02144>] (parse_stream_outer+0x148/0x238) from [<a7f024cc>] (run_shell+0x3c/0x7c)
[<a7f024cc>] (run_shell+0x3c/0x7c) from [<a7f050b4>] (execute_command+0x38/0x7c)
[<a7f050b4>] (execute_command+0x38/0x7c) from [<a7f01efc>] (run_list_real+0x8dc/0x9dc)
[<a7f01efc>] (run_list_real+0x8dc/0x9dc) from [<a7f01a58>] (run_list_real+0x438/0x9dc)

[<a7f2c524>] (unwind_backtrace+0x0/0x9c) from [<a7f1bce0>] (panic+0x28/0x3c) [<a7f1bce0>] (panic+0x28/0x3c) from [<a7f2c97c>] (do_exception+0x10/0x14) [<a7f2c97c>] (do_exception+0x10/0x14) from [<a7f2ca08>] (do_data_abort+0x2c/0x38) [<a7f2ca08>] (do_data_abort+0x2c/0x38) from [<a7f2c750>] (data_abort+0x50/0x60)

While you are at it, the 'ln' command should be under "file commands", not under "scripting commands".

For links to directories I agree, this is nontrivial and can be added later. I don't see though why links to links shouldn't be supported from the start. All it takes is the following, right?

8<------------------------------------------------

fs/fs.c +10 -4
index 7c59126..447b56f 100644
@@ -580,13 +580,13 @@ EXPORT_SYMBOL(unlink);
 static char *realfile(const char *pathname, struct stat *s)
 {
 	char *path = normalise_path(pathname);
-	int ret;
+	int ret, recursive = 16;
 
 	ret = lstat(path, s);
 	if (ret)
 		goto out;
 
-	if (S_ISLNK(s->st_mode)) {
+	while (S_ISLNK(s->st_mode)) {
 		char tmp[PATH_MAX];
 		char *new_path;
 
@@ -603,10 +603,16 @@ static char *realfile(const char *pathname, struct stat *s)
 		path = new_path;
 
 		ret = lstat(path, s);
+		if (ret)
+			goto out;
+
+		if (!recursive--) {
+			ret = -ELOOP;
+			goto out;
+		}
 	}
 
-	if (!ret)
-		return path;
+	return path;
 
 out:
 	free(path);
Signature · 9 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox