diff options
author | davide <davide@FreeBSD.org> | 2013-03-09 13:25:45 +0000 |
---|---|---|
committer | davide <davide@FreeBSD.org> | 2013-03-09 13:25:45 +0000 |
commit | ce7dfce71d8e802cd71adc3fc170aebddb1b8916 (patch) | |
tree | 066a92fc7a2c25a6629b8dcdaa1673c0645e572e | |
parent | f30e75d436ea279224e3f491fa7d4ea8f19cba68 (diff) | |
download | FreeBSD-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.c | 12 | ||||
-rw-r--r-- | sys/fs/smbfs/smbfs_vnops.c | 19 |
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) |