summaryrefslogtreecommitdiff
path: root/include/linux/fs.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/fs.h')
-rw-r--r--include/linux/fs.h88
1 files changed, 61 insertions, 27 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 277f497..0c4df26 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; */
}