FunctionFS: enable multiple functions
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Acked-by: Michal Nazarewicz <mina86@mina86.com> Cc: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
304f0b2453
commit
581791f5c7
@@ -1031,6 +1031,12 @@ struct ffs_sb_fill_data {
|
||||
struct ffs_file_perms perms;
|
||||
umode_t root_mode;
|
||||
const char *dev_name;
|
||||
union {
|
||||
/* set by ffs_fs_mount(), read by ffs_sb_fill() */
|
||||
void *private_data;
|
||||
/* set by ffs_sb_fill(), read by ffs_fs_mount */
|
||||
struct ffs_data *ffs_data;
|
||||
};
|
||||
};
|
||||
|
||||
static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
|
||||
@@ -1047,8 +1053,14 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
|
||||
goto Enomem;
|
||||
|
||||
ffs->sb = sb;
|
||||
ffs->dev_name = data->dev_name;
|
||||
ffs->dev_name = kstrdup(data->dev_name, GFP_KERNEL);
|
||||
if (unlikely(!ffs->dev_name))
|
||||
goto Enomem;
|
||||
ffs->file_perms = data->perms;
|
||||
ffs->private_data = data->private_data;
|
||||
|
||||
/* used by the caller of this function */
|
||||
data->ffs_data = ffs;
|
||||
|
||||
sb->s_fs_info = ffs;
|
||||
sb->s_blocksize = PAGE_CACHE_SIZE;
|
||||
@@ -1167,20 +1179,29 @@ ffs_fs_mount(struct file_system_type *t, int flags,
|
||||
},
|
||||
.root_mode = S_IFDIR | 0500,
|
||||
};
|
||||
struct dentry *rv;
|
||||
int ret;
|
||||
void *ffs_dev;
|
||||
|
||||
ENTER();
|
||||
|
||||
ret = functionfs_check_dev_callback(dev_name);
|
||||
if (unlikely(ret < 0))
|
||||
return ERR_PTR(ret);
|
||||
|
||||
ret = ffs_fs_parse_opts(&data, opts);
|
||||
if (unlikely(ret < 0))
|
||||
return ERR_PTR(ret);
|
||||
|
||||
ffs_dev = functionfs_acquire_dev_callback(dev_name);
|
||||
if (IS_ERR(ffs_dev))
|
||||
return ffs_dev;
|
||||
|
||||
data.dev_name = dev_name;
|
||||
return mount_single(t, flags, &data, ffs_sb_fill);
|
||||
data.private_data = ffs_dev;
|
||||
rv = mount_nodev(t, flags, &data, ffs_sb_fill);
|
||||
|
||||
/* data.ffs_data is set by ffs_sb_fill */
|
||||
if (IS_ERR(rv))
|
||||
functionfs_release_dev_callback(data.ffs_data);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1189,8 +1210,10 @@ ffs_fs_kill_sb(struct super_block *sb)
|
||||
ENTER();
|
||||
|
||||
kill_litter_super(sb);
|
||||
if (sb->s_fs_info)
|
||||
if (sb->s_fs_info) {
|
||||
functionfs_release_dev_callback(sb->s_fs_info);
|
||||
ffs_data_put(sb->s_fs_info);
|
||||
}
|
||||
}
|
||||
|
||||
static struct file_system_type ffs_fs_type = {
|
||||
@@ -1256,6 +1279,7 @@ static void ffs_data_put(struct ffs_data *ffs)
|
||||
ffs_data_clear(ffs);
|
||||
BUG_ON(waitqueue_active(&ffs->ev.waitq) ||
|
||||
waitqueue_active(&ffs->ep0req_completion.wait));
|
||||
kfree(ffs->dev_name);
|
||||
kfree(ffs);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user