aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-21 18:38:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-21 18:38:14 -0400
commitfd9be4ce2e1eb407a8152f823698cc0d652bbec8 (patch)
treeb1cc279fa5b1f90995253f007564f001aa20c743 /include
parentb1af9ccce9cff5b48c37424dbdbb3aa9021915db (diff)
parentad775f5a8faa5845377f093ca11caf577404add9 (diff)
Merge branch 'ro-bind.b6' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'ro-bind.b6' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (24 commits) [PATCH] r/o bind mounts: debugging for missed calls [PATCH] r/o bind mounts: honor mount writer counts at remount [PATCH] r/o bind mounts: track numbers of writers to mounts [PATCH] r/o bind mounts: check mnt instead of superblock directly [PATCH] r/o bind mounts: elevate count for xfs timestamp updates [PATCH] r/o bind mounts: make access() use new r/o helper [PATCH] r/o bind mounts: write counts for truncate() [PATCH] r/o bind mounts: elevate write count for chmod/chown callers [PATCH] r/o bind mounts: elevate write count for open()s [PATCH] r/o bind mounts: elevate write count for ioctls() [PATCH] r/o bind mounts: write count for file_update_time() [PATCH] r/o bind mounts: elevate write count for do_utimes() [PATCH] r/o bind mounts: write counts for touch_atime() [PATCH] r/o bind mounts: elevate write count for ncp_ioctl() [PATCH] r/o bind mounts: elevate write count for xattr_permission() callers [PATCH] r/o bind mounts: get write access for vfs_rename() callers [PATCH] r/o bind mounts: write counts for link/symlink [PATCH] r/o bind mounts: get callers of vfs_mknod/create/mkdir() [PATCH] r/o bind mounts: elevate write count for rmdir and unlink. [PATCH] r/o bind mounts: drop write during emergency remount ...
Diffstat (limited to 'include')
-rw-r--r--include/linux/file.h1
-rw-r--r--include/linux/fs.h52
-rw-r--r--include/linux/mount.h11
3 files changed, 63 insertions, 1 deletions
diff --git a/include/linux/file.h b/include/linux/file.h
index 7239baac81a9..653477021e4c 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -61,6 +61,7 @@ extern struct kmem_cache *filp_cachep;
61 61
62extern void __fput(struct file *); 62extern void __fput(struct file *);
63extern void fput(struct file *); 63extern void fput(struct file *);
64extern void drop_file_write_access(struct file *file);
64 65
65struct file_operations; 66struct file_operations;
66struct vfsmount; 67struct vfsmount;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b84b848431f2..d1eeea669d2c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -776,6 +776,9 @@ static inline int ra_has_index(struct file_ra_state *ra, pgoff_t index)
776 index < ra->start + ra->size); 776 index < ra->start + ra->size);
777} 777}
778 778
779#define FILE_MNT_WRITE_TAKEN 1
780#define FILE_MNT_WRITE_RELEASED 2
781
779struct file { 782struct file {
780 /* 783 /*
781 * fu_list becomes invalid after file_free is called and queued via 784 * fu_list becomes invalid after file_free is called and queued via
@@ -810,6 +813,9 @@ struct file {
810 spinlock_t f_ep_lock; 813 spinlock_t f_ep_lock;
811#endif /* #ifdef CONFIG_EPOLL */ 814#endif /* #ifdef CONFIG_EPOLL */
812 struct address_space *f_mapping; 815 struct address_space *f_mapping;
816#ifdef CONFIG_DEBUG_WRITECOUNT
817 unsigned long f_mnt_write_state;
818#endif
813}; 819};
814extern spinlock_t files_lock; 820extern spinlock_t files_lock;
815#define file_list_lock() spin_lock(&files_lock); 821#define file_list_lock() spin_lock(&files_lock);
@@ -818,6 +824,49 @@ extern spinlock_t files_lock;
818#define get_file(x) atomic_inc(&(x)->f_count) 824#define get_file(x) atomic_inc(&(x)->f_count)
819#define file_count(x) atomic_read(&(x)->f_count) 825#define file_count(x) atomic_read(&(x)->f_count)
820 826
827#ifdef CONFIG_DEBUG_WRITECOUNT
828static inline void file_take_write(struct file *f)
829{
830 WARN_ON(f->f_mnt_write_state != 0);
831 f->f_mnt_write_state = FILE_MNT_WRITE_TAKEN;
832}
833static inline void file_release_write(struct file *f)
834{
835 f->f_mnt_write_state |= FILE_MNT_WRITE_RELEASED;
836}
837static inline void file_reset_write(struct file *f)
838{
839 f->f_mnt_write_state = 0;
840}
841static inline void file_check_state(struct file *f)
842{
843 /*
844 * At this point, either both or neither of these bits
845 * should be set.
846 */
847 WARN_ON(f->f_mnt_write_state == FILE_MNT_WRITE_TAKEN);
848 WARN_ON(f->f_mnt_write_state == FILE_MNT_WRITE_RELEASED);
849}
850static inline int file_check_writeable(struct file *f)
851{
852 if (f->f_mnt_write_state == FILE_MNT_WRITE_TAKEN)
853 return 0;
854 printk(KERN_WARNING "writeable file with no "
855 "mnt_want_write()\n");
856 WARN_ON(1);
857 return -EINVAL;
858}
859#else /* !CONFIG_DEBUG_WRITECOUNT */
860static inline void file_take_write(struct file *filp) {}
861static inline void file_release_write(struct file *filp) {}
862static inline void file_reset_write(struct file *filp) {}
863static inline void file_check_state(struct file *filp) {}
864static inline int file_check_writeable(struct file *filp)
865{
866 return 0;
867}
868#endif /* CONFIG_DEBUG_WRITECOUNT */
869
821#define MAX_NON_LFS ((1UL<<31) - 1) 870#define MAX_NON_LFS ((1UL<<31) - 1)
822 871
823/* Page cache limit. The filesystems should put that into their s_maxbytes 872/* Page cache limit. The filesystems should put that into their s_maxbytes
@@ -1735,7 +1784,8 @@ extern struct file *create_read_pipe(struct file *f);
1735extern struct file *create_write_pipe(void); 1784extern struct file *create_write_pipe(void);
1736extern void free_write_pipe(struct file *); 1785extern void free_write_pipe(struct file *);
1737 1786
1738extern int open_namei(int dfd, const char *, int, int, struct nameidata *); 1787extern struct file *do_filp_open(int dfd, const char *pathname,
1788 int open_flag, int mode);
1739extern int may_open(struct nameidata *, int, int); 1789extern int may_open(struct nameidata *, int, int);
1740 1790
1741extern int kernel_read(struct file *, unsigned long, char *, unsigned long); 1791extern int kernel_read(struct file *, unsigned long, char *, unsigned long);
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 5ee2df217cdf..d6600e3f7e45 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -14,6 +14,7 @@
14 14
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/list.h> 16#include <linux/list.h>
17#include <linux/nodemask.h>
17#include <linux/spinlock.h> 18#include <linux/spinlock.h>
18#include <asm/atomic.h> 19#include <asm/atomic.h>
19 20
@@ -28,8 +29,10 @@ struct mnt_namespace;
28#define MNT_NOATIME 0x08 29#define MNT_NOATIME 0x08
29#define MNT_NODIRATIME 0x10 30#define MNT_NODIRATIME 0x10
30#define MNT_RELATIME 0x20 31#define MNT_RELATIME 0x20
32#define MNT_READONLY 0x40 /* does the user want this to be r/o? */
31 33
32#define MNT_SHRINKABLE 0x100 34#define MNT_SHRINKABLE 0x100
35#define MNT_IMBALANCED_WRITE_COUNT 0x200 /* just for debugging */
33 36
34#define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */ 37#define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */
35#define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */ 38#define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */
@@ -62,6 +65,11 @@ struct vfsmount {
62 int mnt_expiry_mark; /* true if marked for expiry */ 65 int mnt_expiry_mark; /* true if marked for expiry */
63 int mnt_pinned; 66 int mnt_pinned;
64 int mnt_ghosts; 67 int mnt_ghosts;
68 /*
69 * This value is not stable unless all of the mnt_writers[] spinlocks
70 * are held, and all mnt_writer[]s on this mount have 0 as their ->count
71 */
72 atomic_t __mnt_writers;
65}; 73};
66 74
67static inline struct vfsmount *mntget(struct vfsmount *mnt) 75static inline struct vfsmount *mntget(struct vfsmount *mnt)
@@ -71,9 +79,12 @@ static inline struct vfsmount *mntget(struct vfsmount *mnt)
71 return mnt; 79 return mnt;
72} 80}
73 81
82extern int mnt_want_write(struct vfsmount *mnt);
83extern void mnt_drop_write(struct vfsmount *mnt);
74extern void mntput_no_expire(struct vfsmount *mnt); 84extern void mntput_no_expire(struct vfsmount *mnt);
75extern void mnt_pin(struct vfsmount *mnt); 85extern void mnt_pin(struct vfsmount *mnt);
76extern void mnt_unpin(struct vfsmount *mnt); 86extern void mnt_unpin(struct vfsmount *mnt);
87extern int __mnt_is_readonly(struct vfsmount *mnt);
77 88
78static inline void mntput(struct vfsmount *mnt) 89static inline void mntput(struct vfsmount *mnt)
79{ 90{