aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifsfs.c
diff options
context:
space:
mode:
authorPavel Shilovsky <piastry@etersoft.ru>2011-05-05 05:55:12 -0400
committerSteve French <sfrench@us.ibm.com>2011-05-23 23:07:42 -0400
commit724d9f1cfba0cb16a7151333b501e8f7885450d8 (patch)
treed86b0e84a9475374cdbd05cc1e4f85fd0231162f /fs/cifs/cifsfs.c
parent37bb04e5a091a5330faef0cc09930326672b7061 (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.c88
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
106static int 106static int
107cifs_read_super(struct super_block *sb, void *data, 107cifs_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
562static struct dentry * 547static struct dentry *
563cifs_do_mount(struct file_system_type *fs_type, 548cifs_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);
602out:
603 cifs_cleanup_volume_info(&volume_info);
604 return root;
605
606err_out:
607 kfree(cifs_sb);
608 deactivate_locked_super(sb);
609 cifs_cleanup_volume_info(&volume_info);
610 return root;
585} 611}
586 612
587static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, 613static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,