diff options
| -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 | ||
