summaryrefslogtreecommitdiffstats
path: root/sys/fs/smbfs
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2003-06-17 12:58:02 +0000
committertjr <tjr@FreeBSD.org>2003-06-17 12:58:02 +0000
commit6d534d8e046165eceeeee1a288da8f557d4aa386 (patch)
tree6b7cbb58c0fa43be160cb35cbea22eab90824a90 /sys/fs/smbfs
parentec215fe3e905337cba439b9419c1448ebbc5741f (diff)
downloadFreeBSD-src-6d534d8e046165eceeeee1a288da8f557d4aa386.zip
FreeBSD-src-6d534d8e046165eceeeee1a288da8f557d4aa386.tar.gz
Send the close request to the SMB server in smbfs_inactive(), instead of
smbfs_close(). This fixes paging to and from mmap()'d regions of smbfs files after the descriptor has been closed, and makes thttpd, GNU ld, and perhaps more things work that depend on being able to do this. PR: 48291
Diffstat (limited to 'sys/fs/smbfs')
-rw-r--r--sys/fs/smbfs/smbfs_node.c23
-rw-r--r--sys/fs/smbfs/smbfs_node.h2
-rw-r--r--sys/fs/smbfs/smbfs_smb.c3
-rw-r--r--sys/fs/smbfs/smbfs_vnops.c72
4 files changed, 34 insertions, 66 deletions
diff --git a/sys/fs/smbfs/smbfs_node.c b/sys/fs/smbfs/smbfs_node.c
index 093e7ca4..811721f 100644
--- a/sys/fs/smbfs/smbfs_node.c
+++ b/sys/fs/smbfs/smbfs_node.c
@@ -300,6 +300,8 @@ smbfs_reclaim(ap)
SMBVDEBUG("%s,%d\n", np->n_name, vrefcnt(vp));
+ KASSERT((np->n_flag & NOPEN) == 0, ("file not closed before reclaim"));
+
smbfs_hash_lock(smp, td);
dvp = (np->n_parent && (np->n_flag & NREFPARENT)) ?
@@ -340,16 +342,25 @@ smbfs_inactive(ap)
struct vnode *vp = ap->a_vp;
struct smbnode *np = VTOSMB(vp);
struct smb_cred scred;
- int error;
+ struct vattr va;
SMBVDEBUG("%s: %d\n", VTOSMB(vp)->n_name, vrefcnt(vp));
- if (np->n_opencount) {
- error = smbfs_vinvalbuf(vp, V_SAVE, cred, td, 1);
+ if ((np->n_flag & NOPEN) != 0) {
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;
+ smbfs_vinvalbuf(vp, V_SAVE, cred, td, 1);
+ if (vp->v_type == VREG) {
+ VOP_GETATTR(vp, &va, cred, td);
+ smbfs_smb_close(np->n_mount->sm_share, np->n_fid,
+ &np->n_mtime, &scred);
+ } else if (vp->v_type == VDIR) {
+ if (np->n_dirseq != NULL) {
+ smbfs_findclose(np->n_dirseq, &scred);
+ np->n_dirseq = NULL;
+ }
+ }
+ np->n_flag &= ~NOPEN;
}
+ smbfs_attr_cacheremove(vp);
VOP_UNLOCK(vp, 0, td);
return (0);
}
diff --git a/sys/fs/smbfs/smbfs_node.h b/sys/fs/smbfs/smbfs_node.h
index 5474473..884831c 100644
--- a/sys/fs/smbfs/smbfs_node.h
+++ b/sys/fs/smbfs/smbfs_node.h
@@ -43,6 +43,7 @@
/*efine NNEW 0x0008*//* smb/vnode has been allocated */
#define NREFPARENT 0x0010 /* node holds parent from recycling */
#define NFLUSHWIRE 0x1000 /* pending flush request */
+#define NOPEN 0x2000 /* file is open */
struct smbfs_fctx;
@@ -58,7 +59,6 @@ struct smbnode {
u_quad_t n_size;
long n_ino;
int n_dosattr;
- int n_opencount;
u_int16_t n_fid; /* file handle */
int n_rwstate; /* granted access mode */
u_char n_nmlen;
diff --git a/sys/fs/smbfs/smbfs_smb.c b/sys/fs/smbfs/smbfs_smb.c
index 034fc77..3a21ad2 100644
--- a/sys/fs/smbfs/smbfs_smb.c
+++ b/sys/fs/smbfs/smbfs_smb.c
@@ -363,7 +363,8 @@ smb_smb_flush(struct smbnode *np, struct smb_cred *scred)
struct mbchain *mbp;
int error;
- if (np->n_opencount <= 0 || !SMBTOV(np) || SMBTOV(np)->v_type != VREG)
+ if ((np->n_flag & NOPEN) != 0 || !SMBTOV(np) ||
+ SMBTOV(np)->v_type != VREG)
return 0; /* not a regular open file */
error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_FLUSH, scred);
if (error)
diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c
index 7ee89a62..41918b9 100644
--- a/sys/fs/smbfs/smbfs_vnops.c
+++ b/sys/fs/smbfs/smbfs_vnops.c
@@ -170,13 +170,13 @@ smbfs_open(ap)
int mode = ap->a_mode;
int error, accmode;
- SMBVDEBUG("%s,%d\n", np->n_name, np->n_opencount);
+ SMBVDEBUG("%s,%d\n", np->n_name, (np->n_flag & NOPEN) != 0);
if (vp->v_type != VREG && vp->v_type != VDIR) {
SMBFSERR("open eacces vtype=%d\n", vp->v_type);
return EACCES;
}
if (vp->v_type == VDIR) {
- np->n_opencount++;
+ np->n_flag |= NOPEN;
return 0;
}
if (np->n_flag & NMODIFIED) {
@@ -198,10 +198,8 @@ smbfs_open(ap)
np->n_mtime.tv_sec = vattr.va_mtime.tv_sec;
}
}
- if (np->n_opencount) {
- np->n_opencount++;
+ if ((np->n_flag & NOPEN) != 0)
return 0;
- }
/*
* Use DENYNONE to give unixy semantics of permitting
* everything not forbidden by permissions. Ie denial
@@ -221,50 +219,8 @@ smbfs_open(ap)
error = smbfs_smb_open(np, accmode, &scred);
}
}
- if (!error) {
- np->n_opencount++;
- }
- smbfs_attr_cacheremove(vp);
- return error;
-}
-
-static int
-smbfs_closel(struct vop_close_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct smbnode *np = VTOSMB(vp);
- struct thread *td = ap->a_td;
- struct smb_cred scred;
- struct vattr vattr;
- int error;
-
- SMBVDEBUG("name=%s, pid=%d, c=%d\n", np->n_name, td->td_proc->p_pid,
- np->n_opencount);
-
- smb_makescred(&scred, td, ap->a_cred);
-
- if (np->n_opencount == 0) {
- if (vp->v_type != VDIR)
- SMBERROR("Negative opencount\n");
- return 0;
- }
- np->n_opencount--;
- if (vp->v_type == VDIR) {
- if (np->n_opencount)
- return 0;
- if (np->n_dirseq) {
- smbfs_findclose(np->n_dirseq, &scred);
- np->n_dirseq = NULL;
- }
- error = 0;
- } else {
- error = smbfs_vinvalbuf(vp, V_SAVE, ap->a_cred, td, 1);
- if (np->n_opencount)
- return error;
- VOP_GETATTR(vp, &vattr, ap->a_cred, td);
- error = smbfs_smb_close(np->n_mount->sm_share, np->n_fid,
- &np->n_mtime, &scred);
- }
+ if (error == 0)
+ np->n_flag |= NOPEN;
smbfs_attr_cacheremove(vp);
return error;
}
@@ -285,7 +241,7 @@ smbfs_close(ap)
{
struct vnode *vp = ap->a_vp;
struct thread *td = ap->a_td;
- int error, dolock;
+ int dolock;
VI_LOCK(vp);
dolock = (vp->v_iflag & VI_XLOCK) == 0;
@@ -293,10 +249,10 @@ smbfs_close(ap)
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK, td);
else
VI_UNLOCK(vp);
- error = smbfs_closel(ap);
+ /* Nothing. */
if (dolock)
VOP_UNLOCK(vp, 0, td);
- return error;
+ return 0;
}
/*
@@ -333,7 +289,7 @@ smbfs_getattr(ap)
}
smbfs_attr_cacheenter(vp, &fattr);
smbfs_attr_cachelookup(vp, va);
- if (np->n_opencount)
+ if (np->n_flag & NOPEN)
np->n_size = oldsize;
return 0;
}
@@ -384,7 +340,7 @@ smbfs_setattr(ap)
vnode_pager_setsize(vp, (u_long)vap->va_size);
tsize = np->n_size;
np->n_size = vap->va_size;
- if (np->n_opencount == 0) {
+ if ((np->n_flag & NOPEN) == 0) {
error = smbfs_smb_open(np,
SMB_SM_DENYNONE|SMB_AM_OPENRW,
&scred);
@@ -422,7 +378,7 @@ smbfs_setattr(ap)
* If file is opened, then we can use handle based calls.
* If not, use path based ones.
*/
- if (np->n_opencount == 0) {
+ if ((np->n_flag & NOPEN) == 0) {
if (vcp->vc_flags & SMBV_WIN95) {
error = VOP_OPEN(vp, FWRITE, ap->a_cred, ap->a_td);
if (!error) {
@@ -571,7 +527,7 @@ smbfs_remove(ap)
struct smb_cred scred;
int error;
- if (vp->v_type == VDIR || np->n_opencount || vrefcnt(vp) != 1)
+ if (vp->v_type == VDIR || (np->n_flag & NOPEN) != 0 || vrefcnt(vp) != 1)
return EPERM;
smb_makescred(&scred, cnp->cn_thread, cnp->cn_cred);
error = smbfs_smb_delete(np, &scred);
@@ -841,8 +797,8 @@ int smbfs_print (ap)
printf("no smbnode data\n");
return (0);
}
- printf("\tname = %s, parent = %p, opencount = %d\n", np->n_name,
- np->n_parent ? np->n_parent : NULL, np->n_opencount);
+ printf("\tname = %s, parent = %p, open = %d\n", np->n_name,
+ np->n_parent ? np->n_parent : NULL, (np->n_flag & NOPEN) != 0);
return (0);
}
OpenPOWER on IntegriCloud