[BACK]Return to msdosfs_vnops.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / fs / msdosfs

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/fs/msdosfs/msdosfs_vnops.c between version 1.55 and 1.61.4.6

version 1.55, 2008/11/28 10:57:03 version 1.61.4.6, 2011/05/31 03:04:59
Line 60  __KERNEL_RCSID(0, "$NetBSD$");
Line 60  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/buf.h>  #include <sys/buf.h>
 #include <sys/proc.h>  #include <sys/proc.h>
 #include <sys/mount.h>  #include <sys/mount.h>
   #include <sys/fstrans.h>
 #include <sys/vnode.h>  #include <sys/vnode.h>
 #include <sys/signalvar.h>  #include <sys/signalvar.h>
 #include <sys/malloc.h>  #include <sys/malloc.h>
Line 98  __KERNEL_RCSID(0, "$NetBSD$");
Line 99  __KERNEL_RCSID(0, "$NetBSD$");
   
 /*  /*
  * Create a regular file. On entry the directory to contain the file being   * Create a regular file. On entry the directory to contain the file being
  * created is locked.  We must release before we return. We must also free   * created is locked.  We must release before we return.
  * the pathname buffer pointed at by cnp->cn_pnbuf, always on error, or  
  * only if the SAVESTART bit in cn_flags is clear on success.  
  */   */
 int  int
 msdosfs_create(v)  msdosfs_create(void *v)
         void *v;  
 {  {
         struct vop_create_args /* {          struct vop_create_args /* {
                 struct vnode *a_dvp;                  struct vnode *a_dvp;
Line 122  msdosfs_create(v)
Line 120  msdosfs_create(v)
         printf("msdosfs_create(cnp %p, vap %p\n", cnp, ap->a_vap);          printf("msdosfs_create(cnp %p, vap %p\n", cnp, ap->a_vap);
 #endif  #endif
   
           fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED);
         /*          /*
          * If this is the root directory and there is no space left we           * If this is the root directory and there is no space left we
          * can't do anything.  This is because the root directory can not           * can't do anything.  This is because the root directory can not
Line 139  msdosfs_create(v)
Line 138  msdosfs_create(v)
          * use the absence of the owner write bit to make the file           * use the absence of the owner write bit to make the file
          * readonly.           * readonly.
          */           */
 #ifdef DIAGNOSTIC  
         if ((cnp->cn_flags & HASBUF) == 0)  
                 panic("msdosfs_create: no name");  
 #endif  
         memset(&ndirent, 0, sizeof(ndirent));          memset(&ndirent, 0, sizeof(ndirent));
         if ((error = uniqdosname(pdep, cnp, ndirent.de_Name)) != 0)          if ((error = uniqdosname(pdep, cnp, ndirent.de_Name)) != 0)
                 goto bad;                  goto bad;
Line 158  msdosfs_create(v)
Line 153  msdosfs_create(v)
         DETIMES(&ndirent, NULL, NULL, NULL, pdep->de_pmp->pm_gmtoff);          DETIMES(&ndirent, NULL, NULL, NULL, pdep->de_pmp->pm_gmtoff);
         if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0)          if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0)
                 goto bad;                  goto bad;
         if ((cnp->cn_flags & SAVESTART) == 0)          fstrans_done(ap->a_dvp->v_mount);
                 PNBUF_PUT(cnp->cn_pnbuf);  
         VN_KNOTE(ap->a_dvp, NOTE_WRITE);          VN_KNOTE(ap->a_dvp, NOTE_WRITE);
         vput(ap->a_dvp);          vput(ap->a_dvp);
         *ap->a_vpp = DETOV(dep);          *ap->a_vpp = DETOV(dep);
         return (0);          return (0);
   
 bad:  bad:
         PNBUF_PUT(cnp->cn_pnbuf);          fstrans_done(ap->a_dvp->v_mount);
         vput(ap->a_dvp);          vput(ap->a_dvp);
         return (error);          return (error);
 }  }
   
 int  int
 msdosfs_mknod(v)  msdosfs_close(void *v)
         void *v;  
 {  
         struct vop_mknod_args /* {  
                 struct vnode *a_dvp;  
                 struct vnode **a_vpp;  
                 struct componentname *a_cnp;  
                 struct vattr *a_vap;  
         } */ *ap = v;  
   
         PNBUF_PUT(ap->a_cnp->cn_pnbuf);  
         vput(ap->a_dvp);  
         return (EINVAL);  
 }  
   
 int  
 msdosfs_open(void *v)  
 {  
 #if 0  
         struct vop_open_args /* {  
                 struct vnode *a_vp;  
                 int a_mode;  
                 kauth_cred_t a_cred;  
         } */ *ap;  
 #endif  
   
         return (0);  
 }  
   
 int  
 msdosfs_close(v)  
         void *v;  
 {  {
         struct vop_close_args /* {          struct vop_close_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 213  msdosfs_close(v)
Line 176  msdosfs_close(v)
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
         struct denode *dep = VTODE(vp);          struct denode *dep = VTODE(vp);
   
         mutex_enter(&vp->v_interlock);          fstrans_start(vp->v_mount, FSTRANS_SHARED);
           mutex_enter(vp->v_interlock);
         if (vp->v_usecount > 1)          if (vp->v_usecount > 1)
                 DETIMES(dep, NULL, NULL, NULL, dep->de_pmp->pm_gmtoff);                  DETIMES(dep, NULL, NULL, NULL, dep->de_pmp->pm_gmtoff);
         mutex_exit(&vp->v_interlock);          mutex_exit(vp->v_interlock);
           fstrans_done(vp->v_mount);
         return (0);          return (0);
 }  }
   
 int  static int
 msdosfs_access(v)  msdosfs_check_possible(struct vnode *vp, struct denode *dep, mode_t mode)
         void *v;  
 {  {
         struct vop_access_args /* {  
                 struct vnode *a_vp;  
                 int a_mode;  
                 kauth_cred_t a_cred;  
         } */ *ap = v;  
         struct vnode *vp = ap->a_vp;  
         struct denode *dep = VTODE(vp);  
         struct msdosfsmount *pmp = dep->de_pmp;  
         mode_t mode = ap->a_mode;  
   
         /*          /*
          * Disallow write attempts on read-only file systems;           * Disallow write attempts on read-only file systems;
Line 251  msdosfs_access(v)
Line 206  msdosfs_access(v)
                 }                  }
         }          }
   
           return 0;
   }
   
   static int
   msdosfs_check_permitted(struct vnode *vp, struct denode *dep, mode_t mode,
       kauth_cred_t cred)
   {
           struct msdosfsmount *pmp = dep->de_pmp;
           mode_t file_mode;
   
         if ((dep->de_Attributes & ATTR_READONLY) == 0)          if ((dep->de_Attributes & ATTR_READONLY) == 0)
                 mode = S_IRWXU|S_IRWXG|S_IRWXO;                  file_mode = S_IRWXU|S_IRWXG|S_IRWXO;
         else          else
                 mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;                  file_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
         return (vaccess(ap->a_vp->v_type,  
             mode & (vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask),          return genfs_can_access(vp->v_type,
             pmp->pm_uid, pmp->pm_gid, ap->a_mode, ap->a_cred));              file_mode & (vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask),
               pmp->pm_uid, pmp->pm_gid, mode, cred);
 }  }
   
 int  int
 msdosfs_getattr(v)  msdosfs_access(void *v)
         void *v;  {
           struct vop_access_args /* {
                   struct vnode *a_vp;
                   int a_mode;
                   kauth_cred_t a_cred;
           } */ *ap = v;
           struct vnode *vp = ap->a_vp;
           struct denode *dep = VTODE(vp);
           int error;
   
           error = msdosfs_check_possible(vp, dep, ap->a_mode);
           if (error)
                   return error;
   
           error = msdosfs_check_permitted(vp, dep, ap->a_mode, ap->a_cred);
   
           return error;
   }
   
   int
   msdosfs_getattr(void *v)
 {  {
         struct vop_getattr_args /* {          struct vop_getattr_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 276  msdosfs_getattr(v)
Line 262  msdosfs_getattr(v)
         u_long dirsperblk = pmp->pm_BytesPerSec / sizeof(struct direntry);          u_long dirsperblk = pmp->pm_BytesPerSec / sizeof(struct direntry);
         ino_t fileid;          ino_t fileid;
   
           fstrans_start(ap->a_vp->v_mount, FSTRANS_SHARED);
         DETIMES(dep, NULL, NULL, NULL, pmp->pm_gmtoff);          DETIMES(dep, NULL, NULL, NULL, pmp->pm_gmtoff);
         vap->va_fsid = dep->de_dev;          vap->va_fsid = dep->de_dev;
         /*          /*
Line 324  msdosfs_getattr(v)
Line 311  msdosfs_getattr(v)
         vap->va_bytes =          vap->va_bytes =
             (dep->de_FileSize + pmp->pm_crbomask) & ~pmp->pm_crbomask;              (dep->de_FileSize + pmp->pm_crbomask) & ~pmp->pm_crbomask;
         vap->va_type = ap->a_vp->v_type;          vap->va_type = ap->a_vp->v_type;
           fstrans_done(ap->a_vp->v_mount);
         return (0);          return (0);
 }  }
   
 int  int
 msdosfs_setattr(v)  msdosfs_setattr(void *v)
         void *v;  
 {  {
         struct vop_setattr_args /* {          struct vop_setattr_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 358  msdosfs_setattr(v)
Line 345  msdosfs_setattr(v)
             (vap->va_gid != VNOVAL && vap->va_gid != pmp->pm_gid)) {              (vap->va_gid != VNOVAL && vap->va_gid != pmp->pm_gid)) {
 #ifdef MSDOSFS_DEBUG  #ifdef MSDOSFS_DEBUG
                 printf("msdosfs_setattr(): returning EINVAL\n");                  printf("msdosfs_setattr(): returning EINVAL\n");
                 printf("    va_type %d, va_nlink %x, va_fsid %lx, va_fileid %llx\n",                  printf("    va_type %d, va_nlink %x, va_fsid %"PRIx64", va_fileid %llx\n",
                     vap->va_type, vap->va_nlink, vap->va_fsid,                      vap->va_type, vap->va_nlink, vap->va_fsid,
                     (unsigned long long)vap->va_fileid);                      (unsigned long long)vap->va_fileid);
                 printf("    va_blocksize %lx, va_rdev %x, va_bytes %qx, va_gen %lx\n",                  printf("    va_blocksize %lx, va_rdev %"PRIx64", va_bytes %"PRIx64", va_gen %lx\n",
                     vap->va_blocksize, vap->va_rdev, (long long)vap->va_bytes, vap->va_gen);                      vap->va_blocksize, vap->va_rdev, vap->va_bytes, vap->va_gen);
 #endif  #endif
                 return (EINVAL);                  return (EINVAL);
         }          }
Line 372  msdosfs_setattr(v)
Line 359  msdosfs_setattr(v)
         if (ap->a_vp->v_type == VDIR)          if (ap->a_vp->v_type == VDIR)
                 return 0;                  return 0;
   
           fstrans_start(vp->v_mount, FSTRANS_SHARED);
         if (vap->va_size != VNOVAL) {          if (vap->va_size != VNOVAL) {
                 if (vp->v_mount->mnt_flag & MNT_RDONLY)                  if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                         return (EROFS);                          error = EROFS;
                           goto bad;
                   }
                 error = detrunc(dep, (u_long)vap->va_size, 0, cred);                  error = detrunc(dep, (u_long)vap->va_size, 0, cred);
                 if (error)                  if (error)
                         return (error);                          goto bad;
                 de_changed = 1;                  de_changed = 1;
         }          }
         if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {          if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
                 if (vp->v_mount->mnt_flag & MNT_RDONLY)                  if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                         return (EROFS);                          error = EROFS;
                 if (kauth_cred_geteuid(cred) != pmp->pm_uid &&                          goto bad;
                     (error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,                  }
                     NULL)) &&                  error = genfs_can_chtimes(ap->a_vp, vap->va_vaflags,
                     ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||                      pmp->pm_uid, cred);
                     (error = VOP_ACCESS(ap->a_vp, VWRITE, cred))))                  if (error)
                         return (error);                          goto bad;
                 if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 &&                  if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 &&
                     vap->va_atime.tv_sec != VNOVAL)                      vap->va_atime.tv_sec != VNOVAL)
                         unix2dostime(&vap->va_atime, pmp->pm_gmtoff, &dep->de_ADate, NULL, NULL);                          unix2dostime(&vap->va_atime, pmp->pm_gmtoff, &dep->de_ADate, NULL, NULL);
Line 404  msdosfs_setattr(v)
Line 394  msdosfs_setattr(v)
          * attribute.           * attribute.
          */           */
         if (vap->va_mode != (mode_t)VNOVAL) {          if (vap->va_mode != (mode_t)VNOVAL) {
                 if (vp->v_mount->mnt_flag & MNT_RDONLY)                  if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                         return (EROFS);                          error = EROFS;
                           goto bad;
                   }
                 if (kauth_cred_geteuid(cred) != pmp->pm_uid &&                  if (kauth_cred_geteuid(cred) != pmp->pm_uid &&
                     (error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,                      (error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
                     NULL)))                      NULL)))
                         return (error);                          goto bad;
                 /* We ignore the read and execute bits. */                  /* We ignore the read and execute bits. */
                 if (vap->va_mode & S_IWUSR)                  if (vap->va_mode & S_IWUSR)
                         dep->de_Attributes &= ~ATTR_READONLY;                          dep->de_Attributes &= ~ATTR_READONLY;
Line 422  msdosfs_setattr(v)
Line 414  msdosfs_setattr(v)
          * Allow the `archived' bit to be toggled.           * Allow the `archived' bit to be toggled.
          */           */
         if (vap->va_flags != VNOVAL) {          if (vap->va_flags != VNOVAL) {
                 if (vp->v_mount->mnt_flag & MNT_RDONLY)                  if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                         return (EROFS);                          error = EROFS;
                           goto bad;
                   }
                 if (kauth_cred_geteuid(cred) != pmp->pm_uid &&                  if (kauth_cred_geteuid(cred) != pmp->pm_uid &&
                     (error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,                      (error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
                     NULL)))                      NULL)))
                         return (error);                          goto bad;
                 if (vap->va_flags & SF_ARCHIVED)                  if (vap->va_flags & SF_ARCHIVED)
                         dep->de_Attributes &= ~ATTR_ARCHIVE;                          dep->de_Attributes &= ~ATTR_ARCHIVE;
                 else                  else
Line 438  msdosfs_setattr(v)
Line 432  msdosfs_setattr(v)
   
         if (de_changed) {          if (de_changed) {
                 VN_KNOTE(vp, NOTE_ATTRIB);                  VN_KNOTE(vp, NOTE_ATTRIB);
                 return (deupdat(dep, 1));                  error = deupdat(dep, 1);
         } else                  if (error)
                 return (0);                          goto bad;
           }
   
   bad:
           fstrans_done(vp->v_mount);
           return error;
 }  }
   
 int  int
 msdosfs_read(v)  msdosfs_read(void *v)
         void *v;  
 {  {
         struct vop_read_args /* {          struct vop_read_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 477  msdosfs_read(v)
Line 475  msdosfs_read(v)
         if (uio->uio_offset >= dep->de_FileSize)          if (uio->uio_offset >= dep->de_FileSize)
                 return (0);                  return (0);
   
           fstrans_start(vp->v_mount, FSTRANS_SHARED);
         if (vp->v_type == VREG) {          if (vp->v_type == VREG) {
                 const int advice = IO_ADV_DECODE(ap->a_ioflag);                  const int advice = IO_ADV_DECODE(ap->a_ioflag);
   
Line 510  msdosfs_read(v)
Line 509  msdosfs_read(v)
                 /* convert cluster # to sector # */                  /* convert cluster # to sector # */
                 error = pcbmap(dep, lbn, &lbn, 0, &blsize);                  error = pcbmap(dep, lbn, &lbn, 0, &blsize);
                 if (error)                  if (error)
                         return (error);                          goto bad;
   
                 /*                  /*
                  * If we are operating on a directory file then be sure to                   * If we are operating on a directory file then be sure to
Line 522  msdosfs_read(v)
Line 521  msdosfs_read(v)
                 n = MIN(n, pmp->pm_bpcluster - bp->b_resid);                  n = MIN(n, pmp->pm_bpcluster - bp->b_resid);
                 if (error) {                  if (error) {
                         brelse(bp, 0);                          brelse(bp, 0);
                         return (error);                          goto bad;
                 }                  }
                 error = uiomove((char *)bp->b_data + on, (int) n, uio);                  error = uiomove((char *)bp->b_data + on, (int) n, uio);
                 brelse(bp, 0);                  brelse(bp, 0);
Line 531  msdosfs_read(v)
Line 530  msdosfs_read(v)
 out:  out:
         if ((ap->a_ioflag & IO_SYNC) == IO_SYNC)          if ((ap->a_ioflag & IO_SYNC) == IO_SYNC)
                 error = deupdat(dep, 1);                  error = deupdat(dep, 1);
   bad:
           fstrans_done(vp->v_mount);
         return (error);          return (error);
 }  }
   
Line 538  out:
Line 539  out:
  * Write data to a file or directory.   * Write data to a file or directory.
  */   */
 int  int
 msdosfs_write(v)  msdosfs_write(void *v)
         void *v;  
 {  {
         struct vop_write_args /* {          struct vop_write_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 554  msdosfs_write(v)
Line 554  msdosfs_write(v)
         u_long count;          u_long count;
         vsize_t bytelen;          vsize_t bytelen;
         off_t oldoff;          off_t oldoff;
           size_t rem;
         struct uio *uio = ap->a_uio;          struct uio *uio = ap->a_uio;
         struct proc *p = curproc;  
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
         struct denode *dep = VTODE(vp);          struct denode *dep = VTODE(vp);
         struct msdosfsmount *pmp = dep->de_pmp;          struct msdosfsmount *pmp = dep->de_pmp;
Line 590  msdosfs_write(v)
Line 590  msdosfs_write(v)
         if (uio->uio_offset + uio->uio_resid > MSDOSFS_FILESIZE_MAX)          if (uio->uio_offset + uio->uio_resid > MSDOSFS_FILESIZE_MAX)
                 return (EFBIG);                  return (EFBIG);
   
         /*          fstrans_start(vp->v_mount, FSTRANS_SHARED);
          * If they've exceeded their filesize limit, tell them about it.  
          */  
         if (((uio->uio_offset + uio->uio_resid) >  
             p->p_rlimit[RLIMIT_FSIZE].rlim_cur)) {  
                 mutex_enter(proc_lock);  
                 psignal(p, SIGXFSZ);  
                 mutex_exit(proc_lock);  
                 return (EFBIG);  
         }  
   
         /*          /*
          * If the offset we are starting the write at is beyond the end of           * If the offset we are starting the write at is beyond the end of
          * the file, then they've done a seek.  Unix filesystems allow           * the file, then they've done a seek.  Unix filesystems allow
Line 608  msdosfs_write(v)
Line 598  msdosfs_write(v)
          * with zeroed blocks.           * with zeroed blocks.
          */           */
         if (uio->uio_offset > dep->de_FileSize) {          if (uio->uio_offset > dep->de_FileSize) {
                 if ((error = deextend(dep, uio->uio_offset, cred)) != 0)                  if ((error = deextend(dep, uio->uio_offset, cred)) != 0) {
                           fstrans_done(vp->v_mount);
                         return (error);                          return (error);
                   }
         }          }
   
         /*          /*
Line 632  msdosfs_write(v)
Line 624  msdosfs_write(v)
                 dep->de_FileSize = uio->uio_offset + resid;                  dep->de_FileSize = uio->uio_offset + resid;
                 /* hint uvm to not read in extended part */                  /* hint uvm to not read in extended part */
                 uvm_vnp_setwritesize(vp, dep->de_FileSize);                  uvm_vnp_setwritesize(vp, dep->de_FileSize);
                   /* zero out the remainder of the last page */
                   rem = round_page(dep->de_FileSize) - dep->de_FileSize;
                   if (rem > 0)
                           uvm_vnp_zerorange(vp, (off_t)dep->de_FileSize, rem);
                 extended = 1;                  extended = 1;
         }          }
   
Line 650  msdosfs_write(v)
Line 646  msdosfs_write(v)
                  */                   */
   
                 if (!async && oldoff >> 16 != uio->uio_offset >> 16) {                  if (!async && oldoff >> 16 != uio->uio_offset >> 16) {
                         mutex_enter(&vp->v_interlock);                          mutex_enter(vp->v_interlock);
                         error = VOP_PUTPAGES(vp, (oldoff >> 16) << 16,                          error = VOP_PUTPAGES(vp, (oldoff >> 16) << 16,
                             (uio->uio_offset >> 16) << 16, PGO_CLEANIT);                              (uio->uio_offset >> 16) << 16, PGO_CLEANIT);
                 }                  }
Line 659  msdosfs_write(v)
Line 655  msdosfs_write(v)
         /* set final size */          /* set final size */
         uvm_vnp_setsize(vp, dep->de_FileSize);          uvm_vnp_setsize(vp, dep->de_FileSize);
         if (error == 0 && ioflag & IO_SYNC) {          if (error == 0 && ioflag & IO_SYNC) {
                 mutex_enter(&vp->v_interlock);                  mutex_enter(vp->v_interlock);
                 error = VOP_PUTPAGES(vp, trunc_page(oldoff),                  error = VOP_PUTPAGES(vp, trunc_page(oldoff),
                     round_page(oldoff + bytelen), PGO_CLEANIT | PGO_SYNCIO);                      round_page(oldoff + bytelen), PGO_CLEANIT | PGO_SYNCIO);
         }          }
Line 678  errexit:
Line 674  errexit:
                 uio->uio_resid = resid;                  uio->uio_resid = resid;
         } else if ((ioflag & IO_SYNC) == IO_SYNC)          } else if ((ioflag & IO_SYNC) == IO_SYNC)
                 error = deupdat(dep, 1);                  error = deupdat(dep, 1);
           fstrans_done(vp->v_mount);
         KASSERT(vp->v_size == dep->de_FileSize);          KASSERT(vp->v_size == dep->de_FileSize);
         return (error);          return (error);
 }  }
