diff options
Diffstat (limited to 'drivers/usb/gadget/f_fs.c')
-rw-r--r-- | drivers/usb/gadget/f_fs.c | 60 |
1 files changed, 26 insertions, 34 deletions
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 1a66c5baa0d1..0658908d8968 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -1034,37 +1034,19 @@ struct ffs_sb_fill_data { | |||
1034 | struct ffs_file_perms perms; | 1034 | struct ffs_file_perms perms; |
1035 | umode_t root_mode; | 1035 | umode_t root_mode; |
1036 | const char *dev_name; | 1036 | const char *dev_name; |
1037 | union { | 1037 | struct ffs_data *ffs_data; |
1038 | /* set by ffs_fs_mount(), read by ffs_sb_fill() */ | ||
1039 | void *private_data; | ||
1040 | /* set by ffs_sb_fill(), read by ffs_fs_mount */ | ||
1041 | struct ffs_data *ffs_data; | ||
1042 | }; | ||
1043 | }; | 1038 | }; |
1044 | 1039 | ||
1045 | static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) | 1040 | static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) |
1046 | { | 1041 | { |
1047 | struct ffs_sb_fill_data *data = _data; | 1042 | struct ffs_sb_fill_data *data = _data; |
1048 | struct inode *inode; | 1043 | struct inode *inode; |
1049 | struct ffs_data *ffs; | 1044 | struct ffs_data *ffs = data->ffs_data; |
1050 | 1045 | ||
1051 | ENTER(); | 1046 | ENTER(); |
1052 | 1047 | ||
1053 | /* Initialise data */ | ||
1054 | ffs = ffs_data_new(); | ||
1055 | if (unlikely(!ffs)) | ||
1056 | goto Enomem; | ||
1057 | |||
1058 | ffs->sb = sb; | 1048 | ffs->sb = sb; |
1059 | ffs->dev_name = kstrdup(data->dev_name, GFP_KERNEL); | 1049 | data->ffs_data = NULL; |
1060 | if (unlikely(!ffs->dev_name)) | ||
1061 | goto Enomem; | ||
1062 | ffs->file_perms = data->perms; | ||
1063 | ffs->private_data = data->private_data; | ||
1064 | |||
1065 | /* used by the caller of this function */ | ||
1066 | data->ffs_data = ffs; | ||
1067 | |||
1068 | sb->s_fs_info = ffs; | 1050 | sb->s_fs_info = ffs; |
1069 | sb->s_blocksize = PAGE_CACHE_SIZE; | 1051 | sb->s_blocksize = PAGE_CACHE_SIZE; |
1070 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 1052 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
@@ -1080,17 +1062,14 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) | |||
1080 | &data->perms); | 1062 | &data->perms); |
1081 | sb->s_root = d_make_root(inode); | 1063 | sb->s_root = d_make_root(inode); |
1082 | if (unlikely(!sb->s_root)) | 1064 | if (unlikely(!sb->s_root)) |
1083 | goto Enomem; | 1065 | return -ENOMEM; |
1084 | 1066 | ||
1085 | /* EP0 file */ | 1067 | /* EP0 file */ |
1086 | if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs, | 1068 | if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs, |
1087 | &ffs_ep0_operations, NULL))) | 1069 | &ffs_ep0_operations, NULL))) |
1088 | goto Enomem; | 1070 | return -ENOMEM; |
1089 | 1071 | ||
1090 | return 0; | 1072 | return 0; |
1091 | |||
1092 | Enomem: | ||
1093 | return -ENOMEM; | ||
1094 | } | 1073 | } |
1095 | 1074 | ||
1096 | static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) | 1075 | static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) |
@@ -1193,6 +1172,7 @@ ffs_fs_mount(struct file_system_type *t, int flags, | |||
1193 | struct dentry *rv; | 1172 | struct dentry *rv; |
1194 | int ret; | 1173 | int ret; |
1195 | void *ffs_dev; | 1174 | void *ffs_dev; |
1175 | struct ffs_data *ffs; | ||
1196 | 1176 | ||
1197 | ENTER(); | 1177 | ENTER(); |
1198 | 1178 | ||
@@ -1200,18 +1180,30 @@ ffs_fs_mount(struct file_system_type *t, int flags, | |||
1200 | if (unlikely(ret < 0)) | 1180 | if (unlikely(ret < 0)) |
1201 | return ERR_PTR(ret); | 1181 | return ERR_PTR(ret); |
1202 | 1182 | ||
1183 | ffs = ffs_data_new(); | ||
1184 | if (unlikely(!ffs)) | ||
1185 | return ERR_PTR(-ENOMEM); | ||
1186 | ffs->file_perms = data.perms; | ||
1187 | |||
1188 | ffs->dev_name = kstrdup(dev_name, GFP_KERNEL); | ||
1189 | if (unlikely(!ffs->dev_name)) { | ||
1190 | ffs_data_put(ffs); | ||
1191 | return ERR_PTR(-ENOMEM); | ||
1192 | } | ||
1193 | |||
1203 | ffs_dev = functionfs_acquire_dev_callback(dev_name); | 1194 | ffs_dev = functionfs_acquire_dev_callback(dev_name); |
1204 | if (IS_ERR(ffs_dev)) | 1195 | if (IS_ERR(ffs_dev)) { |
1205 | return ffs_dev; | 1196 | ffs_data_put(ffs); |
1197 | return ERR_CAST(ffs_dev); | ||
1198 | } | ||
1199 | ffs->private_data = ffs_dev; | ||
1200 | data.ffs_data = ffs; | ||
1206 | 1201 | ||
1207 | data.dev_name = dev_name; | ||
1208 | data.private_data = ffs_dev; | ||
1209 | rv = mount_nodev(t, flags, &data, ffs_sb_fill); | 1202 | rv = mount_nodev(t, flags, &data, ffs_sb_fill); |
1210 | 1203 | if (IS_ERR(rv) && data.ffs_data) { | |
1211 | /* data.ffs_data is set by ffs_sb_fill */ | ||
1212 | if (IS_ERR(rv)) | ||
1213 | functionfs_release_dev_callback(data.ffs_data); | 1204 | functionfs_release_dev_callback(data.ffs_data); |
1214 | 1205 | ffs_data_put(data.ffs_data); | |
1206 | } | ||
1215 | return rv; | 1207 | return rv; |
1216 | } | 1208 | } |
1217 | 1209 | ||