4 - Manual

Here you can find a list of the functions present in the module and how to use them. LUSE main module follows Lua 5.1 package system, see the Lua 5.1 manual for further explanations.

Quick links:

4.1 - luse module

These functions are global to the LUSE module.

luse.main (argv, fs)

Starts a new filesystem daemon. argv is an array containing additionnal parameters to pass to the FUSE library. fs is a table (or any indexable object) containing methods of the FUSE filesystem you are trying to create.

local luafs = {}
function luafs:getattr(path, stat) return -errno.ENOSYS end
local argv = {"luafs", select(2, ...)}
luse.main(argv, fs)

luse.get_context ([tbl])

Obtain information about the context of the current FUSE request. A table is returned containing fields uid, gid and pid (user, group and thread id of the calling process, respectively). If no arguments are given, a new table is created. If a table is passed as an argument, it is reused and fields are set in it instead.

4.2 - Filesystem methods

These methods may be present in the fs object passed to luse.main. They are all optionnal, though without them your filesystem may not work properly. See example filesystems available in LUSE packages for minimal requirements.

Unless otherwise noted, all these functions should return 0 on success. On error, they should returned a negated error number (for example -errno.EINVAL, see errno module below). Each function will receive the object passed to luse.main as first parameter, that's why they are documented with the colon notation below.

As of FUSE 2.6, there are six FUSE methods that are not bound by LUSE: and init, destroy, lock and bmap which I haven't used yet and are a bit complicated to bind, and getdir and utime which are obsolete.

fs:getattr (path, st)

Get file attributes. st is a stat structure as described in the posixio.new function below. The 'dev' and 'blksize' fields are ignored. The 'ino' field is ignored except if the 'use_ino' mount option is given.

Note that for the find command line utility to work in your filesystem, the 'nlink' field of the stat structure must be properly filled. See this FUSE FAQ entry for more details.

fs:readlink (path, buf, size)

Read the target of a symbolic link. The userdata buffer buf should be filled with a null terminated string. You can use userdata.memcpy to write the content of a string to it.