Line 721  msdosfs_update(struct vnode *vp, const s
Line 718  msdosfs_update(struct vnode *vp, const s
  * could just do a sync if they try an fsync on a directory file.   * could just do a sync if they try an fsync on a directory file.
  */   */
 int  int
 msdosfs_remove(v)  msdosfs_remove(void *v)
         void *v;  
 {  {
         struct vop_remove_args /* {          struct vop_remove_args /* {
                 struct vnode *a_dvp;                  struct vnode *a_dvp;
Line 733  msdosfs_remove(v)
Line 729  msdosfs_remove(v)
         struct denode *ddep = VTODE(ap->a_dvp);          struct denode *ddep = VTODE(ap->a_dvp);
         int error;          int error;
   
           fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED);
         if (ap->a_vp->v_type == VDIR)          if (ap->a_vp->v_type == VDIR)
                 error = EPERM;                  error = EPERM;
         else          else
Line 749  msdosfs_remove(v)
Line 746  msdosfs_remove(v)
                 vput(ap->a_vp); /* causes msdosfs_inactive() to be called                  vput(ap->a_vp); /* causes msdosfs_inactive() to be called
                                  * via vrele() */                                   * via vrele() */
         vput(ap->a_dvp);          vput(ap->a_dvp);
           fstrans_done(ap->a_dvp->v_mount);
         return (error);          return (error);
 }  }
   
 /*  /*
  * DOS filesystems don't know what links are. But since we already called  
  * msdosfs_lookup() with create and lockparent, the parent is locked so we  
  * have to free it before we return the error.  
  */  
 int  
 msdosfs_link(v)  
         void *v;  
 {  
         struct vop_link_args /* {  
                 struct vnode *a_dvp;  
                 struct vnode *a_vp;  
                 struct componentname *a_cnp;  
         } */ *ap = v;  
   
         VOP_ABORTOP(ap->a_dvp, ap->a_cnp);  
         vput(ap->a_dvp);  
         return (EOPNOTSUPP);  
 }  
   
 /*  
  * Renames on files require moving the denode to a new hash queue since the   * Renames on files require moving the denode to a new hash queue since the
  * denode's location is used to compute which hash queue to put the file   * denode's location is used to compute which hash queue to put the file
  * in. Unless it is a rename in place.  For example "mv a b".   * in. Unless it is a rename in place.  For example "mv a b".
Line 829  msdosfs_link(v)
Line 807  msdosfs_link(v)
  * This routine needs help.  badly.   * This routine needs help.  badly.
  */   */
 int  int
 msdosfs_rename(v)  msdosfs_rename(void *v)
         void *v;  
 {  {
         struct vop_rename_args /* {          struct vop_rename_args /* {
                 struct vnode *a_fdvp;                  struct vnode *a_fdvp;
Line 847  msdosfs_rename(v)
Line 824  msdosfs_rename(v)
         struct componentname *tcnp = ap->a_tcnp;          struct componentname *tcnp = ap->a_tcnp;
         struct componentname *fcnp = ap->a_fcnp;          struct componentname *fcnp = ap->a_fcnp;
         struct denode *ip, *xp, *dp, *zp;          struct denode *ip, *xp, *dp, *zp;
         u_char toname[11], oldname[11];          u_char toname[12], oldname[12];
         u_long from_diroffset, to_diroffset;          u_long from_diroffset, to_diroffset;
         u_char to_count;          u_char to_count;
         int doingdirectory = 0, newparent = 0;          int doingdirectory = 0, newparent = 0;
Line 857  msdosfs_rename(v)
Line 834  msdosfs_rename(v)
         struct msdosfsmount *pmp;          struct msdosfsmount *pmp;
         struct direntry *dotdotp;          struct direntry *dotdotp;
         struct buf *bp;          struct buf *bp;
         int fdvp_dorele = 0;  
   
         pmp = VFSTOMSDOSFS(fdvp->v_mount);          pmp = VFSTOMSDOSFS(fdvp->v_mount);
   
 #ifdef DIAGNOSTIC  
         if ((tcnp->cn_flags & HASBUF) == 0 ||  
             (fcnp->cn_flags & HASBUF) == 0)  
                 panic("msdosfs_rename: no name");  
 #endif  
         /*          /*
          * Check for cross-device rename.           * Check for cross-device rename.
          */           */
Line 918  abortit:
Line 889  abortit:
                     (fcnp->cn_flags & ISDOTDOT) ||                      (fcnp->cn_flags & ISDOTDOT) ||
                     (tcnp->cn_flags & ISDOTDOT) ||                      (tcnp->cn_flags & ISDOTDOT) ||
                     (ip->de_flag & DE_RENAME)) {                      (ip->de_flag & DE_RENAME)) {
                         VOP_UNLOCK(fvp, 0);                          VOP_UNLOCK(fvp);
                         error = EINVAL;                          error = EINVAL;
                         goto abortit;                          goto abortit;
                 }                  }
Line 927  abortit:
Line 898  abortit:
         }          }
         VN_KNOTE(fdvp, NOTE_WRITE);             /* XXXLUKEM/XXX: right place? */          VN_KNOTE(fdvp, NOTE_WRITE);             /* XXXLUKEM/XXX: right place? */
   
           fstrans_start(fdvp->v_mount, FSTRANS_SHARED);
         /*          /*
          * When the target exists, both the directory           * When the target exists, both the directory
          * and target vnodes are returned locked.           * and target vnodes are returned locked.
Line 950  abortit:
Line 922  abortit:
          * call to doscheckpath().           * call to doscheckpath().
          */           */
         error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred);          error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred);
         VOP_UNLOCK(fvp, 0);          VOP_UNLOCK(fvp);
         if (VTODE(fdvp)->de_StartCluster != VTODE(tdvp)->de_StartCluster)          if (VTODE(fdvp)->de_StartCluster != VTODE(tdvp)->de_StartCluster)
                 newparent = 1;                  newparent = 1;
   
         /*  
          * XXX: We can do this here because rename uses SAVEFART and  
          * therefore fdvp has at least two references (one doesn't  
          * belong to us, though, and that's evil).  We'll get  
          * another "extra" reference when we do relookup(), so we  
          * need to compensate.  We should *NOT* be doing this, but  
          * it works, so whatever.  
          */  
         vrele(fdvp);  
   
         if (doingdirectory && newparent) {          if (doingdirectory && newparent) {
                 if (error)      /* write access check above */                  if (error)      /* write access check above */
                         goto tdvpbad;                          goto tdvpbad;
Line 971  abortit:
Line 933  abortit:
                         vput(tvp);                          vput(tvp);
                 tvp = NULL;                  tvp = NULL;
                 /*                  /*
                  * doscheckpath() vput()'s dp,                   * doscheckpath() vput()'s tdvp (dp == VTODE(tdvp)),
                  * so we have to do a relookup afterwards                   * so we have to get an extra ref to it first, and
                    * because it's been unlocked we need to do a relookup
                    * afterwards in case tvp has changed.
                  */                   */
                   vref(tdvp);
                 if ((error = doscheckpath(ip, dp)) != 0)                  if ((error = doscheckpath(ip, dp)) != 0)
                         goto out;                          goto bad;
                 if ((tcnp->cn_flags & SAVESTART) == 0)  
                         panic("msdosfs_rename: lost to startdir");  
                 vn_lock(tdvp, LK_EXCLUSIVE | LK_RETRY);                  vn_lock(tdvp, LK_EXCLUSIVE | LK_RETRY);
                 if ((error = relookup(tdvp, &tvp, tcnp)) != 0) {                  if ((error = relookup(tdvp, &tvp, tcnp, 0)) != 0) {
                         VOP_UNLOCK(tdvp, 0);                          VOP_UNLOCK(tdvp);
                         goto out;                          goto bad;
                 }                  }
                 /*  
                  * XXX: SAVESTART causes us to get a reference, but  
                  * that's released already above in doscheckpath()  
                  */  
                 dp = VTODE(tdvp);                  dp = VTODE(tdvp);
                 xp = tvp ? VTODE(tvp) : NULL;                  xp = tvp ? VTODE(tvp) : NULL;
         }          }
