Implementing symlinks in a virtual file system
Asked Answered
E

3

6

I'm working on a virtual file system which isn't disk based, kind of like /proc. Now I want to create a symlink within it to a target on a ext3 file system. I haven't found any standard documentation on ways to achieve this. What I've guessed so far is that I have to write a function to put in for symlink in struct inode_operations. But frankly I'm at a loss even with the function parameters.

If it matters, I started off with this tutorial on LWN: http://lwn.net/Articles/13325/

EDIT: I'm working with libfs, not FUSE at the moment

Enterprise answered 27/12, 2009 at 19:56 Comment(1)
I'm actually working on an already existing kernel module that uses libfs to create the virtual file system. I know it'd be easier if I were using FUSE but right now that's out of the question :)Enterprise
E
2

I was able to accomplish it finally. Here is what I did (some details may differ depending on what the filesystem wants to achieve):

  1. Create inode of the symlink with the S_IFLNK mode and add the target to the i_private field.

  2. Implement follow_link because generic_readlink requires it to be present

static void *sample_follow_link (struct dentry *dentry, struct nameidata *nd)
{
    nd->depth = 0;
    nd_set_link(nd, (char *)dentry->d_inode->i_private);
    return NULL;
}

static struct inode_operations sample_inode_ops = {
    .readlink = generic_readlink,
    .follow_link = sample_follow_link,
};

.....
//in the function for the dentry and inode creation 
inode->i_op = sample_inode_ops

Enterprise answered 2/1, 2010 at 18:38 Comment(0)
C
3

Presumably you're using fuse, if you're not, do :)

All you have to do is implement the getattr function to tell the kernel that the object is a symlink, then implement the readlink function and return the path that the link should link to; the kernel will do the rest.

Chroma answered 28/12, 2009 at 20:52 Comment(0)
E
2

I was able to accomplish it finally. Here is what I did (some details may differ depending on what the filesystem wants to achieve):

  1. Create inode of the symlink with the S_IFLNK mode and add the target to the i_private field.

  2. Implement follow_link because generic_readlink requires it to be present

static void *sample_follow_link (struct dentry *dentry, struct nameidata *nd)
{
    nd->depth = 0;
    nd_set_link(nd, (char *)dentry->d_inode->i_private);
    return NULL;
}

static struct inode_operations sample_inode_ops = {
    .readlink = generic_readlink,
    .follow_link = sample_follow_link,
};

.....
//in the function for the dentry and inode creation 
inode->i_op = sample_inode_ops

Enterprise answered 2/1, 2010 at 18:38 Comment(0)
S
1

I would suggest to take a look at linux/fs/ext2/ source code. Files symlink.c, inode.c, namei.c and probably few others. You will get some idea as of what needs to be done. Contrary to expectation, filesystem code of the individual filesystems is actually very short and easy to read.

But maybe instead of creating new virtual filesystem, you might ask yourself another question, wouldn't fuse user level filesystem be enough in my case? They have slightly better documentation to creating virtual filesystems and a few more examples.

Schick answered 28/12, 2009 at 18:21 Comment(1)
Thanks for the suggestion. I'll definitely look in the ext2 source code for some ideas about implementation.Enterprise

© 2022 - 2024 — McMap. All rights reserved.