function luafs:readlink(path, buf, size)
    local link = "/foo"
    userdata.memcpy(buf, link, math.min(size-1, #link)+1)
end

fs:mknod (path, mode, redev)

Create a file node. This is called for creation of all non-directory, non-symlink nodes. If the filesystem defines a create method, then for regular files that will be called instead. mode is a Lua set (see description of stat structure in posixio.new documentation).

fs:mkdir (path, mode)

Create a directory.

fs:unlink (path)

Remove a file.

fs:rmdir (path)

Remove a directory.

fs:symlink (linkname, path)

Create a symbolic link. path is the name of the link itself in the LUSE filesystem, linkname is the linked file.

fs:link (oldpath, newpath)

Create a hard link to a file.

fs:chmod (path, mode)

Change the permission bits of a file. mode is a Lua set (see description of stat structure in posixio.new documentation).

fs:chown (path, uid, gid)

Change the owner and group of a file.

fs:truncate (path, size)

Change the size of a file.

fs:open (path, fi)

File open operation. fi is a fuse_file_info structure (see below). No creation, or truncation flags ('CREAT', 'EXCL', 'TRUNC') will be passed to fs:open. Open should check if the operation is permitted for the given flags. Optionally open may also return an arbitrary file handle in the fuse_file_info structure, which will be passed to all subsequent operations on that file.

The fuse_file_info structure has the following members:

  • flags, table, this table is a lua set, see the documentation of posixio.open
  • writepage, number
  • direct_io, boolean
  • keep_cache, boolean
  • flush, boolean
  • fh, number, the file handle that the filesystem can write to
  • lock_owner, number

fs:read (path, buf, size, offset, fi)

Read data from an open file. buf is a lightuserdata pointing to a buffer of size size. offset is a position inside the file.

Read should return exactly the number of bytes requested except on end of file or on error, otherwise the rest of the data will be substituted with zeroes. An exception to this is when the direct_io mount option is specified, in which case the return value of the read system call will reflect the return value of this operation.

fs:write (path, buf, size, offset, fi)

Write data to an open file. buf is a lightuserdata pointing to a buffer of size size. offset is a position inside the file.

Write should return exactly the number of bytes requested except on error. An exception to this is when the direct_io mount option is specified (see read operation).

fs:statfs (path, st)

Get file system statistics. st is a statvfs structure (see posixio.new documentation).The 'frsize', 'favail', 'fsid' and 'flag' fields are ignored.

fs:flush (path, fi)

Possibly flush cached data.

BIG NOTE: This is not equivalent to fsync(). It's not a request to sync dirty data.

Flush is called on each fs:close of a file descriptor. So if a filesystem wants to return write errors in fs:close and the file has cached dirty data, this is a good place to write back data and return any errors. Since many applications ignore fs:close errors this is not always useful.

NOTE: The fs:flush method may be called more than once for each fs:open. This happens if more than one file descriptor refers to an opened file due to dup(), dup2() or fork() calls. It is not possible to determine if a flush is final, so each flush should be treated equally. Multiple write-flush sequences are relatively rare, so this shouldn't be a problem.

Filesystems shouldn't assume that fs:flush will always be called after some writes, or that if will be called at all.

fs:release (path, fi)

Release an open file.

Release is called when there are no more references to an open file: all file descriptors are closed and all memory mappings are unmapped.

For every open() call there will be exactly one release() call with the same flags and file descriptor. It is possible to have a file opened more than once, in which case only the last release will mean, that no more reads/writes will happen on the file. The return value of release is ignored.

fs:fsync (path, datasync, fi)

Synchronize file contents. If the datasync parameter is true, then only the user data should be flushed, not the meta data.

fs:listxattr (path, list, size)

List extended attributes.

fs:removexattr (path, name)

Remove extended attributes.

fs:opendir (path, fi)

Open directory. This method should check if the open operation is permitted for this directory.

fs:readdir (path, filler, off, fi)

Read directory. filler is a function with the prototype filler(name, off, fi) that must be called for each directory entry.

The filesystem may choose between two modes of operation:

  1. The readdir implementation ignores the offset parameter, and passes zero to the filler function's offset. The filler function will not return 1 (unless an error happens), so the whole directory is read in a single readdir operation.
  2. The readdir implementation keeps track of the offsets of the directory entries. It uses the offset parameter and always passes non-zero offset to the filler function. When the buffer is full (or an error happens) the filler function will return 1.

NOTE: This LUSE binding currently only support the first mode of operation. You must pass nil as off parameter to the filler function.

fs:releasedir (path, fi)

Release directory.

fs:fsyncdir (path, datasync, fi)

Synchronize directory contents. If the datasync parameter is true, then only the user data should be flushed, naot the meta data.

fs:access (path, mask)

Check file access permissions. This will be called for the access() system call. If the 'default_permissions' mount option is given, this method is not called.

This method is not called under Linux kernel versions 2.4.x.

fs:create (path, mode, fi)

Create and open a file.

If the file does not exist, first create it with the specified mode, and then open it.

If this method is not implemented or under Linux kernel versions earlier than 2.6.15, the mknod() and open() methods will be called instead.

fs:ftruncate (path, size, fi)

Change the size of an open file.

This method is called instead of the fs:truncate method if the truncation was invoked from an ftruncate() system call.

If this method is not implemented or under Linux kernel versions earlier than 2.6.15, the fs:truncate method will be called instead.

fs:fgetattr (path, st, fi)

Get attributes from an open file.

This method is called instead of the fs:getattr method if the file information is available.

Currently this is only called after the fs:create method if that is implemented (see above). Later it may be called for invocations of fstat() too.

fs:utimens (path, tv)

Change the access and modification times of a file with nanosecond resolution. tv is a Lua array containing two other tables, the new access time and modification time respectively. These subtables have two fields each:

  • sec, number, time in seconds
  • nsec, number, the sub-second portion of the time, in nanoseconds

4.3 - errno module

The module contains a number of constants taken from various C, POSIX and Linux headers. Not all error codes are there, but the most common for filesystem operation are defined. Ask if you need more. The bound error codes are: EPERM, ENOENT, ESRCH, EINTR, EIO, ENXIO, E2BIG, ENOEXEC, EBADF, ECHILD, EAGAIN, ENOMEM, EACCES, EFAULT, ENOTBLK, EBUSY, EEXIST, EXDEV, ENODEV, ENOTDIR, EISDIR, EINVAL, ENFILE, EMFILE, ENOTTY, ETXTBSY, EFBIG, ENOSPC, ESPIPE, EROFS, EMLINK, EPIPE, EDOM, ERANGE, ENOSYS.

errno.errno

This pseudo-variable is a getter that can retrieve the last C errno number. It can be compared to other errno constants, or returned to LUSE.

errno.strerror (err)

Returns a string corresponding to the error number err.

4.4 - userdata module

This module exposes some functions to manipulate userdata. It also provides a generic way to create a buffer userdata (without metatable or environment).

userdata.memcpy (to, from, size)

Writes data to a userdata. to must be a userdata (full or light). from can be a userdata or a string. size is the number of bytes copied. No check of the destination or source size is made (it's impossible for light userdata), so this function may read past data end or overwrite memory. Use it with care.

userdata.new (size)

Creates a new userdata buffer of the specified size. This is a full userdata allocated by Lua. It has two fields: data, which is a lightuserdata containing the address of the buffer, and size, which is a number containing the size of the buffer. You can also index the buffer with a number key to offset the buffer address (0-based offset). The userdata also have a __tostring metamethod which converts the content of the userdata to a Lua string.

local ud = userdata.new(2) -- create a 2 byte userdata
print(ud.size) -- size of userdata (2)
print(ud.data) -- address of first byte
print(ud[1]) -- address of second byte
print(tostring(ud)) -- print content of the userdata

userdata.tostring (ud)

This functions converts the content of the full userdata ud to a string.

4.5 - posixio module

This module provides some function to manipulate files and directories. It's a light binding over the POSIX API for files and directories. Unless otherwise stated, these functions return an errno error number. You can compare them with constants in the errno module or return them to LUSE.

Except for posixio.new, all files are direct binding to POSIX functions. You can get their documentation through your system manual. Some portions of a Linux manual have been copied here.

posixio.new (type [, count])

Allocates a POSIX structure. Type must be the name of a supported POSIX struct among: 'stat', 'statvfs' and 'timeval'. count can be used to allocate more than one structure. This is currently only supported with timeval structures.

The stat structure has the following members:

  • dev, number, ID of device containing file
  • ino, number, inode number
  • mode, table, protection; this table is a lua set, with the following keys possibly present and true: IFBLK, IFCHR, IFIFO, IFREG, IFDIR, IFLNK, IFSOCK, IRUSR, IWUSR, IXUSR, IRGRP, IWGRP, IXGRP, IROTH, IWOTH, IXOTH, ISUID, ISGID, ISVTX.
  • nlink, number, number of hard links
  • uid, number, user ID of owner
  • gid, number, group ID of owner
  • rdev, number, device ID (if special file)
  • size, number, total size, in bytes
  • blksize, number, blocksize for filesystem I/O
  • blocks, number, number of blocks allocated
  • atime, number, time of last access
  • mtime, number, time of last modification
  • ctime, number, time of last status change

The statvfs structure has the following members:

  • bsize, number, file system block size
  • frsize, number, fragment size
  • blocks, number, size of fs in f_frsize units
  • bfree, number, # free blocks
  • bavail, number, # free blocks for non-root
  • files, number, # inodes
  • ffree, number, # free inodes
  • favail, number, # free inodes for non-root
  • fsid, number, file system ID
  • flag, number, mount flags
  • namemax, number, maximum filename length

The timeval structure has the following members:

  • sec, number, seconds
  • usec, number, microseconds

posixio.stat (path, st)

Get file status. path is the path to a file. st is a stat userdata created with posixio.new('stat').

posixio.fstat (fd, st)

Get file status. fd is the fd of an open file. st is a stat structure that is filled by posixio.stat.

posixio.lstat (path, st)

posixio.lstat is identical to posixio.stat, except that if path is a symbolic link, then the link itself is stated, not the file that it refers to.

posixio.opendir (path)

Open a directory.

Returns nil on error, or a directory userdata on success. See below for the methods of this userdata.

directory:readdir ()

Read a file entry from a directory.

Returns nil on error or end of directory listing, or a dirent structure (as a userdata) on success. The dirent structure has the following fields:

  • ino, number, inode number
  • off, number, offset to this dirent
  • reclen, number, length of this name
  • name, string, filename

directory:closedir ()

Close directory.

posixio.mkdir (path)

Create a directory.

posixio.rmdir (path)

Delete a directory.

posixio.mknod (path, mode, dev)

Create a file. mode is a Lua set (see description of stat structure in posixio.new documentation). dev is the device number.

posixio.unlink (path)

Delete a name and possible the file it refers to.

posixio.open (path, flags)

Open a file. flags is a Lua set. The set must contain one of these three flags: 'RDWR', 'RDONLY' or 'WRONLY'. The following optionnal flags are also recognized: APPEND, ASYNC, CREAT, DIRECT, DIRECTORY, EXCL, LARGEFILE, NOATIME, NOCTTY, NOFOLLOW, NONBLOCK, NDELAY, SYNC, TRUNC.

Returns -1 on error, or a non-negative number on success. That number is a file descriptor and can be used in subsequent access to this file.

posixio.close (fd)

Close a file. fd is a file descriptor of an open file.

posixio.read (fd, buf, size)

Read from a file descriptor. posixio.read attempts to read up to size bytes from file descriptor fd into the userdata buffer buf. buf can be a light or a full userdata; in either case no size check is performed, so use this function with care.

posixio.write (fd, buf, size)

Write to a file descriptor. posixio.write writes up to size bytes to the file referenced by the descriptor fd from the userdata buffer buf. buf can be a light or a full userdata; in either case no size check is performed, so use this function with care.

posixio.lseek (fd, offset, whence)

Reposition read/write offset. The posixio.lseek function repositions the offset of the open file associated with the file descriptor fildes to the argument offset according to the directive whence as follows:

  • 'SET': The offset is set to offset bytes.
  • 'CUR': The offset is set to its current location plus offset bytes.
  • 'END': The offset is set to the size of the file plus offset bytes.

The lseek() function allows the file offset to be set beyond the end of the file (but this does not change the size of the file). If data is later written at this point, subsequent reads of the data in the gap (a "hole") return null bytes ('\0') until data is actually written into the gap.

posixio.statvfs (path, st)

Get file system statistics. The function posixio.statvfs returns information about a mounted file system. path is the pathname of any file within the mounted filesystem. st is a statvfs userdata created with posixio.new('statvfs').

posixio.utimes (path, times)

Change access and modification times of an inode, with resolution of 1 microsecond. path is the path of the file to change times, while times is an array of 2 timeval structures created with posixio.new('timeval', 2).

Note that this function accepts microsecond resolution, while the fs:utimens method of a FUSE filesystem receives nanosecond resolution times. Make the appropriate conversion.

posixio.rename (oldpath, newpath)

Change the name or location of a file.

posixio.getcwd (buf, size)

Put the path of the current working directory in the userdata buffer buf of size size.

Returns the address of buf as a light userdata on success, a NULL light userdata on error.

local buf = userdata.new(posixio.PATH_MAX)
local result = posixio.getcwd(buf.data, buf.size)
if result~=buf.data then error(errno.strerror(errno.errno)) end

posixio.PATH_MAX

This constant is the maximum number of characters allowed in a path on the current system. It may be useful to allocate some buffers passed to other posixio functions.