|
@@ -695,12 +695,16 @@ static inline void mangle(struct seq_file *m, const char *s)
|
|
*/
|
|
*/
|
|
int generic_show_options(struct seq_file *m, struct vfsmount *mnt)
|
|
int generic_show_options(struct seq_file *m, struct vfsmount *mnt)
|
|
{
|
|
{
|
|
- const char *options = mnt->mnt_sb->s_options;
|
|
|
|
|
|
+ const char *options;
|
|
|
|
+
|
|
|
|
+ rcu_read_lock();
|
|
|
|
+ options = rcu_dereference(mnt->mnt_sb->s_options);
|
|
|
|
|
|
if (options != NULL && options[0]) {
|
|
if (options != NULL && options[0]) {
|
|
seq_putc(m, ',');
|
|
seq_putc(m, ',');
|
|
mangle(m, options);
|
|
mangle(m, options);
|
|
}
|
|
}
|
|
|
|
+ rcu_read_unlock();
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -721,11 +725,22 @@ EXPORT_SYMBOL(generic_show_options);
|
|
*/
|
|
*/
|
|
void save_mount_options(struct super_block *sb, char *options)
|
|
void save_mount_options(struct super_block *sb, char *options)
|
|
{
|
|
{
|
|
- kfree(sb->s_options);
|
|
|
|
- sb->s_options = kstrdup(options, GFP_KERNEL);
|
|
|
|
|
|
+ BUG_ON(sb->s_options);
|
|
|
|
+ rcu_assign_pointer(sb->s_options, kstrdup(options, GFP_KERNEL));
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(save_mount_options);
|
|
EXPORT_SYMBOL(save_mount_options);
|
|
|
|
|
|
|
|
+void replace_mount_options(struct super_block *sb, char *options)
|
|
|
|
+{
|
|
|
|
+ char *old = sb->s_options;
|
|
|
|
+ rcu_assign_pointer(sb->s_options, options);
|
|
|
|
+ if (old) {
|
|
|
|
+ synchronize_rcu();
|
|
|
|
+ kfree(old);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(replace_mount_options);
|
|
|
|
+
|
|
#ifdef CONFIG_PROC_FS
|
|
#ifdef CONFIG_PROC_FS
|
|
/* iterator */
|
|
/* iterator */
|
|
static void *m_start(struct seq_file *m, loff_t *pos)
|
|
static void *m_start(struct seq_file *m, loff_t *pos)
|