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:
Andrzej Pietrasiewicz
2012-05-14 15:51:52 +02:00
committed by Greg Kroah-Hartman
parent 304f0b2453
commit 581791f5c7
4 changed files with 279 additions and 34 deletions

View File

@@ -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);
}
}