- Remove the unused and not completed write support for NTFS.
- Fix a bug where vfs_mountedfrom() is called also when the filesystem is not mounted successfully. Tested by: pho
This commit is contained in:
parent
6b825e43a0
commit
c7ea063227
@ -1352,174 +1352,6 @@ ntfs_filesize(
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is one of write routine.
|
||||
*/
|
||||
int
|
||||
ntfs_writeattr_plain(
|
||||
struct ntfsmount * ntmp,
|
||||
struct ntnode * ip,
|
||||
u_int32_t attrnum,
|
||||
char *attrname,
|
||||
off_t roff,
|
||||
size_t rsize,
|
||||
void *rdata,
|
||||
size_t * initp,
|
||||
struct uio *uio)
|
||||
{
|
||||
size_t init;
|
||||
int error = 0;
|
||||
off_t off = roff, left = rsize, towrite;
|
||||
caddr_t data = rdata;
|
||||
struct ntvattr *vap;
|
||||
*initp = 0;
|
||||
|
||||
while (left) {
|
||||
error = ntfs_ntvattrget(ntmp, ip, attrnum, attrname,
|
||||
ntfs_btocn(off), &vap);
|
||||
if (error)
|
||||
return (error);
|
||||
towrite = MIN(left, ntfs_cntob(vap->va_vcnend + 1) - off);
|
||||
ddprintf(("ntfs_writeattr_plain: o: %d, s: %d (%d - %d)\n",
|
||||
(u_int32_t) off, (u_int32_t) towrite,
|
||||
(u_int32_t) vap->va_vcnstart,
|
||||
(u_int32_t) vap->va_vcnend));
|
||||
error = ntfs_writentvattr_plain(ntmp, ip, vap,
|
||||
off - ntfs_cntob(vap->va_vcnstart),
|
||||
towrite, data, &init, uio);
|
||||
if (error) {
|
||||
printf("ntfs_writeattr_plain: " \
|
||||
"ntfs_writentvattr_plain failed: o: %d, s: %d\n",
|
||||
(u_int32_t) off, (u_int32_t) towrite);
|
||||
printf("ntfs_writeattr_plain: attrib: %d - %d\n",
|
||||
(u_int32_t) vap->va_vcnstart,
|
||||
(u_int32_t) vap->va_vcnend);
|
||||
ntfs_ntvattrrele(vap);
|
||||
break;
|
||||
}
|
||||
ntfs_ntvattrrele(vap);
|
||||
left -= towrite;
|
||||
off += towrite;
|
||||
data = data + towrite;
|
||||
*initp += init;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is one of write routine.
|
||||
*
|
||||
* ntnode should be locked.
|
||||
*/
|
||||
int
|
||||
ntfs_writentvattr_plain(
|
||||
struct ntfsmount * ntmp,
|
||||
struct ntnode * ip,
|
||||
struct ntvattr * vap,
|
||||
off_t roff,
|
||||
size_t rsize,
|
||||
void *rdata,
|
||||
size_t * initp,
|
||||
struct uio *uio)
|
||||
{
|
||||
int error = 0;
|
||||
off_t off;
|
||||
int cnt;
|
||||
cn_t ccn, ccl, cn, left, cl;
|
||||
caddr_t data = rdata;
|
||||
struct buf *bp;
|
||||
size_t tocopy;
|
||||
|
||||
*initp = 0;
|
||||
|
||||
if ((vap->va_flag & NTFS_AF_INRUN) == 0) {
|
||||
printf("ntfs_writevattr_plain: CAN'T WRITE RES. ATTRIBUTE\n");
|
||||
return ENOTTY;
|
||||
}
|
||||
|
||||
ddprintf(("ntfs_writentvattr_plain: data in run: %ld chains\n",
|
||||
vap->va_vruncnt));
|
||||
|
||||
off = roff;
|
||||
left = rsize;
|
||||
ccl = 0;
|
||||
ccn = 0;
|
||||
cnt = 0;
|
||||
for (; left && (cnt < vap->va_vruncnt); cnt++) {
|
||||
ccn = vap->va_vruncn[cnt];
|
||||
ccl = vap->va_vruncl[cnt];
|
||||
|
||||
ddprintf(("ntfs_writentvattr_plain: " \
|
||||
"left %d, cn: 0x%x, cl: %d, off: %d\n", \
|
||||
(u_int32_t) left, (u_int32_t) ccn, \
|
||||
(u_int32_t) ccl, (u_int32_t) off));
|
||||
|
||||
if (ntfs_cntob(ccl) < off) {
|
||||
off -= ntfs_cntob(ccl);
|
||||
cnt++;
|
||||
continue;
|
||||
}
|
||||
if (!ccn && ip->i_number != NTFS_BOOTINO)
|
||||
continue; /* XXX */
|
||||
|
||||
ccl -= ntfs_btocn(off);
|
||||
cn = ccn + ntfs_btocn(off);
|
||||
off = ntfs_btocnoff(off);
|
||||
|
||||
while (left && ccl) {
|
||||
/*
|
||||
* Always read and write single clusters at a time -
|
||||
* we need to avoid requesting differently-sized
|
||||
* blocks at the same disk offsets to avoid
|
||||
* confusing the buffer cache.
|
||||
*/
|
||||
tocopy = MIN(left, ntfs_cntob(1) - off);
|
||||
cl = ntfs_btocl(tocopy + off);
|
||||
KASSERT(cl == 1 && tocopy <= ntfs_cntob(1),
|
||||
("single cluster limit mistake"));
|
||||
ddprintf(("ntfs_writentvattr_plain: write: " \
|
||||
"cn: 0x%x cl: %d, off: %d len: %d, left: %d\n",
|
||||
(u_int32_t) cn, (u_int32_t) cl,
|
||||
(u_int32_t) off, (u_int32_t) tocopy,
|
||||
(u_int32_t) left));
|
||||
if ((off == 0) && (tocopy == ntfs_cntob(cl)))
|
||||
{
|
||||
bp = getblk(ntmp->ntm_devvp, ntfs_cntobn(cn)
|
||||
* ntmp->ntm_multiplier,
|
||||
ntfs_cntob(cl), 0, 0, 0);
|
||||
clrbuf(bp);
|
||||
} else {
|
||||
error = bread(ntmp->ntm_devvp, ntfs_cntobn(cn)
|
||||
* ntmp->ntm_multiplier,
|
||||
ntfs_cntob(cl), NOCRED, &bp);
|
||||
if (error) {
|
||||
brelse(bp);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
if (uio)
|
||||
uiomove(bp->b_data + off, tocopy, uio);
|
||||
else
|
||||
memcpy(bp->b_data + off, data, tocopy);
|
||||
bawrite(bp);
|
||||
data = data + tocopy;
|
||||
*initp += tocopy;
|
||||
off = 0;
|
||||
left -= tocopy;
|
||||
cn += cl;
|
||||
ccl -= cl;
|
||||
}
|
||||
}
|
||||
|
||||
if (left) {
|
||||
printf("ntfs_writentvattr_plain: POSSIBLE RUN ERROR\n");
|
||||
error = EINVAL;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is one of read routines.
|
||||
*
|
||||
|
@ -99,8 +99,6 @@ void ntfs_ntref(struct ntnode *);
|
||||
void ntfs_ntrele(struct ntnode *);
|
||||
void ntfs_ntput(struct ntnode *);
|
||||
int ntfs_loadntnode( struct ntfsmount *, struct ntnode * );
|
||||
int ntfs_writentvattr_plain(struct ntfsmount *, struct ntnode *, struct ntvattr *, off_t, size_t, void *, size_t *, struct uio *);
|
||||
int ntfs_writeattr_plain(struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *, size_t *, struct uio *);
|
||||
void ntfs_toupper_init(void);
|
||||
void ntfs_toupper_destroy(void);
|
||||
int ntfs_toupper_use(struct mount *, struct ntfsmount *);
|
||||
|
@ -152,7 +152,6 @@ static int
|
||||
ntfs_mount(struct mount *mp)
|
||||
{
|
||||
int err = 0, error;
|
||||
accmode_t accmode;
|
||||
struct vnode *devvp;
|
||||
struct nameidata ndp;
|
||||
struct thread *td;
|
||||
@ -162,6 +161,11 @@ ntfs_mount(struct mount *mp)
|
||||
if (vfs_filteropt(mp->mnt_optnew, ntfs_opts))
|
||||
return (EINVAL);
|
||||
|
||||
/* Force mount as read-only. */
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_RDONLY;
|
||||
MNT_IUNLOCK(mp);
|
||||
|
||||
from = vfs_getopts(mp->mnt_optnew, "from", &error);
|
||||
if (error)
|
||||
return (error);
|
||||
@ -173,11 +177,10 @@ ntfs_mount(struct mount *mp)
|
||||
if (mp->mnt_flag & MNT_UPDATE) {
|
||||
if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) {
|
||||
/* Process export requests in vfs_mount.c */
|
||||
goto success;
|
||||
return (0);
|
||||
} else {
|
||||
printf("ntfs_mount(): MNT_UPDATE not supported\n");
|
||||
err = EINVAL;
|
||||
goto error_1;
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,10 +190,8 @@ ntfs_mount(struct mount *mp)
|
||||
*/
|
||||
NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, from, td);
|
||||
err = namei(&ndp);
|
||||
if (err) {
|
||||
/* can't get devvp!*/
|
||||
goto error_1;
|
||||
}
|
||||
if (err)
|
||||
return (err);
|
||||
NDFREE(&ndp, NDF_ONLY_PNBUF);
|
||||
devvp = ndp.ni_vp;
|
||||
|
||||
@ -203,10 +204,7 @@ ntfs_mount(struct mount *mp)
|
||||
* If mount by non-root, then verify that user has necessary
|
||||
* permissions on the device.
|
||||
*/
|
||||
accmode = VREAD;
|
||||
if ((mp->mnt_flag & MNT_RDONLY) == 0)
|
||||
accmode |= VWRITE;
|
||||
err = VOP_ACCESS(devvp, accmode, td->td_ucred, td);
|
||||
err = VOP_ACCESS(devvp, VREAD, td->td_ucred, td);
|
||||
if (err)
|
||||
err = priv_check(td, PRIV_VFS_MOUNT_PERM);
|
||||
if (err) {
|
||||
@ -244,22 +242,16 @@ ntfs_mount(struct mount *mp)
|
||||
* don't have to do it here unless we want to set it
|
||||
* to something other than "path" for some rason.
|
||||
*/
|
||||
/* Save "mounted from" info for mount point (NULL pad)*/
|
||||
vfs_mountedfrom(mp, from);
|
||||
|
||||
err = ntfs_mountfs(devvp, mp, td);
|
||||
if (err == 0) {
|
||||
|
||||
/* Save "mounted from" info for mount point. */
|
||||
vfs_mountedfrom(mp, from);
|
||||
}
|
||||
}
|
||||
if (err) {
|
||||
if (err)
|
||||
vrele(devvp);
|
||||
return (err);
|
||||
}
|
||||
|
||||
goto success;
|
||||
|
||||
error_1: /* no state to back out*/
|
||||
/* XXX: missing NDFREE(&ndp, ...) */
|
||||
|
||||
success:
|
||||
return (err);
|
||||
}
|
||||
|
||||
@ -275,13 +267,12 @@ ntfs_mountfs(devvp, mp, td)
|
||||
struct buf *bp;
|
||||
struct ntfsmount *ntmp;
|
||||
struct cdev *dev = devvp->v_rdev;
|
||||
int error, ronly, i, v;
|
||||
int error, i, v;
|
||||
struct vnode *vp;
|
||||
struct g_consumer *cp;
|
||||
struct g_provider *pp;
|
||||
char *cs_ntfs, *cs_local;
|
||||
|
||||
ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
|
||||
DROP_GIANT();
|
||||
g_topology_lock();
|
||||
|
||||
@ -296,7 +287,7 @@ ntfs_mountfs(devvp, mp, td)
|
||||
if ((pp != NULL) && ((pp->acr | pp->acw | pp->ace ) != 0))
|
||||
error = EPERM;
|
||||
else
|
||||
error = g_vfs_open(devvp, &cp, "ntfs", ronly ? 0 : 1);
|
||||
error = g_vfs_open(devvp, &cp, "ntfs", 0);
|
||||
|
||||
g_topology_unlock();
|
||||
PICKUP_GIANT();
|
||||
|
@ -67,7 +67,6 @@
|
||||
#include <sys/unistd.h> /* for pathconf(2) constants */
|
||||
|
||||
static vop_read_t ntfs_read;
|
||||
static vop_write_t ntfs_write;
|
||||
static vop_getattr_t ntfs_getattr;
|
||||
static vop_inactive_t ntfs_inactive;
|
||||
static vop_reclaim_t ntfs_reclaim;
|
||||
@ -78,7 +77,6 @@ static vop_open_t ntfs_open;
|
||||
static vop_close_t ntfs_close;
|
||||
static vop_readdir_t ntfs_readdir;
|
||||
static vop_cachedlookup_t ntfs_lookup;
|
||||
static vop_fsync_t ntfs_fsync;
|
||||
static vop_pathconf_t ntfs_pathconf;
|
||||
static vop_vptofh_t ntfs_vptofh;
|
||||
|
||||
@ -272,6 +270,7 @@ ntfs_strategy(ap)
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
struct ntfsmount *ntmp = ip->i_mp;
|
||||
u_int32_t toread;
|
||||
int error;
|
||||
|
||||
dprintf(("ntfs_strategy: offset: %d, blkno: %d, lblkno: %d\n",
|
||||
@ -281,99 +280,33 @@ ntfs_strategy(ap)
|
||||
dprintf(("strategy: bcount: %d flags: 0x%x\n",
|
||||
(u_int32_t)bp->b_bcount,bp->b_flags));
|
||||
|
||||
if (bp->b_iocmd == BIO_READ) {
|
||||
u_int32_t toread;
|
||||
KASSERT(bp->b_iocmd == BIO_READ, ("Invalid buffer\n"));
|
||||
|
||||
if (ntfs_cntob(bp->b_blkno) >= fp->f_size) {
|
||||
clrbuf(bp);
|
||||
error = 0;
|
||||
} else {
|
||||
toread = MIN(bp->b_bcount,
|
||||
fp->f_size-ntfs_cntob(bp->b_blkno));
|
||||
dprintf(("ntfs_strategy: toread: %d, fsize: %d\n",
|
||||
toread,(u_int32_t)fp->f_size));
|
||||
|
||||
error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
|
||||
fp->f_attrname, ntfs_cntob(bp->b_blkno),
|
||||
toread, bp->b_data, NULL);
|
||||
|
||||
if (error) {
|
||||
printf("ntfs_strategy: ntfs_readattr failed\n");
|
||||
bp->b_error = error;
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
}
|
||||
|
||||
bzero(bp->b_data + toread, bp->b_bcount - toread);
|
||||
}
|
||||
if (ntfs_cntob(bp->b_blkno) >= fp->f_size) {
|
||||
clrbuf(bp);
|
||||
error = 0;
|
||||
} else {
|
||||
size_t tmp;
|
||||
u_int32_t towrite;
|
||||
toread = MIN(bp->b_bcount,
|
||||
fp->f_size-ntfs_cntob(bp->b_blkno));
|
||||
dprintf(("ntfs_strategy: toread: %d, fsize: %d\n",
|
||||
toread,(u_int32_t)fp->f_size));
|
||||
|
||||
if (ntfs_cntob(bp->b_blkno) + bp->b_bcount >= fp->f_size) {
|
||||
printf("ntfs_strategy: CAN'T EXTEND FILE\n");
|
||||
bp->b_error = error = EFBIG;
|
||||
error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
|
||||
fp->f_attrname, ntfs_cntob(bp->b_blkno),
|
||||
toread, bp->b_data, NULL);
|
||||
|
||||
if (error) {
|
||||
printf("ntfs_strategy: ntfs_readattr failed\n");
|
||||
bp->b_error = error;
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
} else {
|
||||
towrite = MIN(bp->b_bcount,
|
||||
fp->f_size-ntfs_cntob(bp->b_blkno));
|
||||
dprintf(("ntfs_strategy: towrite: %d, fsize: %d\n",
|
||||
towrite,(u_int32_t)fp->f_size));
|
||||
|
||||
error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype,
|
||||
fp->f_attrname, ntfs_cntob(bp->b_blkno),towrite,
|
||||
bp->b_data, &tmp, NULL);
|
||||
|
||||
if (error) {
|
||||
printf("ntfs_strategy: ntfs_writeattr fail\n");
|
||||
bp->b_error = error;
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
bzero(bp->b_data + toread, bp->b_bcount - toread);
|
||||
}
|
||||
bufdone(bp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ntfs_write(ap)
|
||||
struct vop_write_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct uio *a_uio;
|
||||
int a_ioflag;
|
||||
struct ucred *a_cred;
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct fnode *fp = VTOF(vp);
|
||||
register struct ntnode *ip = FTONT(fp);
|
||||
struct uio *uio = ap->a_uio;
|
||||
struct ntfsmount *ntmp = ip->i_mp;
|
||||
u_int64_t towrite;
|
||||
size_t written;
|
||||
int error;
|
||||
|
||||
dprintf(("ntfs_write: ino: %d, off: %d resid: %d, segflg: %d\n",ip->i_number,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg));
|
||||
dprintf(("ntfs_write: filesize: %d",(u_int32_t)fp->f_size));
|
||||
|
||||
if (uio->uio_resid + uio->uio_offset > fp->f_size) {
|
||||
printf("ntfs_write: CAN'T WRITE BEYOND END OF FILE\n");
|
||||
return (EFBIG);
|
||||
}
|
||||
|
||||
towrite = MIN(uio->uio_resid, fp->f_size - uio->uio_offset);
|
||||
|
||||
dprintf((", towrite: %d\n",(u_int32_t)towrite));
|
||||
|
||||
error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype,
|
||||
fp->f_attrname, uio->uio_offset, towrite, NULL, &written, uio);
|
||||
#ifdef NTFS_DEBUG
|
||||
if (error)
|
||||
printf("ntfs_write: ntfs_writeattr failed: %d\n", error);
|
||||
#endif
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
ntfs_access(ap)
|
||||
struct vop_access_args /* {
|
||||
@ -390,7 +323,7 @@ ntfs_access(ap)
|
||||
dprintf(("ntfs_access: %d\n",ip->i_number));
|
||||
|
||||
/*
|
||||
* Disallow write attempts on read-only filesystems;
|
||||
* Disallow write attempts as we assume read-only filesystems;
|
||||
* unless the file is a socket, fifo, or a block or
|
||||
* character device resident on the filesystem.
|
||||
*/
|
||||
@ -399,8 +332,8 @@ ntfs_access(ap)
|
||||
case VDIR:
|
||||
case VLNK:
|
||||
case VREG:
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
return (EROFS);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -630,7 +563,6 @@ ntfs_lookup(ap)
|
||||
return (error);
|
||||
|
||||
if ((cnp->cn_flags & ISLASTCN) &&
|
||||
(dvp->v_mount->mnt_flag & MNT_RDONLY) &&
|
||||
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
|
||||
return (EROFS);
|
||||
|
||||
@ -678,24 +610,6 @@ ntfs_lookup(ap)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the blocks of a file to disk.
|
||||
*
|
||||
* This function is worthless for vnodes that represent directories. Maybe we
|
||||
* could just do a sync if they try an fsync on a directory file.
|
||||
*/
|
||||
static int
|
||||
ntfs_fsync(ap)
|
||||
struct vop_fsync_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct ucred *a_cred;
|
||||
int a_waitfor;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return POSIX pathconf information applicable to NTFS filesystem
|
||||
*/
|
||||
@ -756,7 +670,6 @@ struct vop_vector ntfs_vnodeops = {
|
||||
.vop_bmap = ntfs_bmap,
|
||||
.vop_cachedlookup = ntfs_lookup,
|
||||
.vop_close = ntfs_close,
|
||||
.vop_fsync = ntfs_fsync,
|
||||
.vop_getattr = ntfs_getattr,
|
||||
.vop_inactive = ntfs_inactive,
|
||||
.vop_lookup = vfs_cache_lookup,
|
||||
@ -766,6 +679,5 @@ struct vop_vector ntfs_vnodeops = {
|
||||
.vop_readdir = ntfs_readdir,
|
||||
.vop_reclaim = ntfs_reclaim,
|
||||
.vop_strategy = ntfs_strategy,
|
||||
.vop_write = ntfs_write,
|
||||
.vop_vptofh = ntfs_vptofh,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user