Tim Robbins wrote:
> Here's a backtrace of a smbfs panic. Looks like it does not correctly
> handle the smbfs_getpages error it is encountering and leaves garbage
> vnodes lying around. The panic probably comes from the VI_LOCK macro
> call on smbfs_node.c line 321.
> 
> # cp blah.tar.gz ~tim
> cp: /home/tim/blah.tar.gz: Bad address


Read the list archives.  We discussed this to death.  The correct
thing to do is to back off and retry -- that's decimal 60, which
is hex 0x3c, which, according to /sys/netsmb/smb_rq.h is:

#define SMBR_REXMIT        0x0004  /* request should be retransmitted */
#define SMBR_INTR          0x0008  /* request interrupted */
#define SMBR_RESTART       0x0010  /* request should be repeated if possible */
#define SMBR_NORESTART     0x0020  /* request is not restartable */

If you don't want to try to implement this, note that the read/write
works (try 'dd' instead of 'cp', so you aren't using mmap'ed pages,
and see that 'dd' works).

I don't think it's worth writing the code to attempt the retry, until
you know that the code will work -- that it's backed up far enough
that the retry won't fail.  This basically means you need to know why
it's failing in the first place, which means you need to be familiar
with how the server is implemented (not likely, unless your name is
"Luke Howard", you're a Microsoft employee, or you have a Windows
source license -- otherwise it's probably about two weeks worth of
work).

The attached patch works around the problem by disabling the getpages
and putpages code in the smbfs.  This basically turns paging operations
into reads and writes, which we know from using 'dd' instead of 'cp'
will work.

Note: this is only a workaround: it disables obviously incorrect code,
but doesn't provide replacement code for the bogus code.

-- Terry
Index: smbfs_io.c
===================================================================
RCS file: /cvs/src/sys/fs/smbfs/smbfs_io.c,v
retrieving revision 1.13
diff -c -r1.13 smbfs_io.c
*** smbfs_io.c  4 Aug 2002 10:29:30 -0000       1.13
--- smbfs_io.c  21 Nov 2002 05:53:23 -0000
***************
*** 400,405 ****
--- 400,406 ----
        return error;
  }
  
+ #if BROKEN_PAGE_IO
  /*
   * Vnode op for VM getpages.
   * Wish wish .... get rid from multiple IO routines
***************
*** 655,660 ****
--- 656,662 ----
        return rtvals[0];
  #endif /* SMBFS_RWGENERIC */
  }
+ #endif        /* BROKEN_PAGE_IO */
  
  /*
   * Flush and invalidate all dirty buffers. If another process is already
Index: smbfs_node.h
===================================================================
RCS file: /cvs/src/sys/fs/smbfs/smbfs_node.h,v
retrieving revision 1.2
diff -c -r1.2 smbfs_node.h
*** smbfs_node.h        18 Sep 2002 09:27:04 -0000      1.2
--- smbfs_node.h        21 Nov 2002 05:53:47 -0000
***************
*** 75,83 ****
  #define VTOSMB(vp)    ((struct smbnode *)(vp)->v_data)
  #define SMBTOV(np)    ((struct vnode *)(np)->n_vnode)
  
  struct vop_getpages_args;
- struct vop_inactive_args;
  struct vop_putpages_args;
  struct vop_reclaim_args;
  struct ucred;
  struct uio;
--- 75,85 ----
  #define VTOSMB(vp)    ((struct smbnode *)(vp)->v_data)
  #define SMBTOV(np)    ((struct vnode *)(np)->n_vnode)
  
+ #if BROKEN_PAGE_IO
  struct vop_getpages_args;
  struct vop_putpages_args;
+ #endif        /* BROKEN_PAGE_IO */
+ struct vop_inactive_args;
  struct vop_reclaim_args;
  struct ucred;
  struct uio;
***************
*** 89,96 ****
--- 91,100 ----
        struct smbfattr *fap, struct vnode **vpp);
  u_int32_t smbfs_hash(const u_char *name, int nmlen);
  
+ #if BROKEN_PAGE_IO
  int  smbfs_getpages(struct vop_getpages_args *);
  int  smbfs_putpages(struct vop_putpages_args *);
+ #endif        /* BROKEN_PAGE_IO */
  int  smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred);
  int  smbfs_writevnode(struct vnode *vp, struct uio *uiop, struct ucred *cred, int 
ioflag);
  void smbfs_attr_cacheenter(struct vnode *vp, struct smbfattr *fap);
Index: smbfs_vnops.c
===================================================================
RCS file: /cvs/src/sys/fs/smbfs/smbfs_vnops.c,v
retrieving revision 1.24
diff -c -r1.24 smbfs_vnops.c
*** smbfs_vnops.c       26 Sep 2002 14:07:43 -0000      1.24
--- smbfs_vnops.c       21 Nov 2002 05:52:32 -0000
***************
*** 96,102 ****
--- 96,104 ----
        { &vop_create_desc,             (vop_t *) smbfs_create },
        { &vop_fsync_desc,              (vop_t *) smbfs_fsync },
        { &vop_getattr_desc,            (vop_t *) smbfs_getattr },
+ #if BROKEN_PAGE_IO
        { &vop_getpages_desc,           (vop_t *) smbfs_getpages },
+ #endif        /* BROKEN_PAGE_IO */
        { &vop_inactive_desc,           (vop_t *) smbfs_inactive },
        { &vop_ioctl_desc,              (vop_t *) smbfs_ioctl },
        { &vop_islocked_desc,           (vop_t *) vop_stdislocked },
***************
*** 108,114 ****
--- 110,118 ----
        { &vop_open_desc,               (vop_t *) smbfs_open },
        { &vop_pathconf_desc,           (vop_t *) smbfs_pathconf },
        { &vop_print_desc,              (vop_t *) smbfs_print },
+ #if BROKEN_PAGE_IO
        { &vop_putpages_desc,           (vop_t *) smbfs_putpages },
+ #endif        /* BROKEN_PAGE_IO */
        { &vop_read_desc,               (vop_t *) smbfs_read },
        { &vop_readdir_desc,            (vop_t *) smbfs_readdir },
        { &vop_reclaim_desc,            (vop_t *) smbfs_reclaim },

Reply via email to