Line 1025  abortit:
Line 984  abortit:
          * into the denode and directory entry for the destination           * into the denode and directory entry for the destination
          * file/directory.           * file/directory.
          */           */
         if ((error = uniqdosname(VTODE(tdvp), tcnp, toname)) != 0)          if ((error = uniqdosname(VTODE(tdvp), tcnp, toname)) != 0) {
                   fstrans_done(fdvp->v_mount);
                 goto abortit;                  goto abortit;
           }
   
         /*          /*
          * Since from wasn't locked at various places above,           * Since from wasn't locked at various places above,
Line 1034  abortit:
Line 995  abortit:
          */           */
         fcnp->cn_flags &= ~MODMASK;          fcnp->cn_flags &= ~MODMASK;
         fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;          fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
         if ((fcnp->cn_flags & SAVESTART) == 0)          VOP_UNLOCK(tdvp);
                 panic("msdosfs_rename: lost from startdir");  
         VOP_UNLOCK(tdvp, 0);  
         vn_lock(fdvp, LK_EXCLUSIVE | LK_RETRY);          vn_lock(fdvp, LK_EXCLUSIVE | LK_RETRY);
         if ((error = relookup(fdvp, &fvp, fcnp))) {          if ((error = relookup(fdvp, &fvp, fcnp, 0))) {
                 VOP_UNLOCK(fdvp, 0);                  VOP_UNLOCK(fdvp);
                 vrele(ap->a_fvp);                  vrele(ap->a_fvp);
                 vrele(tdvp);                  vrele(tdvp);
                   fstrans_done(fdvp->v_mount);
                 return (error);                  return (error);
         }          }
         if (fvp == NULL) {          if (fvp == NULL) {
Line 1053  abortit:
Line 1013  abortit:
                 vput(fdvp);                  vput(fdvp);
                 vrele(ap->a_fvp);                  vrele(ap->a_fvp);
                 vrele(tdvp);                  vrele(tdvp);
                   fstrans_done(fdvp->v_mount);
                 return 0;                  return 0;
         }          }
         fdvp_dorele = 1;          VOP_UNLOCK(fdvp);
         VOP_UNLOCK(fdvp, 0);  
         xp = VTODE(fvp);          xp = VTODE(fvp);
         zp = VTODE(fdvp);          zp = VTODE(fdvp);
         from_diroffset = zp->de_fndoffset;          from_diroffset = zp->de_fndoffset;
