diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2011-05-05 05:55:12 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-05-23 23:07:42 -0400 |
commit | 724d9f1cfba0cb16a7151333b501e8f7885450d8 (patch) | |
tree | d86b0e84a9475374cdbd05cc1e4f85fd0231162f /fs/cifs/cifsfs.c | |
parent | 37bb04e5a091a5330faef0cc09930326672b7061 (diff) |
CIFS: Simplify mount code for further shared sb capability
Reorganize code to get mount option at first and when get a superblock.
This lets us use shared superblock model further for equal mounts.
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r-- | fs/cifs/cifsfs.c | 88 |
1 files changed, 57 insertions, 31 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 493b74ca5648..131afadce0e0 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -104,19 +104,16 @@ cifs_sb_deactive(struct super_block *sb) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | static int | 106 | static int |
107 | cifs_read_super(struct super_block *sb, void *data, | 107 | cifs_read_super(struct super_block *sb, struct cifs_sb_info *cifs_sb, |
108 | const char *devname, int silent) | 108 | void *data, struct smb_vol *volume_info, const char *devname, |
109 | int silent) | ||
109 | { | 110 | { |
110 | struct inode *inode; | 111 | struct inode *inode; |
111 | struct cifs_sb_info *cifs_sb; | ||
112 | int rc = 0; | 112 | int rc = 0; |
113 | 113 | ||
114 | /* BB should we make this contingent on mount parm? */ | 114 | /* BB should we make this contingent on mount parm? */ |
115 | sb->s_flags |= MS_NODIRATIME | MS_NOATIME; | 115 | sb->s_flags |= MS_NODIRATIME | MS_NOATIME; |
116 | sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); | 116 | sb->s_fs_info = cifs_sb; |
117 | cifs_sb = CIFS_SB(sb); | ||
118 | if (cifs_sb == NULL) | ||
119 | return -ENOMEM; | ||
120 | 117 | ||
121 | spin_lock_init(&cifs_sb->tlink_tree_lock); | 118 | spin_lock_init(&cifs_sb->tlink_tree_lock); |
122 | cifs_sb->tlink_tree = RB_ROOT; | 119 | cifs_sb->tlink_tree = RB_ROOT; |
@@ -128,22 +125,10 @@ cifs_read_super(struct super_block *sb, void *data, | |||
128 | } | 125 | } |
129 | cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; | 126 | cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; |
130 | 127 | ||
131 | /* | 128 | if (data) |
132 | * Copy mount params to sb for use in submounts. Better to do | 129 | cifs_sb->mountdata = data; |
133 | * the copy here and deal with the error before cleanup gets | ||
134 | * complicated post-mount. | ||
135 | */ | ||
136 | if (data) { | ||
137 | cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL); | ||
138 | if (cifs_sb->mountdata == NULL) { | ||
139 | bdi_destroy(&cifs_sb->bdi); | ||
140 | kfree(sb->s_fs_info); | ||
141 | sb->s_fs_info = NULL; | ||
142 | return -ENOMEM; | ||
143 | } | ||
144 | } | ||
145 | 130 | ||
146 | rc = cifs_mount(sb, cifs_sb, devname); | 131 | rc = cifs_mount(sb, cifs_sb, volume_info, devname); |
147 | 132 | ||
148 | if (rc) { | 133 | if (rc) { |
149 | if (!silent) | 134 | if (!silent) |
@@ -561,27 +546,68 @@ static const struct super_operations cifs_super_ops = { | |||
561 | 546 | ||
562 | static struct dentry * | 547 | static struct dentry * |
563 | cifs_do_mount(struct file_system_type *fs_type, | 548 | cifs_do_mount(struct file_system_type *fs_type, |
564 | int flags, const char *dev_name, void *data) | 549 | int flags, const char *dev_name, void *data) |
565 | { | 550 | { |
566 | int rc; | 551 | int rc; |
567 | struct super_block *sb; | 552 | struct super_block *sb; |
568 | 553 | struct cifs_sb_info *cifs_sb; | |
569 | sb = sget(fs_type, NULL, set_anon_super, NULL); | 554 | struct smb_vol *volume_info; |
555 | struct dentry *root; | ||
556 | char *copied_data = NULL; | ||
570 | 557 | ||
571 | cFYI(1, "Devname: %s flags: %d ", dev_name, flags); | 558 | cFYI(1, "Devname: %s flags: %d ", dev_name, flags); |
572 | 559 | ||
573 | if (IS_ERR(sb)) | 560 | rc = cifs_setup_volume_info(&volume_info, (char *)data, dev_name); |
574 | return ERR_CAST(sb); | 561 | if (rc) |
562 | return ERR_PTR(rc); | ||
563 | |||
564 | cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); | ||
565 | if (cifs_sb == NULL) { | ||
566 | root = ERR_PTR(-ENOMEM); | ||
567 | goto out; | ||
568 | } | ||
569 | |||
570 | cifs_setup_cifs_sb(volume_info, cifs_sb); | ||
571 | |||
572 | sb = sget(fs_type, NULL, set_anon_super, NULL); | ||
573 | if (IS_ERR(sb)) { | ||
574 | kfree(cifs_sb); | ||
575 | root = ERR_CAST(sb); | ||
576 | goto out; | ||
577 | } | ||
575 | 578 | ||
576 | sb->s_flags = flags; | 579 | sb->s_flags = flags; |
577 | 580 | ||
578 | rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0); | 581 | /* |
582 | * Copy mount params for use in submounts. Better to do | ||
583 | * the copy here and deal with the error before cleanup gets | ||
584 | * complicated post-mount. | ||
585 | */ | ||
586 | copied_data = kstrndup(data, PAGE_SIZE, GFP_KERNEL); | ||
587 | if (copied_data == NULL) { | ||
588 | root = ERR_PTR(-ENOMEM); | ||
589 | goto err_out; | ||
590 | } | ||
591 | |||
592 | rc = cifs_read_super(sb, cifs_sb, copied_data, volume_info, dev_name, | ||
593 | flags & MS_SILENT ? 1 : 0); | ||
579 | if (rc) { | 594 | if (rc) { |
580 | deactivate_locked_super(sb); | 595 | root = ERR_PTR(rc); |
581 | return ERR_PTR(rc); | 596 | goto err_out; |
582 | } | 597 | } |
598 | |||
583 | sb->s_flags |= MS_ACTIVE; | 599 | sb->s_flags |= MS_ACTIVE; |
584 | return dget(sb->s_root); | 600 | |
601 | root = dget(sb->s_root); | ||
602 | out: | ||
603 | cifs_cleanup_volume_info(&volume_info); | ||
604 | return root; | ||
605 | |||
606 | err_out: | ||
607 | kfree(cifs_sb); | ||
608 | deactivate_locked_super(sb); | ||
609 | cifs_cleanup_volume_info(&volume_info); | ||
610 | return root; | ||
585 | } | 611 | } |
586 | 612 | ||
587 | static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 613 | static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, |