📄 fs.h
字号:
extern int fsync_dev(kdev_t);
extern int fsync_inode_buffers(struct inode *);
extern int osync_inode_buffers(struct inode *);
extern int inode_has_buffers(struct inode *);
extern void filemap_fdatasync(struct address_space *);
extern void filemap_fdatawait(struct address_space *);
extern void sync_supers(kdev_t);
extern int bmap(struct inode *, int);
extern int notify_change(struct dentry *, struct iattr *);
extern int permission(struct inode *, int);
extern int vfs_permission(struct inode *, int);
extern int get_write_access(struct inode *);
extern int deny_write_access(struct file *);
static inline void put_write_access(struct inode * inode)
{
atomic_dec(&inode->i_writecount);
}
static inline void allow_write_access(struct file *file)
{
if (file)
atomic_inc(&file->f_dentry->d_inode->i_writecount);
}
extern int do_pipe(int *);
extern int open_namei(const char *, int, int, struct nameidata *);
extern int kernel_read(struct file *, unsigned long, char *, unsigned long);
extern struct file * open_exec(const char *);
/* fs/dcache.c -- generic fs support functions */
extern int is_subdir(struct dentry *, struct dentry *);
extern ino_t find_inode_number(struct dentry *, struct qstr *);
/*
* Kernel pointers have redundant information, so we can use a
* scheme where we can return either an error code or a dentry
* pointer with the same return value.
*
* This should be a per-architecture thing, to allow different
* error and pointer decisions.
*/
static inline void *ERR_PTR(long error)
{
return (void *) error;
}
static inline long PTR_ERR(const void *ptr)
{
return (long) ptr;
}
static inline long IS_ERR(const void *ptr)
{
return (unsigned long)ptr > (unsigned long)-1000L;
}
/*
* The bitmask for a lookup event:
* - follow links at the end
* - require a directory
* - ending slashes ok even for nonexistent files
* - internal "there are more path compnents" flag
*/
#define LOOKUP_FOLLOW (1)
#define LOOKUP_DIRECTORY (2)
#define LOOKUP_CONTINUE (4)
#define LOOKUP_POSITIVE (8)
#define LOOKUP_PARENT (16)
#define LOOKUP_NOALT (32)
/*
* Type of the last component on LOOKUP_PARENT
*/
enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
/*
* "descriptor" for what we're up to with a read for sendfile().
* This allows us to use the same read code yet
* have multiple different users of the data that
* we read from a file.
*
* The simplest case just copies the data to user
* mode.
*/
typedef struct {
size_t written;
size_t count;
char * buf;
int error;
} read_descriptor_t;
typedef int (*read_actor_t)(read_descriptor_t *, struct page *, unsigned long, unsigned long);
/* needed for stackable file system support */
extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
extern int __user_walk(const char *, unsigned, struct nameidata *);
extern int path_init(const char *, unsigned, struct nameidata *);
extern int path_walk(const char *, struct nameidata *);
extern void path_release(struct nameidata *);
extern int follow_down(struct vfsmount **, struct dentry **);
extern int follow_up(struct vfsmount **, struct dentry **);
extern struct dentry * lookup_one(const char *, struct dentry *);
extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
#define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
#define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
extern void iput(struct inode *);
extern void force_delete(struct inode *);
extern struct inode * igrab(struct inode *);
extern ino_t iunique(struct super_block *, ino_t);
typedef int (*find_inode_t)(struct inode *, unsigned long, void *);
extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *);
static inline struct inode *iget(struct super_block *sb, unsigned long ino)
{
return iget4(sb, ino, NULL, NULL);
}
extern void clear_inode(struct inode *);
extern struct inode * get_empty_inode(void);
static inline struct inode * new_inode(struct super_block *sb)
{
struct inode *inode = get_empty_inode();
if (inode) {
inode->i_sb = sb;
inode->i_dev = sb->s_dev;
}
return inode;
}
extern void insert_inode_hash(struct inode *);
extern void remove_inode_hash(struct inode *);
extern struct file * get_empty_filp(void);
extern void file_move(struct file *f, struct list_head *list);
extern void file_moveto(struct file *new, struct file *old);
extern struct buffer_head * get_hash_table(kdev_t, int, int);
extern struct buffer_head * getblk(kdev_t, int, int);
extern void ll_rw_block(int, int, struct buffer_head * bh[]);
extern void submit_bh(int, struct buffer_head *);
extern int is_read_only(kdev_t);
extern void __brelse(struct buffer_head *);
static inline void brelse(struct buffer_head *buf)
{
if (buf)
__brelse(buf);
}
extern void __bforget(struct buffer_head *);
static inline void bforget(struct buffer_head *buf)
{
if (buf)
__bforget(buf);
}
extern void set_blocksize(kdev_t, int);
extern unsigned int get_hardblocksize(kdev_t);
extern struct buffer_head * bread(kdev_t, int, int);
extern void wakeup_bdflush(int wait);
extern int brw_page(int, struct page *, kdev_t, int [], int);
typedef int (get_block_t)(struct inode*,long,struct buffer_head*,int);
/* Generic buffer handling for block filesystems.. */
extern int block_flushpage(struct page *, unsigned long);
extern int block_symlink(struct inode *, const char *, int);
extern int block_write_full_page(struct page*, get_block_t*);
extern int block_read_full_page(struct page*, get_block_t*);
extern int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
extern int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*,
unsigned long *);
extern int block_sync_page(struct page *);
int generic_block_bmap(struct address_space *, long, get_block_t *);
int generic_commit_write(struct file *, struct page *, unsigned, unsigned);
int block_truncate_page(struct address_space *, loff_t, get_block_t *);
extern int generic_file_mmap(struct file *, struct vm_area_struct *);
extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *);
extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *);
extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t);
extern ssize_t generic_read_dir(struct file *, char *, size_t, loff_t *);
extern struct file_operations generic_ro_fops;
extern int vfs_readlink(struct dentry *, char *, int, const char *);
extern int vfs_follow_link(struct nameidata *, const char *);
extern int page_readlink(struct dentry *, char *, int);
extern int page_follow_link(struct dentry *, struct nameidata *);
extern struct inode_operations page_symlink_inode_operations;
extern int vfs_readdir(struct file *, filldir_t, void *);
extern int dcache_readdir(struct file *, void *, filldir_t);
extern struct file_system_type *get_fs_type(const char *name);
extern struct super_block *get_super(kdev_t);
struct super_block *get_empty_super(void);
extern void put_super(kdev_t);
unsigned long generate_cluster(kdev_t, int b[], int);
unsigned long generate_cluster_swab32(kdev_t, int b[], int);
extern kdev_t ROOT_DEV;
extern char root_device_name[];
extern void show_buffers(void);
extern void mount_root(void);
#ifdef CONFIG_BLK_DEV_INITRD
extern kdev_t real_root_dev;
extern int change_root(kdev_t, const char *);
#endif
extern ssize_t char_read(struct file *, char *, size_t, loff_t *);
extern ssize_t block_read(struct file *, char *, size_t, loff_t *);
extern int read_ahead[];
extern ssize_t char_write(struct file *, const char *, size_t, loff_t *);
extern ssize_t block_write(struct file *, const char *, size_t, loff_t *);
extern int file_fsync(struct file *, struct dentry *, int);
extern int generic_buffer_fdatasync(struct inode *inode, unsigned long start_idx, unsigned long end_idx);
extern int generic_osync_inode(struct inode *, int);
extern int inode_change_ok(struct inode *, struct iattr *);
extern void inode_setattr(struct inode *, struct iattr *);
/*
* Common dentry functions for inclusion in the VFS
* or in other stackable file systems. Some of these
* functions were in linux/fs/ C (VFS) files.
*
*/
/*
* Locking the parent is needed to:
* - serialize directory operations
* - make sure the parent doesn't change from
* under us in the middle of an operation.
*
* NOTE! Right now we'd rather use a "struct inode"
* for this, but as I expect things to move toward
* using dentries instead for most things it is
* probably better to start with the conceptually
* better interface of relying on a path of dentries.
*/
static inline struct dentry *lock_parent(struct dentry *dentry)
{
struct dentry *dir = dget(dentry->d_parent);
down(&dir->d_inode->i_sem);
return dir;
}
static inline struct dentry *get_parent(struct dentry *dentry)
{
return dget(dentry->d_parent);
}
static inline void unlock_dir(struct dentry *dir)
{
up(&dir->d_inode->i_sem);
dput(dir);
}
/*
* Whee.. Deadlock country. Happily there are only two VFS
* operations that does this..
*/
static inline void double_down(struct semaphore *s1, struct semaphore *s2)
{
if (s1 != s2) {
if ((unsigned long) s1 < (unsigned long) s2) {
struct semaphore *tmp = s2;
s2 = s1; s1 = tmp;
}
down(s1);
}
down(s2);
}
/*
* Ewwwwwwww... _triple_ lock. We are guaranteed that the 3rd argument is
* not equal to 1st and not equal to 2nd - the first case (target is parent of
* source) would be already caught, the second is plain impossible (target is
* its own parent and that case would be caught even earlier). Very messy.
* I _think_ that it works, but no warranties - please, look it through.
* Pox on bloody lusers who mandated overwriting rename() for directories...
*/
static inline void triple_down(struct semaphore *s1,
struct semaphore *s2,
struct semaphore *s3)
{
if (s1 != s2) {
if ((unsigned long) s1 < (unsigned long) s2) {
if ((unsigned long) s1 < (unsigned long) s3) {
struct semaphore *tmp = s3;
s3 = s1; s1 = tmp;
}
if ((unsigned long) s1 < (unsigned long) s2) {
struct semaphore *tmp = s2;
s2 = s1; s1 = tmp;
}
} else {
if ((unsigned long) s1 < (unsigned long) s3) {
struct semaphore *tmp = s3;
s3 = s1; s1 = tmp;
}
if ((unsigned long) s2 < (unsigned long) s3) {
struct semaphore *tmp = s3;
s3 = s2; s2 = tmp;
}
}
down(s1);
} else if ((unsigned long) s2 < (unsigned long) s3) {
struct semaphore *tmp = s3;
s3 = s2; s2 = tmp;
}
down(s2);
down(s3);
}
static inline void double_up(struct semaphore *s1, struct semaphore *s2)
{
up(s1);
if (s1 != s2)
up(s2);
}
static inline void triple_up(struct semaphore *s1,
struct semaphore *s2,
struct semaphore *s3)
{
up(s1);
if (s1 != s2)
up(s2);
up(s3);
}
static inline void double_lock(struct dentry *d1, struct dentry *d2)
{
double_down(&d1->d_inode->i_sem, &d2->d_inode->i_sem);
}
static inline void double_unlock(struct dentry *d1, struct dentry *d2)
{
double_up(&d1->d_inode->i_sem,&d2->d_inode->i_sem);
dput(d1);
dput(d2);
}
#endif /* __KERNEL__ */
#endif /* _LINUX_FS_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -