I'm writing a File system in userspace (FUSE) and trying to overwrite a soft link.
For example, this is the fuse structure:
/dir -- file_a
-- file_b
-- link_a -> /points/to/some/file
-- link_b -> /points/to/some/file
When I try to change the link with ln command:
ln -fs /new/file/to/point /dir/link_a
My symlink implementation gets a random file name:
int my_symlink(const char * lnk, const char * pth)
{
print("SYMLINK %s\n%s\n", pth, lnk);
return 0;
}
SYMLINK /dir/CuOG78dJ
/new/file/to/point
The "CuOG78dJ" part is always different.
I thought that in order to delete/overwrite the existing file, fuse is calling some other function before symlink, so I implemented unlink, rename, ioctl, mknod, truncate, chmod, chown and open, but none of these was called before symlink.
UPDATE
I added a print function to my readlink and getattr implementations, and I'm mounting the file system with debug option, and this is the result:
Print output when I use the ln
function:
GETATTR /dir
GETATTR /dir/link_a
READLINK /dir/link_a, buf: /points/to/some/file
GETATTR /dir/link_a
GETATTR /dir/CuFSXC22
SYMLINK /dir/CuFSXC22 /new/file/to/point
GETATTR /dir/CuFSXC22
The readlink function returns the current path, which is /points/to/some/file, and the getattr function does:
st->st_uid = getuid();
st->st_gid = getgid();
st->st_atime = time( NULL );
st->st_mtime = time( NULL );
st->st_mode = S_IFLNK | 0777;
st->st_nlink = 1;
st->st_size = 1024;
This is the file system debug output when I use the ln
command:
unique: 5, opcode: LOOKUP (1), nodeid: 1, insize: 52, pid: 24832
LOOKUP /dir
getattr /dir
NODEID: 2
unique: 5, success, outsize: 144
unique: 6, opcode: LOOKUP (1), nodeid: 2, insize: 53, pid: 24832
LOOKUP /dir/link_a
getattr /dir/link_a
NODEID: 3
unique: 6, success, outsize: 144
unique: 7, opcode: READLINK (5), nodeid: 3, insize: 40, pid: 24832
readlink /dir/link_a 4097
unique: 7, success, outsize: 25
unique: 8, opcode: GETATTR (3), nodeid: 3, insize: 56, pid: 24832
getattr /dir/link_a
unique: 8, success, outsize: 120
unique: 9, opcode: LOOKUP (1), nodeid: 2, insize: 49, pid: 24832
LOOKUP /dir/Cuysnat0
getattr /dir/Cuysnat0
unique: 9, error: -2 (No such file or directory), outsize: 16
unique: 10, opcode: SYMLINK (6), nodeid: 2, insize: 131, pid: 24832
symlink /new/file/to/point /dir/Cuysnat0
getattr /dir/Cuysnat0
unique: 10, error: -2 (No such file or directory), outsize: 16
Maybe someone can help with that? Thanks
Seems that when I try to overwrite the symlink, ln
creates a random symlink, which points to the wanted file, then renames the symlink.
In order to make it work, I had to: