diff options
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r-- | fs/fuse/inode.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 38cf97d6469c..1baaaeb2e850 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -39,6 +39,7 @@ struct fuse_mount_data { | |||
39 | unsigned group_id_present : 1; | 39 | unsigned group_id_present : 1; |
40 | unsigned flags; | 40 | unsigned flags; |
41 | unsigned max_read; | 41 | unsigned max_read; |
42 | unsigned blksize; | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | static struct inode *fuse_alloc_inode(struct super_block *sb) | 45 | static struct inode *fuse_alloc_inode(struct super_block *sb) |
@@ -274,6 +275,7 @@ enum { | |||
274 | OPT_DEFAULT_PERMISSIONS, | 275 | OPT_DEFAULT_PERMISSIONS, |
275 | OPT_ALLOW_OTHER, | 276 | OPT_ALLOW_OTHER, |
276 | OPT_MAX_READ, | 277 | OPT_MAX_READ, |
278 | OPT_BLKSIZE, | ||
277 | OPT_ERR | 279 | OPT_ERR |
278 | }; | 280 | }; |
279 | 281 | ||
@@ -285,14 +287,16 @@ static match_table_t tokens = { | |||
285 | {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, | 287 | {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, |
286 | {OPT_ALLOW_OTHER, "allow_other"}, | 288 | {OPT_ALLOW_OTHER, "allow_other"}, |
287 | {OPT_MAX_READ, "max_read=%u"}, | 289 | {OPT_MAX_READ, "max_read=%u"}, |
290 | {OPT_BLKSIZE, "blksize=%u"}, | ||
288 | {OPT_ERR, NULL} | 291 | {OPT_ERR, NULL} |
289 | }; | 292 | }; |
290 | 293 | ||
291 | static int parse_fuse_opt(char *opt, struct fuse_mount_data *d) | 294 | static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) |
292 | { | 295 | { |
293 | char *p; | 296 | char *p; |
294 | memset(d, 0, sizeof(struct fuse_mount_data)); | 297 | memset(d, 0, sizeof(struct fuse_mount_data)); |
295 | d->max_read = ~0; | 298 | d->max_read = ~0; |
299 | d->blksize = 512; | ||
296 | 300 | ||
297 | while ((p = strsep(&opt, ",")) != NULL) { | 301 | while ((p = strsep(&opt, ",")) != NULL) { |
298 | int token; | 302 | int token; |
@@ -345,6 +349,12 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d) | |||
345 | d->max_read = value; | 349 | d->max_read = value; |
346 | break; | 350 | break; |
347 | 351 | ||
352 | case OPT_BLKSIZE: | ||
353 | if (!is_bdev || match_int(&args[0], &value)) | ||
354 | return 0; | ||
355 | d->blksize = value; | ||
356 | break; | ||
357 | |||
348 | default: | 358 | default: |
349 | return 0; | 359 | return 0; |
350 | } | 360 | } |
@@ -500,15 +510,21 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
500 | struct dentry *root_dentry; | 510 | struct dentry *root_dentry; |
501 | struct fuse_req *init_req; | 511 | struct fuse_req *init_req; |
502 | int err; | 512 | int err; |
513 | int is_bdev = sb->s_bdev != NULL; | ||
503 | 514 | ||
504 | if (sb->s_flags & MS_MANDLOCK) | 515 | if (sb->s_flags & MS_MANDLOCK) |
505 | return -EINVAL; | 516 | return -EINVAL; |
506 | 517 | ||
507 | if (!parse_fuse_opt((char *) data, &d)) | 518 | if (!parse_fuse_opt((char *) data, &d, is_bdev)) |
508 | return -EINVAL; | 519 | return -EINVAL; |
509 | 520 | ||
510 | sb->s_blocksize = PAGE_CACHE_SIZE; | 521 | if (is_bdev) { |
511 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 522 | if (!sb_set_blocksize(sb, d.blksize)) |
523 | return -EINVAL; | ||
524 | } else { | ||
525 | sb->s_blocksize = PAGE_CACHE_SIZE; | ||
526 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | ||
527 | } | ||
512 | sb->s_magic = FUSE_SUPER_MAGIC; | 528 | sb->s_magic = FUSE_SUPER_MAGIC; |
513 | sb->s_op = &fuse_super_operations; | 529 | sb->s_op = &fuse_super_operations; |
514 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 530 | sb->s_maxbytes = MAX_LFS_FILESIZE; |