version 1.61.4.6, 2011/05/31 03:04:59 |
version 1.96.4.1, 2017/04/21 16:54:01 |
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 104 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 103 __KERNEL_RCSID(0, "$NetBSD$"); |
|
int |
int |
msdosfs_create(void *v) |
msdosfs_create(void *v) |
{ |
{ |
struct vop_create_args /* { |
struct vop_create_v3_args /* { |
struct vnode *a_dvp; |
struct vnode *a_dvp; |
struct vnode **a_vpp; |
struct vnode **a_vpp; |
struct componentname *a_cnp; |
struct componentname *a_cnp; |
Line 120 msdosfs_create(void *v) |
|
Line 119 msdosfs_create(void *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 153 msdosfs_create(void *v) |
|
Line 151 msdosfs_create(void *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; |
fstrans_done(ap->a_dvp->v_mount); |
|
VN_KNOTE(ap->a_dvp, NOTE_WRITE); |
VN_KNOTE(ap->a_dvp, NOTE_WRITE); |
vput(ap->a_dvp); |
|
*ap->a_vpp = DETOV(dep); |
*ap->a_vpp = DETOV(dep); |
return (0); |
return (0); |
|
|
bad: |
bad: |
fstrans_done(ap->a_dvp->v_mount); |
|
vput(ap->a_dvp); |
|
return (error); |
return (error); |
} |
} |
|
|
Line 176 msdosfs_close(void *v) |
|
Line 170 msdosfs_close(void *v) |
|
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
struct denode *dep = VTODE(vp); |
struct denode *dep = VTODE(vp); |
|
|
fstrans_start(vp->v_mount, FSTRANS_SHARED); |
|
mutex_enter(vp->v_interlock); |
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); |
} |
} |
|
|
Line 221 msdosfs_check_permitted(struct vnode *vp |
|
Line 213 msdosfs_check_permitted(struct vnode *vp |
|
else |
else |
file_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 genfs_can_access(vp->v_type, |
file_mode &= (vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask); |
file_mode & (vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask), |
|
pmp->pm_uid, pmp->pm_gid, mode, cred); |
return kauth_authorize_vnode(cred, KAUTH_ACCESS_ACTION(mode, |
|
vp->v_type, file_mode), vp, NULL, genfs_can_access(vp->v_type, |
|
file_mode, pmp->pm_uid, pmp->pm_gid, mode, cred)); |
} |
} |
|
|
int |
int |
Line 262 msdosfs_getattr(void *v) |
|
Line 256 msdosfs_getattr(void *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 304 msdosfs_getattr(void *v) |
|
Line 297 msdosfs_getattr(void *v) |
|
vap->va_ctime = vap->va_mtime; |
vap->va_ctime = vap->va_mtime; |
} |
} |
vap->va_flags = 0; |
vap->va_flags = 0; |
if ((dep->de_Attributes & ATTR_ARCHIVE) == 0) |
if ((dep->de_Attributes & ATTR_ARCHIVE) == 0) { |
|
vap->va_flags |= SF_ARCHIVED; |
vap->va_mode |= S_ARCH1; |
vap->va_mode |= S_ARCH1; |
|
} |
vap->va_gen = 0; |
vap->va_gen = 0; |
vap->va_blocksize = pmp->pm_bpcluster; |
vap->va_blocksize = pmp->pm_bpcluster; |
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); |
} |
} |
|
|
Line 359 msdosfs_setattr(void *v) |
|
Line 353 msdosfs_setattr(void *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) { |
error = EROFS; |
error = EROFS; |
Line 375 msdosfs_setattr(void *v) |
|
Line 368 msdosfs_setattr(void *v) |
|
error = EROFS; |
error = EROFS; |
goto bad; |
goto bad; |
} |
} |
error = genfs_can_chtimes(ap->a_vp, vap->va_vaflags, |
error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_TIMES, |
pmp->pm_uid, cred); |
ap->a_vp, NULL, genfs_can_chtimes(ap->a_vp, vap->va_vaflags, |
|
pmp->pm_uid, cred)); |
if (error) |
if (error) |
goto bad; |
goto bad; |
if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 && |
if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 && |
Line 398 msdosfs_setattr(void *v) |
|
Line 392 msdosfs_setattr(void *v) |
|
error = EROFS; |
error = EROFS; |
goto bad; |
goto bad; |
} |
} |
if (kauth_cred_geteuid(cred) != pmp->pm_uid && |
error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_FLAGS, vp, |
(error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, |
NULL, genfs_can_chflags(cred, vp->v_type, pmp->pm_uid, false)); |
NULL))) |
if (error) |
goto bad; |
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) |
Line 418 msdosfs_setattr(void *v) |
|
Line 412 msdosfs_setattr(void *v) |
|
error = EROFS; |
error = EROFS; |
goto bad; |
goto bad; |
} |
} |
if (kauth_cred_geteuid(cred) != pmp->pm_uid && |
error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_FLAGS, vp, |
(error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, |
NULL, genfs_can_chflags(cred, vp->v_type, pmp->pm_uid, false)); |
NULL))) |
if (error) |
goto bad; |
goto bad; |
if (vap->va_flags & SF_ARCHIVED) |
if (vap->va_flags & SF_ARCHIVED) |
dep->de_Attributes &= ~ATTR_ARCHIVE; |
dep->de_Attributes &= ~ATTR_ARCHIVE; |
Line 438 msdosfs_setattr(void *v) |
|
Line 432 msdosfs_setattr(void *v) |
|
} |
} |
|
|
bad: |
bad: |
fstrans_done(vp->v_mount); |
|
return error; |
return error; |
} |
} |
|
|
Line 475 msdosfs_read(void *v) |
|
Line 468 msdosfs_read(void *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 499 msdosfs_read(void *v) |
|
Line 491 msdosfs_read(void *v) |
|
lbn = de_cluster(pmp, uio->uio_offset); |
lbn = de_cluster(pmp, uio->uio_offset); |
on = uio->uio_offset & pmp->pm_crbomask; |
on = uio->uio_offset & pmp->pm_crbomask; |
n = MIN(pmp->pm_bpcluster - on, uio->uio_resid); |
n = MIN(pmp->pm_bpcluster - on, uio->uio_resid); |
if (uio->uio_offset >= dep->de_FileSize) |
if (uio->uio_offset >= dep->de_FileSize) { |
return (0); |
return (0); |
|
} |
/* file size (and hence diff) may be up to 4GB */ |
/* file size (and hence diff) may be up to 4GB */ |
diff = dep->de_FileSize - uio->uio_offset; |
diff = dep->de_FileSize - uio->uio_offset; |
if (diff < n) |
if (diff < n) |
Line 517 msdosfs_read(void *v) |
|
Line 510 msdosfs_read(void *v) |
|
* vnode for the directory. |
* vnode for the directory. |
*/ |
*/ |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, lbn), blsize, |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, lbn), blsize, |
NOCRED, 0, &bp); |
0, &bp); |
n = MIN(n, pmp->pm_bpcluster - bp->b_resid); |
|
if (error) { |
if (error) { |
brelse(bp, 0); |
|
goto bad; |
goto bad; |
} |
} |
|
n = MIN(n, pmp->pm_bpcluster - bp->b_resid); |
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); |
} while (error == 0 && uio->uio_resid > 0 && n != 0); |
} while (error == 0 && uio->uio_resid > 0 && n != 0); |
|
|
out: |
out: |
if ((ap->a_ioflag & IO_SYNC) == IO_SYNC) |
if ((ap->a_ioflag & IO_SYNC) == IO_SYNC) { |
error = deupdat(dep, 1); |
int uerror; |
|
|
|
uerror = deupdat(dep, 1); |
|
if (error == 0) |
|
error = uerror; |
|
} |
bad: |
bad: |
fstrans_done(vp->v_mount); |
|
return (error); |
return (error); |
} |
} |
|
|
Line 590 msdosfs_write(void *v) |
|
Line 586 msdosfs_write(void *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 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 599 msdosfs_write(void *v) |
|
Line 594 msdosfs_write(void *v) |
|
*/ |
*/ |
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 627 msdosfs_write(void *v) |
|
Line 621 msdosfs_write(void *v) |
|
/* zero out the remainder of the last page */ |
/* zero out the remainder of the last page */ |
rem = round_page(dep->de_FileSize) - dep->de_FileSize; |
rem = round_page(dep->de_FileSize) - dep->de_FileSize; |
if (rem > 0) |
if (rem > 0) |
uvm_vnp_zerorange(vp, (off_t)dep->de_FileSize, rem); |
ubc_zerorange(&vp->v_uobj, (off_t)dep->de_FileSize, |
|
rem, UBC_UNMAP_FLAG(vp)); |
extended = 1; |
extended = 1; |
} |
} |
|
|
Line 648 msdosfs_write(void *v) |
|
Line 643 msdosfs_write(void *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 | PGO_LAZY); |
} |
} |
} while (error == 0 && uio->uio_resid > 0); |
} while (error == 0 && uio->uio_resid > 0); |
|
|
|
|
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 729 msdosfs_remove(void *v) |
|
Line 724 msdosfs_remove(void *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 746 msdosfs_remove(void *v) |
|
Line 740 msdosfs_remove(void *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); |
} |
} |
|
|
|
|
} |
} |
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. |
|
|
* 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; |
} |
} |
|
|
|
|
VOP_UNLOCK(fdvp); |
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) { |
|
|
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; |
} |
} |
VOP_UNLOCK(fdvp); |
VOP_UNLOCK(fdvp); |
|
|
} |
} |
cache_purge(fvp); |
cache_purge(fvp); |
if (!doingdirectory) { |
if (!doingdirectory) { |
|
struct denode_key old_key = ip->de_key; |
|
struct denode_key new_key = ip->de_key; |
|
|
error = pcbmap(dp, de_cluster(pmp, to_diroffset), 0, |
error = pcbmap(dp, de_cluster(pmp, to_diroffset), 0, |
&ip->de_dirclust, 0); |
&new_key.dk_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); |
VOP_UNLOCK(fvp); |
goto bad; |
goto bad; |
} |
} |
ip->de_diroffset = to_diroffset; |
new_key.dk_diroffset = to_diroffset; |
if (ip->de_dirclust != MSDOSFSROOT) |
if (new_key.dk_dirclust != MSDOSFSROOT) |
ip->de_diroffset &= pmp->pm_crbomask; |
new_key.dk_diroffset &= pmp->pm_crbomask; |
|
vcache_rekey_enter(pmp->pm_mountp, fvp, &old_key, |
|
sizeof(old_key), &new_key, sizeof(new_key)); |
|
ip->de_key = new_key; |
|
vcache_rekey_exit(pmp->pm_mountp, fvp, &old_key, |
|
sizeof(old_key), &ip->de_key, sizeof(ip->de_key)); |
} |
} |
reinsert(ip); |
|
} |
} |
|
|
/* |
/* |
|
|
} else |
} else |
bn = cntobn(pmp, cn); |
bn = cntobn(pmp, cn); |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), |
pmp->pm_bpcluster, NOCRED, B_MODIFY, &bp); |
pmp->pm_bpcluster, B_MODIFY, &bp); |
if (error) { |
if (error) { |
/* XXX should really panic here, fs is corrupt */ |
/* XXX should really panic here, fs is corrupt */ |
brelse(bp, 0); |
|
VOP_UNLOCK(fvp); |
VOP_UNLOCK(fvp); |
goto bad; |
goto bad; |
} |
} |
|
|
ip->de_flag &= ~DE_RENAME; |
ip->de_flag &= ~DE_RENAME; |
vrele(fdvp); |
vrele(fdvp); |
vrele(fvp); |
vrele(fvp); |
fstrans_done(fdvp->v_mount); |
|
return (error); |
return (error); |
|
|
/* XXX: uuuh */ |
/* XXX: uuuh */ |
Line 1160 static const struct { |
|
Line 1154 static const struct { |
|
int |
int |
msdosfs_mkdir(void *v) |
msdosfs_mkdir(void *v) |
{ |
{ |
struct vop_mkdir_args /* { |
struct vop_mkdir_v3_args /* { |
struct vnode *a_dvp; |
struct vnode *a_dvp; |
struvt vnode **a_vpp; |
struvt vnode **a_vpp; |
struvt componentname *a_cnp; |
struvt componentname *a_cnp; |
Line 1179 msdosfs_mkdir(void *v) |
|
Line 1173 msdosfs_mkdir(void *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 1261 msdosfs_mkdir(void *v) |
|
Line 1254 msdosfs_mkdir(void *v) |
|
if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0) |
if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0) |
goto bad; |
goto bad; |
VN_KNOTE(ap->a_dvp, NOTE_WRITE | NOTE_LINK); |
VN_KNOTE(ap->a_dvp, NOTE_WRITE | NOTE_LINK); |
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: |
vput(ap->a_dvp); |
|
fstrans_done(ap->a_dvp->v_mount); |
|
return (error); |
return (error); |
} |
} |
|
|
Line 1298 msdosfs_rmdir(void *v) |
|
Line 1287 msdosfs_rmdir(void *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 |
|
|
if (dvp) |
if (dvp) |
vput(dvp); |
vput(dvp); |
vput(vp); |
vput(vp); |
fstrans_done(ap->a_dvp->v_mount); |
|
return (error); |
return (error); |
} |
} |
|
|
Line 1377 msdosfs_readdir(void *v) |
|
Line 1364 msdosfs_readdir(void *v) |
|
int ncookies = 0, nc = 0; |
int ncookies = 0, nc = 0; |
off_t offset, uio_off; |
off_t offset, uio_off; |
int chksum = -1; |
int chksum = -1; |
|
uint16_t namlen; |
|
|
#ifdef MSDOSFS_DEBUG |
#ifdef MSDOSFS_DEBUG |
printf("msdosfs_readdir(): vp %p, uio %p, cred %p, eofflagp %p\n", |
printf("msdosfs_readdir(): vp %p, uio %p, cred %p, eofflagp %p\n", |
Line 1406 msdosfs_readdir(void *v) |
|
Line 1394 msdosfs_readdir(void *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 1484 msdosfs_readdir(void *v) |
|
Line 1471 msdosfs_readdir(void *v) |
|
if ((error = pcbmap(dep, lbn, &bn, &cn, &blsize)) != 0) |
if ((error = pcbmap(dep, lbn, &bn, &cn, &blsize)) != 0) |
break; |
break; |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, |
NOCRED, 0, &bp); |
0, &bp); |
if (error) { |
if (error) { |
brelse(bp, 0); |
|
goto bad; |
goto bad; |
} |
} |
n = MIN(n, blsize - bp->b_resid); |
n = MIN(n, blsize - bp->b_resid); |
Line 1525 msdosfs_readdir(void *v) |
|
Line 1511 msdosfs_readdir(void *v) |
|
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME) |
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME) |
continue; |
continue; |
chksum = win2unixfn((struct winentry *)dentp, |
chksum = win2unixfn((struct winentry *)dentp, |
dirbuf, chksum); |
dirbuf, chksum, &namlen, |
|
pmp->pm_flags & MSDOSFSMNT_UTF8); |
|
if (chksum != -1) |
|
dirbuf->d_namlen = namlen; |
continue; |
continue; |
} |
} |
|
|
Line 1568 msdosfs_readdir(void *v) |
|
Line 1557 msdosfs_readdir(void *v) |
|
pmp->pm_flags & MSDOSFSMNT_SHORTNAME); |
pmp->pm_flags & MSDOSFSMNT_SHORTNAME); |
else |
else |
dirbuf->d_name[dirbuf->d_namlen] = 0; |
dirbuf->d_name[dirbuf->d_namlen] = 0; |
|
namlen = dirbuf->d_namlen; |
chksum = -1; |
chksum = -1; |
dirbuf->d_reclen = _DIRENT_SIZE(dirbuf); |
dirbuf->d_reclen = _DIRENT_SIZE(dirbuf); |
if (uio->uio_resid < dirbuf->d_reclen) { |
if (uio->uio_resid < dirbuf->d_reclen) { |
|
|
|
|
bad: |
bad: |
free(dirbuf, M_MSDOSFSTMP); |
free(dirbuf, M_MSDOSFSTMP); |
fstrans_done(ap->a_vp->v_mount); |
|
return (error); |
return (error); |
} |
} |
|
|
Line 1770 msdosfs_pathconf(void *v) |
|
Line 1759 msdosfs_pathconf(void *v) |
|
*ap->a_retval = 1; |
*ap->a_retval = 1; |
return (0); |
return (0); |
case _PC_NO_TRUNC: |
case _PC_NO_TRUNC: |
*ap->a_retval = 0; |
*ap->a_retval = 1; |
return (0); |
return (0); |
case _PC_SYNC_IO: |
case _PC_SYNC_IO: |
*ap->a_retval = 1; |
*ap->a_retval = 1; |
Line 1798 msdosfs_fsync(void *v) |
|
Line 1787 msdosfs_fsync(void *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; |
error = vflushbuf(vp, wait); |
error = vflushbuf(vp, ap->a_flags); |
if (error == 0 && (ap->a_flags & FSYNC_DATAONLY) == 0) |
if (error == 0 && (ap->a_flags & FSYNC_DATAONLY) == 0) |
error = msdosfs_update(vp, NULL, NULL, wait ? UPDATE_WAIT : 0); |
error = msdosfs_update(vp, NULL, NULL, wait ? UPDATE_WAIT : 0); |
|
|
Line 1812 msdosfs_fsync(void *v) |
|
Line 1800 msdosfs_fsync(void *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 1867 const struct vnodeopv_entry_desc msdosfs |
|
Line 1854 const struct vnodeopv_entry_desc msdosfs |
|
{ &vop_setattr_desc, msdosfs_setattr }, /* setattr */ |
{ &vop_setattr_desc, msdosfs_setattr }, /* setattr */ |
{ &vop_read_desc, msdosfs_read }, /* read */ |
{ &vop_read_desc, msdosfs_read }, /* read */ |
{ &vop_write_desc, msdosfs_write }, /* write */ |
{ &vop_write_desc, msdosfs_write }, /* write */ |
|
{ &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ |
|
{ &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ |
{ &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ |
{ &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ |
{ &vop_ioctl_desc, msdosfs_ioctl }, /* ioctl */ |
{ &vop_ioctl_desc, msdosfs_ioctl }, /* ioctl */ |
{ &vop_poll_desc, msdosfs_poll }, /* poll */ |
{ &vop_poll_desc, msdosfs_poll }, /* poll */ |