|
@@ -80,6 +80,60 @@ struct vfsmount *alloc_vfsmnt(const char *name)
|
|
|
return mnt;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Most r/o checks on a fs are for operations that take
|
|
|
+ * discrete amounts of time, like a write() or unlink().
|
|
|
+ * We must keep track of when those operations start
|
|
|
+ * (for permission checks) and when they end, so that
|
|
|
+ * we can determine when writes are able to occur to
|
|
|
+ * a filesystem.
|
|
|
+ */
|
|
|
+/**
|
|
|
+ * mnt_want_write - get write access to a mount
|
|
|
+ * @mnt: the mount on which to take a write
|
|
|
+ *
|
|
|
+ * This tells the low-level filesystem that a write is
|
|
|
+ * about to be performed to it, and makes sure that
|
|
|
+ * writes are allowed before returning success. When
|
|
|
+ * the write operation is finished, mnt_drop_write()
|
|
|
+ * must be called. This is effectively a refcount.
|
|
|
+ */
|
|
|
+int mnt_want_write(struct vfsmount *mnt)
|
|
|
+{
|
|
|
+ if (__mnt_is_readonly(mnt))
|
|
|
+ return -EROFS;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(mnt_want_write);
|
|
|
+
|
|
|
+/**
|
|
|
+ * mnt_drop_write - give up write access to a mount
|
|
|
+ * @mnt: the mount on which to give up write access
|
|
|
+ *
|
|
|
+ * Tells the low-level filesystem that we are done
|
|
|
+ * performing writes to it. Must be matched with
|
|
|
+ * mnt_want_write() call above.
|
|
|
+ */
|
|
|
+void mnt_drop_write(struct vfsmount *mnt)
|
|
|
+{
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(mnt_drop_write);
|
|
|
+
|
|
|
+/*
|
|
|
+ * __mnt_is_readonly: check whether a mount is read-only
|
|
|
+ * @mnt: the mount to check for its write status
|
|
|
+ *
|
|
|
+ * This shouldn't be used directly ouside of the VFS.
|
|
|
+ * It does not guarantee that the filesystem will stay
|
|
|
+ * r/w, just that it is right *now*. This can not and
|
|
|
+ * should not be used in place of IS_RDONLY(inode).
|
|
|
+ */
|
|
|
+int __mnt_is_readonly(struct vfsmount *mnt)
|
|
|
+{
|
|
|
+ return (mnt->mnt_sb->s_flags & MS_RDONLY);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(__mnt_is_readonly);
|
|
|
+
|
|
|
int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb)
|
|
|
{
|
|
|
mnt->mnt_sb = sb;
|