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 *);
};