summaryrefslogtreecommitdiffstats
path: root/sys/fs/smbfs/smbfs_vfsops.c
diff options
context:
space:
mode:
authordavide <davide@FreeBSD.org>2013-05-04 14:03:18 +0000
committerdavide <davide@FreeBSD.org>2013-05-04 14:03:18 +0000
commit49171951e3c2ee391cc14135ca9389ecb4e38f47 (patch)
tree58f50a43b89521ebbbf95593be5439c98bbdde90 /sys/fs/smbfs/smbfs_vfsops.c
parent6473a2540f9533d31ae4872e4485cd1f7eb2e402 (diff)
downloadFreeBSD-src-49171951e3c2ee391cc14135ca9389ecb4e38f47.zip
FreeBSD-src-49171951e3c2ee391cc14135ca9389ecb4e38f47.tar.gz
Completely rewrite the interface to smbdev switching from dev_clone
to cdevpriv(9). This commit changes the semantic of mount_smbfs in userland as well, which now passes file descriptor in order to to mount a specific filesystem istance. Reviewed by: attilio, ed Tested by: martymac
Diffstat (limited to 'sys/fs/smbfs/smbfs_vfsops.c')
-rw-r--r--sys/fs/smbfs/smbfs_vfsops.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/sys/fs/smbfs/smbfs_vfsops.c b/sys/fs/smbfs/smbfs_vfsops.c
index 8b92376..938b7ff 100644
--- a/sys/fs/smbfs/smbfs_vfsops.c
+++ b/sys/fs/smbfs/smbfs_vfsops.c
@@ -122,7 +122,7 @@ smbfs_cmount(struct mntarg *ma, void * data, uint64_t flags)
}
static const char *smbfs_opts[] = {
- "dev", "soft", "intr", "strong", "have_nls", "long",
+ "fd", "soft", "intr", "strong", "have_nls", "long",
"mountpoint", "rootpath", "uid", "gid", "file_mode", "dir_mode",
"caseopt", "errmsg", NULL
};
@@ -135,10 +135,12 @@ smbfs_mount(struct mount *mp)
struct smb_share *ssp = NULL;
struct vnode *vp;
struct thread *td;
+ struct smb_dev *dev;
struct smb_cred *scred;
int error, v;
char *pc, *pe;
+ dev = NULL;
td = curthread;
if (mp->mnt_flag & (MNT_UPDATE | MNT_ROOTFS))
return EOPNOTSUPP;
@@ -150,26 +152,29 @@ smbfs_mount(struct mount *mp)
scred = smbfs_malloc_scred();
smb_makescred(scred, td, td->td_ucred);
- if (1 != vfs_scanopt(mp->mnt_optnew, "dev", "%d", &v)) {
- vfs_mount_error(mp, "No dev option");
+
+ /* Ask userspace of `fd`, the file descriptor of this session */
+ if (1 != vfs_scanopt(mp->mnt_optnew, "fd", "%d", &v)) {
+ vfs_mount_error(mp, "No fd option");
smbfs_free_scred(scred);
return (EINVAL);
}
- error = smb_dev2share(v, SMBM_EXEC, scred, &ssp);
+ error = smb_dev2share(v, SMBM_EXEC, scred, &ssp, &dev);
+ smp = malloc(sizeof(*smp), M_SMBFSDATA, M_WAITOK | M_ZERO);
if (error) {
printf("invalid device handle %d (%d)\n", v, error);
- vfs_mount_error(mp, "invalid device handle %d (%d)\n", v, error);
+ vfs_mount_error(mp, "invalid device handle %d %d\n", v, error);
smbfs_free_scred(scred);
+ free(smp, M_SMBFSDATA);
return error;
}
vcp = SSTOVC(ssp);
smb_share_unlock(ssp, 0);
mp->mnt_stat.f_iosize = SSTOVC(ssp)->vc_txmax;
-
- smp = malloc(sizeof(*smp), M_SMBFSDATA, M_WAITOK | M_ZERO);
- mp->mnt_data = smp;
+ mp->mnt_data = smp;
smp->sm_share = ssp;
smp->sm_root = NULL;
+ smp->sm_dev = dev;
if (1 != vfs_scanopt(mp->mnt_optnew,
"caseopt", "%d", &smp->sm_caseopt)) {
vfs_mount_error(mp, "Invalid caseopt");
@@ -238,8 +243,15 @@ smbfs_mount(struct mount *mp)
bad:
if (ssp)
smb_share_put(ssp, scred);
- smbfs_free_scred(scred);
- return error;
+ smbfs_free_scred(scred);
+ SMB_LOCK();
+ if (error && smp->sm_dev == dev) {
+ smp->sm_dev = NULL;
+ sdp_trydestroy(dev);
+ }
+ SMB_UNLOCK();
+ free(smp, M_SMBFSDATA);
+ return error;
}
/* Unmount the filesystem described by mp. */
@@ -249,6 +261,7 @@ smbfs_unmount(struct mount *mp, int mntflags)
struct thread *td;
struct smbmount *smp = VFSTOSMBFS(mp);
struct smb_cred *scred;
+ struct smb_dev *dev;
int error, flags;
SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags);
@@ -277,7 +290,13 @@ smbfs_unmount(struct mount *mp, int mntflags)
if (error)
goto out;
smb_share_put(smp->sm_share, scred);
+ SMB_LOCK();
+ dev = smp->sm_dev;
+ if (!dev)
+ panic("No private data for mount point");
+ sdp_trydestroy(dev);
mp->mnt_data = NULL;
+ SMB_UNLOCK();
free(smp, M_SMBFSDATA);
MNT_ILOCK(mp);
mp->mnt_flag &= ~MNT_LOCAL;
OpenPOWER on IntegriCloud