aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/namespace.c54
-rw-r--r--include/linux/mount.h3
2 files changed, 57 insertions, 0 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 94f026ec990a..066b393578c1 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -80,6 +80,60 @@ struct vfsmount *alloc_vfsmnt(const char *name)
80 return mnt; 80 return mnt;
81} 81}
82 82
83/*
84 * Most r/o checks on a fs are for operations that take
85 * discrete amounts of time, like a write() or unlink().
86 * We must keep track of when those operations start
87 * (for permission checks) and when they end, so that
88 * we can determine when writes are able to occur to
89 * a filesystem.
90 */
91/**
92 * mnt_want_write - get write access to a mount
93 * @mnt: the mount on which to take a write
94 *
95 * This tells the low-level filesystem that a write is
96 * about to be performed to it, and makes sure that
97 * writes are allowed before returning success. When
98 * the write operation is finished, mnt_drop_write()
99 * must be called. This is effectively a refcount.
100 */
101int mnt_want_write(struct vfsmount *mnt)
102{
103 if (__mnt_is_readonly(mnt))
104 return -EROFS;
105 return 0;
106}
107EXPORT_SYMBOL_GPL(mnt_want_write);
108
109/**
110 * mnt_drop_write - give up write access to a mount
111 * @mnt: the mount on which to give up write access
112 *
113 * Tells the low-level filesystem that we are done
114 * performing writes to it. Must be matched with
115 * mnt_want_write() call above.
116 */
117void mnt_drop_write(struct vfsmount *mnt)
118{
119}
120EXPORT_SYMBOL_GPL(mnt_drop_write);
121
122/*
123 * __mnt_is_readonly: check whether a mount is read-only
124 * @mnt: the mount to check for its write status
125 *
126 * This shouldn't be used directly ouside of the VFS.
127 * It does not guarantee that the filesystem will stay
128 * r/w, just that it is right *now*. This can not and
129 * should not be used in place of IS_RDONLY(inode).
130 */
131int __mnt_is_readonly(struct vfsmount *mnt)
132{
133 return (mnt->mnt_sb->s_flags & MS_RDONLY);
134}
135EXPORT_SYMBOL_GPL(__mnt_is_readonly);
136
83int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb) 137int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb)
84{ 138{
85 mnt->mnt_sb = sb; 139 mnt->mnt_sb = sb;
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 5ee2df217cdf..2eecd2c8c760 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -71,9 +71,12 @@ static inline struct vfsmount *mntget(struct vfsmount *mnt)
71 return mnt; 71 return mnt;
72} 72}
73 73
74extern int mnt_want_write(struct vfsmount *mnt);
75extern void mnt_drop_write(struct vfsmount *mnt);
74extern void mntput_no_expire(struct vfsmount *mnt); 76extern void mntput_no_expire(struct vfsmount *mnt);
75extern void mnt_pin(struct vfsmount *mnt); 77extern void mnt_pin(struct vfsmount *mnt);
76extern void mnt_unpin(struct vfsmount *mnt); 78extern void mnt_unpin(struct vfsmount *mnt);
79extern int __mnt_is_readonly(struct vfsmount *mnt);
77 80
78static inline void mntput(struct vfsmount *mnt) 81static inline void mntput(struct vfsmount *mnt)
79{ 82{