diff options
Diffstat (limited to 'include/linux/fs.h')
| -rw-r--r-- | include/linux/fs.h | 88 | 
1 files changed, 61 insertions, 27 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index 277f497923a..0c4df261af7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -58,14 +58,15 @@ struct inodes_stat_t {  #define NR_FILE  8192	/* this can well be larger on a larger system */ -#define MAY_EXEC 1 -#define MAY_WRITE 2 -#define MAY_READ 4 -#define MAY_APPEND 8 -#define MAY_ACCESS 16 -#define MAY_OPEN 32 -#define MAY_CHDIR 64 -#define MAY_NOT_BLOCK 128	/* called from RCU mode, don't block */ +#define MAY_EXEC		0x00000001 +#define MAY_WRITE		0x00000002 +#define MAY_READ		0x00000004 +#define MAY_APPEND		0x00000008 +#define MAY_ACCESS		0x00000010 +#define MAY_OPEN		0x00000020 +#define MAY_CHDIR		0x00000040 +/* called from RCU mode, don't block */ +#define MAY_NOT_BLOCK		0x00000080  /*   * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond @@ -767,14 +768,25 @@ struct inode {  	/* Stat data, not accessed from path walking */  	unsigned long		i_ino; -	unsigned int		i_nlink; +	/* +	 * Filesystems may only read i_nlink directly.  They shall use the +	 * following functions for modification: +	 * +	 *    (set|clear|inc|drop)_nlink +	 *    inode_(inc|dec)_link_count +	 */ +	union { +		const unsigned int i_nlink; +		unsigned int __i_nlink; +	};  	dev_t			i_rdev; -	loff_t			i_size;  	struct timespec		i_atime;  	struct timespec		i_mtime;  	struct timespec		i_ctime; -	unsigned int		i_blkbits; +	spinlock_t		i_lock;	/* i_blocks, i_bytes, maybe i_size */ +	unsigned short          i_bytes;  	blkcnt_t		i_blocks; +	loff_t			i_size;  #ifdef __NEED_I_SIZE_ORDERED  	seqcount_t		i_size_seqcount; @@ -782,7 +794,6 @@ struct inode {  	/* Misc */  	unsigned long		i_state; -	spinlock_t		i_lock;	/* i_blocks, i_bytes, maybe i_size */  	struct mutex		i_mutex;  	unsigned long		dirtied_when;	/* jiffies of first dirtying */ @@ -796,9 +807,10 @@ struct inode {  		struct rcu_head		i_rcu;  	};  	atomic_t		i_count; +	unsigned int		i_blkbits;  	u64			i_version; -	unsigned short          i_bytes;  	atomic_t		i_dio_count; +	atomic_t		i_writecount;  	const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */  	struct file_lock	*i_flock;  	struct address_space	i_data; @@ -822,7 +834,6 @@ struct inode {  #ifdef CONFIG_IMA  	atomic_t		i_readcount; /* struct files open RO */  #endif -	atomic_t		i_writecount;  	void			*i_private; /* fs or device private pointer */  }; @@ -963,7 +974,12 @@ struct file {  #define f_dentry	f_path.dentry  #define f_vfsmnt	f_path.mnt  	const struct file_operations	*f_op; -	spinlock_t		f_lock;  /* f_ep_links, f_flags, no IRQ */ + +	/* +	 * Protects f_ep_links, f_flags, f_pos vs i_size in lseek SEEK_CUR. +	 * Must not be taken from IRQ context. +	 */ +	spinlock_t		f_lock;  #ifdef CONFIG_SMP  	int			f_sb_list_cpu;  #endif @@ -1063,6 +1079,8 @@ static inline int file_check_writeable(struct file *filp)  #define FL_LEASE	32	/* lease held on this file */  #define FL_CLOSE	64	/* unlock on close */  #define FL_SLEEP	128	/* A blocking lock */ +#define FL_DOWNGRADE_PENDING	256 /* Lease is being downgraded */ +#define FL_UNLOCK_PENDING	512 /* Lease is being broken */  /*   * Special return value from posix_lock_file() and vfs_lock_file() for @@ -1109,7 +1127,7 @@ struct file_lock {  	struct list_head fl_link;	/* doubly linked list of all locks */  	struct list_head fl_block;	/* circular list of blocked processes */  	fl_owner_t fl_owner; -	unsigned char fl_flags; +	unsigned int fl_flags;  	unsigned char fl_type;  	unsigned int fl_pid;  	struct pid *fl_nspid; @@ -1119,7 +1137,9 @@ struct file_lock {  	loff_t fl_end;  	struct fasync_struct *	fl_fasync; /* for lease break notifications */ -	unsigned long fl_break_time;	/* for nonblocking lease breaks */ +	/* for lease breaks: */ +	unsigned long fl_break_time; +	unsigned long fl_downgrade_time;  	const struct file_lock_operations *fl_ops;	/* Callbacks for filesystems */  	const struct lock_manager_operations *fl_lmops;	/* Callbacks for lockmanagers */ @@ -1623,9 +1643,10 @@ struct inode_operations {  struct seq_file;  ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, -				unsigned long nr_segs, unsigned long fast_segs, -				struct iovec *fast_pointer, -				struct iovec **ret_pointer); +			      unsigned long nr_segs, unsigned long fast_segs, +			      struct iovec *fast_pointer, +			      struct iovec **ret_pointer, +			      int check_access);  extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);  extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); @@ -1744,6 +1765,19 @@ static inline void mark_inode_dirty_sync(struct inode *inode)  }  /** + * set_nlink - directly set an inode's link count + * @inode: inode + * @nlink: new nlink (should be non-zero) + * + * This is a low-level filesystem helper to replace any + * direct filesystem manipulation of i_nlink. + */ +static inline void set_nlink(struct inode *inode, unsigned int nlink) +{ +	inode->__i_nlink = nlink; +} + +/**   * inc_nlink - directly increment an inode's link count   * @inode: inode   * @@ -1753,7 +1787,7 @@ static inline void mark_inode_dirty_sync(struct inode *inode)   */  static inline void inc_nlink(struct inode *inode)  { -	inode->i_nlink++; +	inode->__i_nlink++;  }  static inline void inode_inc_link_count(struct inode *inode) @@ -1775,7 +1809,7 @@ static inline void inode_inc_link_count(struct inode *inode)   */  static inline void drop_nlink(struct inode *inode)  { -	inode->i_nlink--; +	inode->__i_nlink--;  }  /** @@ -1788,7 +1822,7 @@ static inline void drop_nlink(struct inode *inode)   */  static inline void clear_nlink(struct inode *inode)  { -	inode->i_nlink = 0; +	inode->__i_nlink = 0;  }  static inline void inode_dec_link_count(struct inode *inode) @@ -2397,8 +2431,8 @@ file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);  extern loff_t noop_llseek(struct file *file, loff_t offset, int origin);  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 loff_t generic_file_llseek_unlocked(struct file *file, loff_t offset, -			int origin); +extern loff_t generic_file_llseek_size(struct file *file, loff_t offset, +		int origin, loff_t maxsize);  extern int generic_file_open(struct inode * inode, struct file * filp);  extern int nonseekable_open(struct inode * inode, struct file * filp); @@ -2624,8 +2658,8 @@ static const struct file_operations __fops = {				\  	.llseek	 = generic_file_llseek,					\  }; -static inline void __attribute__((format(printf, 1, 2))) -__simple_attr_check_format(const char *fmt, ...) +static inline __printf(1, 2) +void __simple_attr_check_format(const char *fmt, ...)  {  	/* don't do anything, just let the compiler check the arguments; */  }  |