asmlinkage ssize_t sys_read(unsigned int fd, char * buf, size_t count)
{
        ssize_t ret;
        struct file * file;

        ret = -EBADF;
        file = fget(fd);
        if (file) {
                if (file->f_mode & FMODE_READ) {
                        ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode,
                                                file, file->f_pos, count);
                        if (!ret) {
                                ssize_t (*read)(struct file *, char *, size_t, loff_t *);
                                ret = -EINVAL;
                                if (file->f_op && (read = file->f_op->read) != NULL)
                                        ret = read(file, buf, count, &file->f_pos);
                        }
                }
                fput(file);
        }
        return ret;
}

asmlinkage int sys_statfs(const char * path, struct statfs * buf)
{
        struct dentry * dentry;
        int error;

        lock_kernel();
        dentry = namei(path);
        error = PTR_ERR(dentry);
        if (!IS_ERR(dentry)) {
                struct inode * inode = dentry->d_inode;
                struct super_block * sb = inode->i_sb;

                error = -ENODEV;
                if (sb && sb->s_op && sb->s_op->statfs)
                        error = sb->s_op->statfs(sb, buf, sizeof(struct statfs));

                dput(dentry);
        }
        unlock_kernel();
        return error;
}
 

struct file_operations {
        loff_t (*llseek) (struct file *, loff_t, int);
        ssize_t (*read) (struct file *, char *, size_t, loff_t *);
        ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
        int (*readdir) (struct file *, void *, filldir_t);
        unsigned int (*poll) (struct file *, struct poll_table_struct *);
        int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
        int (*mmap) (struct file *, struct vm_area_struct *);
        int (*open) (struct inode *, struct file *);
        int (*flush) (struct file *);
        int (*release) (struct inode *, struct file *);
        int (*fsync) (struct file *, struct dentry *);
        int (*fasync) (int, struct file *, int);
        int (*check_media_change) (kdev_t dev);
        int (*revalidate) (kdev_t dev);
        int (*lock) (struct file *, int, struct file_lock *);
};

struct inode_operations {
        struct file_operations * default_file_ops;
        int (*create) (struct inode *,struct dentry *,int);
        struct dentry * (*lookup) (struct inode *,struct dentry *);
        int (*link) (struct dentry *,struct inode *,struct dentry *);
        int (*unlink) (struct inode *,struct dentry *);
        int (*symlink) (struct inode *,struct dentry *,const char *);
        int (*mkdir) (struct inode *,struct dentry *,int);
        int (*rmdir) (struct inode *,struct dentry *);
        int (*mknod) (struct inode *,struct dentry *,int,int);
        int (*rename) (struct inode *, struct dentry *,
                        struct inode *, struct dentry *);
        int (*readlink) (struct dentry *, char *,int);
        struct dentry * (*follow_link) (struct dentry *, struct dentry *, unsigned int);
        /*
         * the order of these functions within the VFS template has been
         * changed because SMP locking has changed: from now on all get_block,
         * readpage, writepage and flushpage functions are supposed to do
         * whatever locking they need to get proper SMP operation - for
         * now in most cases this means a lock/unlock_kernel at entry/exit.
         * [The new order is also slightly more logical :)]
         */
        /*
         * Generic block allocator exported by the lowlevel fs. All metadata
         * details are handled by the lowlevel fs, all 'logical data content'
         * details are handled by the highlevel block layer.
         */
        int (*get_block) (struct inode *, long, struct buffer_head *, int);

        int (*readpage) (struct file *, struct page *);
        int (*writepage) (struct file *, struct page *);
        int (*flushpage) (struct inode *, struct page *, unsigned long);

        void (*truncate) (struct inode *);
        int (*permission) (struct inode *, int);
        int (*smap) (struct inode *,int);
        int (*revalidate) (struct dentry *);
};