summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavide <davide@FreeBSD.org>2013-03-09 13:25:45 +0000
committerdavide <davide@FreeBSD.org>2013-03-09 13:25:45 +0000
commitce7dfce71d8e802cd71adc3fc170aebddb1b8916 (patch)
tree066a92fc7a2c25a6629b8dcdaa1673c0645e572e
parentf30e75d436ea279224e3f491fa7d4ea8f19cba68 (diff)
downloadFreeBSD-src-ce7dfce71d8e802cd71adc3fc170aebddb1b8916.zip
FreeBSD-src-ce7dfce71d8e802cd71adc3fc170aebddb1b8916.tar.gz
smbfs_lookup() in the DOTDOT case operates on dvp->n_parent without
proper locking. This doesn't prevent in any case reclaim of the vnode. Avoid this not going over-the-wire in this case and relying on subsequent smbfs_getattr() call to restore consistency. While I'm here, change a couple of SMBVDEBUG() in MPASS(). sbmfs_smb_lookup() doesn't and shouldn't know about '.' and '..' Reported by: pho's stress2 suite
-rw-r--r--sys/fs/smbfs/smbfs_smb.c12
-rw-r--r--sys/fs/smbfs/smbfs_vnops.c19
2 files changed, 16 insertions, 15 deletions
diff --git a/sys/fs/smbfs/smbfs_smb.c b/sys/fs/smbfs/smbfs_smb.c
index 05d482e..ec4a49d 100644
--- a/sys/fs/smbfs/smbfs_smb.c
+++ b/sys/fs/smbfs/smbfs_smb.c
@@ -1455,15 +1455,9 @@ smbfs_smb_lookup(struct smbnode *dnp, const char *name, int nmlen,
fap->fa_ino = 2;
return 0;
}
- if (nmlen == 1 && name[0] == '.') {
- error = smbfs_smb_lookup(dnp, NULL, 0, fap, scred);
- return error;
- } else if (nmlen == 2 && name[0] == '.' && name[1] == '.') {
- error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, fap,
- scred);
- printf("%s: knows NOTHING about '..'\n", __func__);
- return error;
- }
+ MPASS(!(nmlen == 2 && name[0] == '.' && name[1] == '.'));
+ MPASS(!(nmlen == 1 && name[0] == '.'));
+ ASSERT_VOP_ELOCKED(dnp->n_vnode, "smbfs_smb_lookup");
error = smbfs_findopen(dnp, name, nmlen,
SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR, scred, &ctx);
if (error)
diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c
index 6285dfd..6ceed9c 100644
--- a/sys/fs/smbfs/smbfs_vnops.c
+++ b/sys/fs/smbfs/smbfs_vnops.c
@@ -1204,13 +1204,20 @@ smbfs_lookup(ap)
smb_makescred(scred, td, cnp->cn_cred);
fap = &fattr;
if (flags & ISDOTDOT) {
- error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, fap,
- scred);
- SMBVDEBUG("result of dotdot lookup: %d\n", error);
- } else {
- fap = &fattr;
+ /*
+ * In the DOTDOT case, don't go over-the-wire
+ * in order to request attributes. We already
+ * know it's a directory and subsequent call to
+ * smbfs_getattr() will restore consistency.
+ *
+ */
+ SMBVDEBUG("smbfs_smb_lookup: dotdot\n");
+ } else if (isdot) {
+ error = smbfs_smb_lookup(dnp, NULL, 0, fap, scred);
+ SMBVDEBUG("result of smbfs_smb_lookup: %d\n", error);
+ }
+ else {
error = smbfs_smb_lookup(dnp, name, nmlen, fap, scred);
-/* if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.')*/
SMBVDEBUG("result of smbfs_smb_lookup: %d\n", error);
}
if (error && error != ENOENT)
OpenPOWER on IntegriCloud