Line 1073  abortit:
Line 1033  abortit:
                 if (doingdirectory)                  if (doingdirectory)
                         panic("rename: lost dir entry");                          panic("rename: lost dir entry");
                 vrele(ap->a_fvp);                  vrele(ap->a_fvp);
                 VOP_UNLOCK(fvp, 0);  
                 xp = NULL;                  xp = NULL;
         } else {          } else {
                 vrele(fvp);                  vrele(fvp);
Line 1094  abortit:
Line 1053  abortit:
                 error = createde(ip, dp, (struct denode **)0, tcnp);                  error = createde(ip, dp, (struct denode **)0, tcnp);
                 if (error) {                  if (error) {
                         memcpy(ip->de_Name, oldname, 11);                          memcpy(ip->de_Name, oldname, 11);
                         VOP_UNLOCK(fvp, 0);                          VOP_UNLOCK(fvp);
                         goto bad;                          goto bad;
                 }                  }
                 ip->de_refcnt++;                  ip->de_refcnt++;
                 zp->de_fndoffset = from_diroffset;                  zp->de_fndoffset = from_diroffset;
                 if ((error = removede(zp, ip)) != 0) {                  if ((error = removede(zp, ip)) != 0) {
                         /* XXX should really panic here, fs is corrupt */                          /* XXX should really panic here, fs is corrupt */
                         VOP_UNLOCK(fvp, 0);                          VOP_UNLOCK(fvp);
                         goto bad;                          goto bad;
                 }                  }
                 cache_purge(fvp);                  cache_purge(fvp);
Line 1110  abortit:
Line 1069  abortit:
                                        &ip->de_dirclust, 0);                                         &ip->de_dirclust, 0);
                         if (error) {                          if (error) {
                                 /* XXX should really panic here, fs is corrupt */                                  /* XXX should really panic here, fs is corrupt */
                                 VOP_UNLOCK(fvp, 0);                                  VOP_UNLOCK(fvp);
                                 goto bad;                                  goto bad;
                         }                          }
                         ip->de_diroffset = to_diroffset;                          ip->de_diroffset = to_diroffset;
Line 1136  abortit:
Line 1095  abortit:
                 if (error) {                  if (error) {
                         /* XXX should really panic here, fs is corrupt */                          /* XXX should really panic here, fs is corrupt */
                         brelse(bp, 0);                          brelse(bp, 0);
                         VOP_UNLOCK(fvp, 0);                          VOP_UNLOCK(fvp);
                         goto bad;                          goto bad;
                 }                  }
                 dotdotp = (struct direntry *)bp->b_data + 1;                  dotdotp = (struct direntry *)bp->b_data + 1;
Line 1149  abortit:
Line 1108  abortit:
                 }                  }
                 if ((error = bwrite(bp)) != 0) {                  if ((error = bwrite(bp)) != 0) {
                         /* XXX should really panic here, fs is corrupt */                          /* XXX should really panic here, fs is corrupt */
                         VOP_UNLOCK(fvp, 0);                          VOP_UNLOCK(fvp);
                         goto bad;                          goto bad;
                 }                  }
         }          }
   
         VN_KNOTE(fvp, NOTE_RENAME);          VN_KNOTE(fvp, NOTE_RENAME);
         VOP_UNLOCK(fvp, 0);          VOP_UNLOCK(fvp);
 bad:  bad:
         if (tvp)          if (tvp)
                 vput(tvp);                  vput(tvp);
         vrele(tdvp);          vrele(tdvp);
 out:  
         ip->de_flag &= ~DE_RENAME;          ip->de_flag &= ~DE_RENAME;
         if (fdvp_dorele)          vrele(fdvp);
                 vrele(fdvp);  
         vrele(fvp);          vrele(fvp);
           fstrans_done(fdvp->v_mount);
         return (error);          return (error);
   
         /* XXX: uuuh */          /* XXX: uuuh */
 tdvpbad:  tdvpbad:
         VOP_UNLOCK(tdvp, 0);          VOP_UNLOCK(tdvp);
         goto bad;          goto bad;
 }  }
   
Line 1200  static const struct {
Line 1158  static const struct {
 };  };
   
 int  int
 msdosfs_mkdir(v)  msdosfs_mkdir(void *v)
         void *v;  
 {  {
         struct vop_mkdir_args /* {          struct vop_mkdir_args /* {
                 struct vnode *a_dvp;                  struct vnode *a_dvp;
Line 1222  msdosfs_mkdir(v)
Line 1179  msdosfs_mkdir(v)
         struct buf *bp;          struct buf *bp;
         int async = pdep->de_pmp->pm_mountp->mnt_flag & MNT_ASYNC;          int async = pdep->de_pmp->pm_mountp->mnt_flag & MNT_ASYNC;
   
           fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED);
         /*          /*
          * If this is the root directory and there is no space left we           * If this is the root directory and there is no space left we
          * can't do anything.  This is because the root directory can not           * can't do anything.  This is because the root directory can not
Line 1292  msdosfs_mkdir(v)
Line 1250  msdosfs_mkdir(v)
          * cluster.  This will be written to an empty slot in the parent           * cluster.  This will be written to an empty slot in the parent
          * directory.           * directory.
          */           */
 #ifdef DIAGNOSTIC  
         if ((cnp->cn_flags & HASBUF) == 0)  
                 panic("msdosfs_mkdir: no name");  
 #endif  
         if ((error = uniqdosname(pdep, cnp, ndirent.de_Name)) != 0)          if ((error = uniqdosname(pdep, cnp, ndirent.de_Name)) != 0)
                 goto bad;                  goto bad;
   
Line 1306  msdosfs_mkdir(v)
Line 1260  msdosfs_mkdir(v)
         ndirent.de_devvp = pdep->de_devvp;          ndirent.de_devvp = pdep->de_devvp;
         if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0)          if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0)
                 goto bad;                  goto bad;
         if ((cnp->cn_flags & SAVESTART) == 0)  
                 PNBUF_PUT(cnp->cn_pnbuf);  
         VN_KNOTE(ap->a_dvp, NOTE_WRITE | NOTE_LINK);          VN_KNOTE(ap->a_dvp, NOTE_WRITE | NOTE_LINK);
         vput(ap->a_dvp);          vput(ap->a_dvp);
         *ap->a_vpp = DETOV(dep);          *ap->a_vpp = DETOV(dep);
           fstrans_done(ap->a_dvp->v_mount);
         return (0);          return (0);
   
 bad:  bad:
         clusterfree(pmp, newcluster, NULL);          clusterfree(pmp, newcluster, NULL);
 bad2:  bad2:
         PNBUF_PUT(cnp->cn_pnbuf);  
         vput(ap->a_dvp);          vput(ap->a_dvp);
           fstrans_done(ap->a_dvp->v_mount);
         return (error);          return (error);
 }  }
   
 int  int
 msdosfs_rmdir(v)  msdosfs_rmdir(void *v)
         void *v;  
 {  {
         struct vop_rmdir_args /* {          struct vop_rmdir_args /* {
                 struct vnode *a_dvp;                  struct vnode *a_dvp;
Line 1346  msdosfs_rmdir(v)
Line 1298  msdosfs_rmdir(v)
                 vput(vp);                  vput(vp);
                 return (EINVAL);                  return (EINVAL);
         }          }
           fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED);
         /*          /*
          * Verify the directory is empty (and valid).           * Verify the directory is empty (and valid).
          * (Rmdir ".." won't be valid since           * (Rmdir ".." won't be valid since
Line 1387  out:
Line 1340  out:
         if (dvp)          if (dvp)
                 vput(dvp);                  vput(dvp);
         vput(vp);          vput(vp);
           fstrans_done(ap->a_dvp->v_mount);
         return (error);          return (error);
 }  }
   
 /*  
  * DOS filesystems don't know what symlinks are.  
  */  
 int  int
 msdosfs_symlink(v)  msdosfs_readdir(void *v)
         void *v;  
 {  
         struct vop_symlink_args /* {  
                 struct vnode *a_dvp;  
                 struct vnode **a_vpp;  
                 struct componentname *a_cnp;  
                 struct vattr *a_vap;  
                 char *a_target;  
         } */ *ap = v;  
   
         VOP_ABORTOP(ap->a_dvp, ap->a_cnp);  
         vput(ap->a_dvp);  
         return (EOPNOTSUPP);  
 }  
   
 int  
 msdosfs_readdir(v)  
         void *v;  
 {  {
         struct vop_readdir_args /* {          struct vop_readdir_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 1473  msdosfs_readdir(v)
Line 1406  msdosfs_readdir(v)
         uio->uio_resid = count;          uio->uio_resid = count;
         uio_off = uio->uio_offset;          uio_off = uio->uio_offset;
   
           fstrans_start(ap->a_vp->v_mount, FSTRANS_SHARED);
   
         /* Allocate a temporary dirent buffer. */          /* Allocate a temporary dirent buffer. */
         dirbuf = malloc(sizeof(struct dirent), M_MSDOSFSTMP, M_WAITOK | M_ZERO);          dirbuf = malloc(sizeof(struct dirent), M_MSDOSFSTMP, M_WAITOK | M_ZERO);
   
Line 1552  msdosfs_readdir(v)
Line 1487  msdosfs_readdir(v)
                     NOCRED, 0, &bp);                      NOCRED, 0, &bp);
                 if (error) {                  if (error) {
                         brelse(bp, 0);                          brelse(bp, 0);
                         free(dirbuf, M_MSDOSFSTMP);                          goto bad;
                         return (error);  
                 }                  }
                 n = MIN(n, blsize - bp->b_resid);                  n = MIN(n, blsize - bp->b_resid);
   
Line 1674  out:
Line 1608  out:
                 } else                  } else
                         *ap->a_ncookies = ncookies;                          *ap->a_ncookies = ncookies;
         }          }
   
   bad:
         free(dirbuf, M_MSDOSFSTMP);          free(dirbuf, M_MSDOSFSTMP);
           fstrans_done(ap->a_vp->v_mount);
         return (error);          return (error);
 }  }
   
 /*  /*
  * DOS filesystems don't know what symlinks are.  
  */  
 int  
 msdosfs_readlink(void *v)  
 {  
 #if 0  
         struct vop_readlink_args /* {  
                 struct vnode *a_vp;  
                 struct uio *a_uio;  
                 kauth_cred_t a_cred;  
         } */ *ap;  
 #endif  
   
         return (EINVAL);  
 }  
   
 /*  
  * vp  - address of vnode file the file   * vp  - address of vnode file the file
  * bn  - which cluster we are interested in mapping to a filesystem block number.   * bn  - which cluster we are interested in mapping to a filesystem block number.
  * vpp - returns the vnode for the block special file holding the filesystem   * vpp - returns the vnode for the block special file holding the filesystem
Line 1703  msdosfs_readlink(void *v)
Line 1623  msdosfs_readlink(void *v)
  * bnp - address of where to return the filesystem relative block number   * bnp - address of where to return the filesystem relative block number
  */   */
 int  int
 msdosfs_bmap(v)  msdosfs_bmap(void *v)
         void *v;  
 {  {
         struct vop_bmap_args /* {          struct vop_bmap_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 1753  msdosfs_bmap(v)
Line 1672  msdosfs_bmap(v)
 }  }
   
 int  int
 msdosfs_strategy(v)  msdosfs_strategy(void *v)
         void *v;  
 {  {
         struct vop_strategy_args /* {          struct vop_strategy_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 1798  msdosfs_strategy(v)
Line 1716  msdosfs_strategy(v)
 }  }
   
 int  int
 msdosfs_print(v)  msdosfs_print(void *v)
         void *v;  
 {  {
         struct vop_print_args /* {          struct vop_print_args /* {
                 struct vnode *vp;                  struct vnode *vp;
Line 1809  msdosfs_print(v)
Line 1726  msdosfs_print(v)
         printf(          printf(
             "tag VT_MSDOSFS, startcluster %ld, dircluster %ld, diroffset %ld ",              "tag VT_MSDOSFS, startcluster %ld, dircluster %ld, diroffset %ld ",
             dep->de_StartCluster, dep->de_dirclust, dep->de_diroffset);              dep->de_StartCluster, dep->de_dirclust, dep->de_diroffset);
         printf(" dev %d, %d ", major(dep->de_dev), minor(dep->de_dev));          printf(" dev %llu, %llu ", (unsigned long long)major(dep->de_dev),
               (unsigned long long)minor(dep->de_dev));
         printf("\n");          printf("\n");
         return (0);          return (0);
 }  }
   
 int  int
 msdosfs_advlock(v)  msdosfs_advlock(void *v)
         void *v;  
 {  {
         struct vop_advlock_args /* {          struct vop_advlock_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 1831  msdosfs_advlock(v)
Line 1748  msdosfs_advlock(v)
 }  }
   
 int  int
 msdosfs_pathconf(v)  msdosfs_pathconf(void *v)
         void *v;  
 {  {
         struct vop_pathconf_args /* {          struct vop_pathconf_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 1869  msdosfs_pathconf(v)
Line 1785  msdosfs_pathconf(v)
 }  }
   
 int  int
 msdosfs_fsync(v)  msdosfs_fsync(void *v)
         void *v;  
 {  {
         struct vop_fsync_args /* {          struct vop_fsync_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
Line 1883  msdosfs_fsync(v)
Line 1798  msdosfs_fsync(v)
         int wait;          int wait;
         int error;          int error;
   
           fstrans_start(vp->v_mount, FSTRANS_LAZY);
         wait = (ap->a_flags & FSYNC_WAIT) != 0;          wait = (ap->a_flags & FSYNC_WAIT) != 0;
         vflushbuf(vp, wait);          error = vflushbuf(vp, wait);
         if ((ap->a_flags & FSYNC_DATAONLY) != 0)          if (error == 0 && (ap->a_flags & FSYNC_DATAONLY) == 0)
                 error = 0;  
         else  
                 error = msdosfs_update(vp, NULL, NULL, wait ? UPDATE_WAIT : 0);                  error = msdosfs_update(vp, NULL, NULL, wait ? UPDATE_WAIT : 0);
   
         if (error == 0 && ap->a_flags & FSYNC_CACHE) {          if (error == 0 && ap->a_flags & FSYNC_CACHE) {
Line 1898  msdosfs_fsync(v)
Line 1812  msdosfs_fsync(v)
                 error = VOP_IOCTL(devvp, DIOCCACHESYNC, &l, FWRITE,                  error = VOP_IOCTL(devvp, DIOCCACHESYNC, &l, FWRITE,
                                           curlwp->l_cred);                                            curlwp->l_cred);
         }          }
           fstrans_done(vp->v_mount);
   
         return (error);          return (error);
 }  }
Line 1944  const struct vnodeopv_entry_desc msdosfs
Line 1859  const struct vnodeopv_entry_desc msdosfs
         { &vop_default_desc, vn_default_error },          { &vop_default_desc, vn_default_error },
         { &vop_lookup_desc, msdosfs_lookup },           /* lookup */          { &vop_lookup_desc, msdosfs_lookup },           /* lookup */
         { &vop_create_desc, msdosfs_create },           /* create */          { &vop_create_desc, msdosfs_create },           /* create */
         { &vop_mknod_desc, msdosfs_mknod },             /* mknod */          { &vop_mknod_desc, genfs_eopnotsupp },          /* mknod */
         { &vop_open_desc, msdosfs_open },               /* open */          { &vop_open_desc, genfs_nullop },               /* open */
         { &vop_close_desc, msdosfs_close },             /* close */          { &vop_close_desc, msdosfs_close },             /* close */
         { &vop_access_desc, msdosfs_access },           /* access */          { &vop_access_desc, msdosfs_access },           /* access */
         { &vop_getattr_desc, msdosfs_getattr },         /* getattr */          { &vop_getattr_desc, msdosfs_getattr },         /* getattr */
Line 1961  const struct vnodeopv_entry_desc msdosfs
Line 1876  const struct vnodeopv_entry_desc msdosfs
         { &vop_fsync_desc, msdosfs_fsync },             /* fsync */          { &vop_fsync_desc, msdosfs_fsync },             /* fsync */
         { &vop_seek_desc, msdosfs_seek },               /* seek */          { &vop_seek_desc, msdosfs_seek },               /* seek */
         { &vop_remove_desc, msdosfs_remove },           /* remove */          { &vop_remove_desc, msdosfs_remove },           /* remove */
         { &vop_link_desc, msdosfs_link },               /* link */          { &vop_link_desc, genfs_eopnotsupp },           /* link */
         { &vop_rename_desc, msdosfs_rename },           /* rename */          { &vop_rename_desc, msdosfs_rename },           /* rename */
         { &vop_mkdir_desc, msdosfs_mkdir },             /* mkdir */          { &vop_mkdir_desc, msdosfs_mkdir },             /* mkdir */
         { &vop_rmdir_desc, msdosfs_rmdir },             /* rmdir */          { &vop_rmdir_desc, msdosfs_rmdir },             /* rmdir */
         { &vop_symlink_desc, msdosfs_symlink },         /* symlink */          { &vop_symlink_desc, genfs_eopnotsupp },        /* symlink */
         { &vop_readdir_desc, msdosfs_readdir },         /* readdir */          { &vop_readdir_desc, msdosfs_readdir },         /* readdir */
         { &vop_readlink_desc, msdosfs_readlink },       /* readlink */          { &vop_readlink_desc, genfs_einval },           /* readlink */
         { &vop_abortop_desc, msdosfs_abortop },         /* abortop */          { &vop_abortop_desc, msdosfs_abortop },         /* abortop */
         { &vop_inactive_desc, msdosfs_inactive },       /* inactive */          { &vop_inactive_desc, msdosfs_inactive },       /* inactive */
         { &vop_reclaim_desc, msdosfs_reclaim },         /* reclaim */          { &vop_reclaim_desc, msdosfs_reclaim },         /* reclaim */

Legend:
Removed from v.1.55  
changed lines
  Added in v.1.61.4.6

CVSweb <webmaster@jp.NetBSD.org>