|
@@ -776,6 +776,9 @@ static inline int ra_has_index(struct file_ra_state *ra, pgoff_t index)
|
|
|
index < ra->start + ra->size);
|
|
|
}
|
|
|
|
|
|
+#define FILE_MNT_WRITE_TAKEN 1
|
|
|
+#define FILE_MNT_WRITE_RELEASED 2
|
|
|
+
|
|
|
struct file {
|
|
|
/*
|
|
|
* fu_list becomes invalid after file_free is called and queued via
|
|
@@ -810,6 +813,9 @@ struct file {
|
|
|
spinlock_t f_ep_lock;
|
|
|
#endif /* #ifdef CONFIG_EPOLL */
|
|
|
struct address_space *f_mapping;
|
|
|
+#ifdef CONFIG_DEBUG_WRITECOUNT
|
|
|
+ unsigned long f_mnt_write_state;
|
|
|
+#endif
|
|
|
};
|
|
|
extern spinlock_t files_lock;
|
|
|
#define file_list_lock() spin_lock(&files_lock);
|
|
@@ -818,6 +824,49 @@ extern spinlock_t files_lock;
|
|
|
#define get_file(x) atomic_inc(&(x)->f_count)
|
|
|
#define file_count(x) atomic_read(&(x)->f_count)
|
|
|
|
|
|
+#ifdef CONFIG_DEBUG_WRITECOUNT
|
|
|
+static inline void file_take_write(struct file *f)
|
|
|
+{
|
|
|
+ WARN_ON(f->f_mnt_write_state != 0);
|
|
|
+ f->f_mnt_write_state = FILE_MNT_WRITE_TAKEN;
|
|
|
+}
|
|
|
+static inline void file_release_write(struct file *f)
|
|
|
+{
|
|
|
+ f->f_mnt_write_state |= FILE_MNT_WRITE_RELEASED;
|
|
|
+}
|
|
|
+static inline void file_reset_write(struct file *f)
|
|
|
+{
|
|
|
+ f->f_mnt_write_state = 0;
|
|
|
+}
|
|
|
+static inline void file_check_state(struct file *f)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * At this point, either both or neither of these bits
|
|
|
+ * should be set.
|
|
|
+ */
|
|
|
+ WARN_ON(f->f_mnt_write_state == FILE_MNT_WRITE_TAKEN);
|
|
|
+ WARN_ON(f->f_mnt_write_state == FILE_MNT_WRITE_RELEASED);
|
|
|
+}
|
|
|
+static inline int file_check_writeable(struct file *f)
|
|
|
+{
|
|
|
+ if (f->f_mnt_write_state == FILE_MNT_WRITE_TAKEN)
|
|
|
+ return 0;
|
|
|
+ printk(KERN_WARNING "writeable file with no "
|
|
|
+ "mnt_want_write()\n");
|
|
|
+ WARN_ON(1);
|
|
|
+ return -EINVAL;
|
|
|
+}
|
|
|
+#else /* !CONFIG_DEBUG_WRITECOUNT */
|
|
|
+static inline void file_take_write(struct file *filp) {}
|
|
|
+static inline void file_release_write(struct file *filp) {}
|
|
|
+static inline void file_reset_write(struct file *filp) {}
|
|
|
+static inline void file_check_state(struct file *filp) {}
|
|
|
+static inline int file_check_writeable(struct file *filp)
|
|
|
+{
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+#endif /* CONFIG_DEBUG_WRITECOUNT */
|
|
|
+
|
|
|
#define MAX_NON_LFS ((1UL<<31) - 1)
|
|
|
|
|
|
/* Page cache limit. The filesystems should put that into their s_maxbytes
|