]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/linux/fs.h
[PATCH] r/o bind mounts: debugging for missed calls
[linux-2.6-omap-h63xx.git] / include / linux / fs.h
index 013b9c2b88e6b6069a8332091af94c39f7246227..d1eeea669d2c7c1fc4b8f9d4d13bad2a90e3dab8 100644 (file)
@@ -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