📄 fs.h
字号:
extern int check_disk_change(kdev_t);extern int invalidate_inodes(struct super_block *);extern int invalidate_device(kdev_t, int);extern void invalidate_inode_pages(struct inode *);extern void invalidate_inode_pages2(struct address_space *);extern void invalidate_inode_buffers(struct inode *);#define invalidate_buffers(dev) __invalidate_buffers((dev), 0)#define destroy_buffers(dev) __invalidate_buffers((dev), 1)extern void invalidate_bdev(struct block_device *, int);extern void __invalidate_buffers(kdev_t dev, int);extern void sync_inodes(kdev_t);extern void sync_unlocked_inodes(void);extern void write_inode_now(struct inode *, int);extern int sync_buffers(kdev_t, int);extern void sync_dev(kdev_t);extern int fsync_dev(kdev_t);extern int fsync_super(struct super_block *);extern int fsync_no_super(kdev_t);extern void sync_inodes_sb(struct super_block *);extern int fsync_buffers_list(struct list_head *);static inline int fsync_inode_buffers(struct inode *inode){ return fsync_buffers_list(&inode->i_dirty_buffers);}static inline int fsync_inode_data_buffers(struct inode *inode){ return fsync_buffers_list(&inode->i_dirty_data_buffers);}extern int inode_has_buffers(struct inode *);extern int filemap_fdatasync(struct address_space *);extern int filemap_fdatawait(struct address_space *);extern void sync_supers(kdev_t dev, int wait);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 FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));extern int FASTCALL(path_walk(const char *, struct nameidata *));extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));extern int FASTCALL(link_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_len(const char *, struct dentry *, int);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 struct inode * ilookup(struct super_block *, unsigned long);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 struct inode * icreate(struct super_block *, unsigned long, int);extern void unlock_new_inode(struct inode *);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; inode->i_blkbits = sb->s_blocksize_bits; } return inode;}extern void remove_suid(struct inode *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 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 int set_blocksize(kdev_t, int);extern int sb_set_blocksize(struct super_block *, int);extern int sb_min_blocksize(struct super_block *, int);extern struct buffer_head * bread(kdev_t, int, int);static inline struct buffer_head * sb_bread(struct super_block *sb, int block){ return bread(sb->s_dev, block, sb->s_blocksize);}static inline struct buffer_head * sb_getblk(struct super_block *sb, int block){ return getblk(sb->s_dev, block, sb->s_blocksize);}static inline struct buffer_head * sb_get_hash_table(struct super_block *sb, int block){ return get_hash_table(sb->s_dev, block, sb->s_blocksize);}extern void wakeup_bdflush(void);extern void put_unused_buffer_head(struct buffer_head * bh);extern struct buffer_head * get_unused_buffer_head(int async);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 try_to_release_page(struct page * page, int gfp_mask);extern int discard_bh_page(struct page *, unsigned long, int);#define block_flushpage(page, offset) discard_bh_page(page, offset, 1)#define block_invalidate_page(page) discard_bh_page(page, 0, 0)extern void create_empty_buffers(struct page *, kdev_t, 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 generic_cont_expand(struct inode *inode, loff_t size) ;extern int block_commit_write(struct page *page, unsigned from, unsigned to);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_direct_IO(int, struct inode *, struct kiobuf *, unsigned long, int, get_block_t *);extern int waitfor_one_page(struct page *);extern int writeout_one_page(struct page *);extern int generic_file_mmap(struct file *, struct vm_area_struct *);extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);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 loff_t no_llseek(struct file *file, loff_t offset, int origin);extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);extern ssize_t generic_read_dir(struct file *, char *, size_t, loff_t *);extern int generic_file_open(struct inode * inode, struct file * filp);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_dir_open(struct inode *, struct file *);extern int dcache_dir_close(struct inode *, struct file *);extern loff_t dcache_dir_lseek(struct file *, loff_t, int);extern int dcache_dir_fsync(struct file *, struct dentry *, int);extern int dcache_readdir(struct file *, void *, filldir_t);extern struct file_operations dcache_dir_ops;extern struct file_system_type *get_fs_type(const char *name);extern struct super_block *get_super(kdev_t);extern void drop_super(struct super_block *sb);static inline int is_mounted(kdev_t dev){ struct super_block *sb = get_super(dev); if (sb) { drop_super(sb); return 1; } return 0;}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);#ifdef CONFIG_BLK_DEV_INITRDextern unsigned int real_root_dev;#endifextern 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);#define OSYNC_METADATA (1<<0)#define OSYNC_DATA (1<<1)#define OSYNC_INODE (1<<2)extern int inode_change_ok(struct inode *, struct iattr *);extern int 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 + -