smbfs kernel panic
Matthew Dillon
dillon at apollo.backplane.com
Sat Jun 4 11:03:35 PDT 2005
Please try this patch set. I'm not sure whether SMBFS can
safely use the root creds for file closes, which its
inactive code has to do, so I cache the cred used in the
first open and use that for the close.
When I redid the VFS I wanted it to work from pure threads.
Most VFSs don't need creds for inactive and choosing which
cred to use (because multiple user id's might have had the
file open) is rather non-deterministic... so I simply don't
make the cred information available. This means that the
three filesystems that need it (ntfs, smbfs, nfs) need to do
their own heuristic which typically involves caching the open
creds in the auxillary node structure to supply to the close.
This is mainly due to mistakes made in the protocol
specification. For example, NFS servers should always accept
root creds to mean 'the greatest access the server allows
that client to have', but they often don't and instead for user mounts
only allow that particular user cred. It's stupid but it's the way
the cookie crumbles.
-Matt
Index: smbfs_node.c
===================================================================
RCS file: /cvs/src/sys/vfs/smbfs/smbfs_node.c,v
retrieving revision 1.16
diff -u -r1.16 smbfs_node.c
--- smbfs_node.c 17 Dec 2004 00:18:35 -0000 1.16
+++ smbfs_node.c 4 Jun 2005 17:42:37 -0000
@@ -346,16 +346,16 @@
struct smb_cred scred;
int error;
- KKASSERT(td->td_proc);
- cred = td->td_proc->p_ucred;
-
SMBVDEBUG("%s: %d\n", VTOSMB(vp)->n_name, vp->v_usecount);
if (np->n_opencount) {
error = smbfs_vinvalbuf(vp, V_SAVE, td, 1);
+ cred = np->n_cached_cred;
+ np->n_cached_cred = NULL;
smb_makescred(&scred, td, cred);
error = smbfs_smb_close(np->n_mount->sm_share, np->n_fid,
&np->n_mtime, &scred);
np->n_opencount = 0;
+ crfree(cred);
}
return (0);
}
Index: smbfs_node.h
===================================================================
RCS file: /cvs/src/sys/vfs/smbfs/smbfs_node.h,v
retrieving revision 1.4
diff -u -r1.4 smbfs_node.h
--- smbfs_node.h 28 Aug 2004 19:02:28 -0000 1.4
+++ smbfs_node.h 4 Jun 2005 17:35:40 -0000
@@ -61,6 +61,7 @@
long n_ino;
int n_dosattr;
int n_opencount;
+ struct ucred *n_cached_cred; /* cred used to open file */
u_int16_t n_fid; /* file handle */
int n_rwstate; /* granted access mode */
u_char n_nmlen;
Index: smbfs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/vfs/smbfs/smbfs_vfsops.c,v
retrieving revision 1.20
diff -u -r1.20 smbfs_vfsops.c
--- smbfs_vfsops.c 20 Apr 2005 17:01:56 -0000 1.20
+++ smbfs_vfsops.c 4 Jun 2005 17:45:16 -0000
@@ -144,8 +144,10 @@
int error;
char *pc, *pe;
- KKASSERT(td->td_proc);
- cred = td->td_proc->p_ucred;
+ if (td->td_proc)
+ cred = td->td_proc->p_ucred;
+ else
+ cred = proc0.p_ucred;
if (data == NULL) {
printf("missing data argument\n");
@@ -254,8 +256,10 @@
struct ucred *cred;
int error, flags;
- KKASSERT(td->td_proc);
- cred = td->td_proc->p_ucred;
+ if (td->td_proc)
+ cred = td->td_proc->p_ucred;
+ else
+ cred = proc0.p_ucred;
SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags);
flags = 0;
@@ -307,9 +311,6 @@
struct smb_cred scred;
int error;
- KKASSERT(td->td_proc);
- cred = td->td_proc->p_ucred;
-
if (smp == NULL) {
SMBERROR("smp == NULL (bug in umount)\n");
return EINVAL;
@@ -318,6 +319,11 @@
*vpp = SMBTOV(smp->sm_root);
return vget(*vpp, LK_EXCLUSIVE | LK_RETRY, td);
}
+ if (td->td_proc)
+ cred = td->td_proc->p_ucred;
+ else
+ cred = proc0.p_ucred;
+
smb_makescred(&scred, td, cred);
error = smbfs_smb_lookup(NULL, NULL, 0, &fattr, &scred);
if (error)
@@ -388,8 +394,10 @@
struct ucred *cred;
int error = 0;
- KKASSERT(td->td_proc);
- cred = td->td_proc->p_ucred;
+ if (td->td_proc)
+ cred = td->td_proc->p_ucred;
+ else
+ cred = proc0.p_ucred;
if (np == NULL)
return EINVAL;
Index: smbfs_vnops.c
===================================================================
RCS file: /cvs/src/sys/vfs/smbfs/smbfs_vnops.c,v
retrieving revision 1.22
diff -u -r1.22 smbfs_vnops.c
--- smbfs_vnops.c 15 Feb 2005 08:32:18 -0000 1.22
+++ smbfs_vnops.c 4 Jun 2005 17:42:21 -0000
@@ -178,6 +178,8 @@
return EACCES;
}
if (vp->v_type == VDIR) {
+ if (np->n_opencount == 0)
+ np->n_cached_cred = crhold(ap->a_cred);
np->n_opencount++;
return 0;
}
@@ -216,6 +218,7 @@
error = smbfs_smb_open(np, accmode, &scred);
}
if (!error) {
+ np->n_cached_cred = crhold(ap->a_cred);
np->n_opencount++;
}
smbfs_attr_cacheremove(vp);
@@ -258,6 +261,8 @@
error = smbfs_smb_close(np->n_mount->sm_share, np->n_fid,
&np->n_mtime, &scred);
}
+ crfree(np->n_cached_cred);
+ np->n_cached_cred = NULL;
smbfs_attr_cacheremove(vp);
return error;
}
More information about the Bugs
mailing list