Saturday, July 29, 2006

Linux Kernel 2.4 API's

get_unused_fd() - Attempts to find an empty slot in the current process's file descriptor table and marks it busy. The operation can fail, if the process has too many file descriptors open.

Prototype: int get_unused_fd(void)

fd_install() - Associates the file structure returned by filp_open() to the allocated slot in the file descriptor.

Prototype: void fd_install(unsigned int fd, struct file *file)


# int fd = get_unused_fd();
# struct file *f = filp_open(name, flags, mode)
# fd_install(fd, f);

filp_open() - Does the real open

Prototype: struct file *filp_open(const char *filename, int flags, int mode)

open_namei() - Fills in the nameidata structure containing the dentry and vfsmount structures. This function interacts with the dentry cache via path_walk(), which in turn calls real_lookup(), which invokes the filesystem specific inode_operations->lookup() method. The role of this function is to find the entry in the parent directory with the matching name and then do iget(sb, ino) to get the corresponding inode - which brings us to the inode cache. When the inode is read in, the dentry in instantiated by means of d_add(dentry, inode).

Prototype: open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)

# struct file *filp_open (const char *name, int flags, int mode)
# {
# struct nameidata nd;
# open_namei (filename, namei_flags, mode, &nd);
# return dentry_open(nd.dentry, nd.mnt, flags);
# }

dentry_open() - Given a dentry and vfsmount, this function allocates a new 'struct file' and links them together; it also invokes the filesystem specific f_op->open() method which are set in inode->i_fop when inode was read in open_namei() (which provied inode via dentry->d_inode).

Prototype: struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)

Example: Refer open_namei()

getname() - Copies the file name from user space to the kernel space.

Prototype: char *getname(const char *filename)

cached_lookup() - Tries to find the given dentry in a cache of recently used dentries. If it is not found, the real_lookup() goes to the filesystem, which goes to the disk and actually finds the thing.

register_filesystem() - Registers a file system with the kernel. This function returns error if the file system is slready registered else stores the 'file_system_type' in the kernels filesystem table.
Main information stored in 'struct file_system_type' is
struct file_system_type {
const char *name;
struct super_block * (*read_super) ...;
where 'name' - name of the file system.
'read_super' - will be responsible for initializing a 'struct super_block'. The superblock contains fundamental information, and also pointers to the block device operations needed to operate on this filesystem.

Prototype: int register_filesystem(struct file_system_type *fs)

lookup_create() - Looks up a dentry, creates it if it does not exist

Prototype: struct dentry *lookup_create(struct nameidata *nd, int is_dir)

get_fs() - Returns the current address limit (must always be in terms of a process)
Refer "Linux Kernel Programming - Points to remember.txt Point 2"

set_fs() - Sets the current address limit. Only options available are KERNEL_DS & USER_DS
Refer "Linux Kernel Programming - Points to remember.txt Point 2"


# old_fs = get_fs();
# set_fs(KERNEL_DS);
# fd = sys_open(filename, O_RDONLY, 0);
# if (fd >= 0) {
# /* read the file here */
# sys_close(fd);
# }
# set_fs(old_fs);

dget() - Gets a reference to a dentry. Given a dentry, increments the reference count. A dentry will never be destroyed in reference exist.

Prototype: struct dentry * dget (struct dentry * dentry)

atomic_read() - Reads atomic variable

Prototype: atomic_read(atomic_t *)

atomic_inc() -

path_lookup() -

path_release() -

d_path() - Returns ASCII parh name provided dentry & vfsmount
Prototype: char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, char *buf, int buflen)

mntget() - Increments mount count

Prototype: struct vfsmount *mntget(struct vfsmount *mnt)

Function Definition:

# struct vfsmount *mntget(struct vfsmount *mnt)
# {
# if (mnt)
# atomic_inc(&mnt->mnt_count);
# return mnt;
# }

mntput() - Decrements the mount count. It also decrements dentry associated with the mount point, if mount count is zero.

Prototype: void mntput(struct vfsmount *mnt)

Function Definition:

# void mntput(struct vfsmount *mnt)
# {
# if (mnt) {
# if (atomic_dec_and_test(&mnt->mnt_count))
# __mntput(mnt);
# }
# }

putname() - Free's kernel memory reserved by calling getname().

Prototype: putname(name) (macro)

dput() - Release dentry. This will drop the usage count and if appropriate call the dentry unlink method as well as removing it from the queues and releaseing its resources. If the parent dentries were scheduled for release they too many now get deleted.

Prototype: void dput(struct dentry *dentry)

schedule_timeout() - Sleep until timeout. Make the current task sleep until timeout jiffies have elapsed. The routine will return immediately unless the current task state has been set

Prototype: signed long schedule_timeout (signed long timeout);
where - timeout value in jiffies


No comments: