PERFORCE change 195925 for review
Ilya Putsikau
ilya at FreeBSD.org
Sat Jul 9 08:59:31 UTC 2011
http://p4web.freebsd.org/@@195925?ac=10
Change 195925 by ilya at ilya_triton2011 on 2011/07/09 08:59:09
Rewrite fuse_io_strategy to be similar to NFS.
Set iosize to PAGE_SIZE (was MAXBSIZE)
Set file size in fuse_write_directbackend
Refresh file size before write
Remove fuse_std_buffeater
Affected files ...
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.h#17 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.c#16 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.h#9 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.c#15 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.h#15 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vfsops.c#20 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#37 edit
Differences ...
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.h#17 (text+ko) ====
@@ -130,6 +130,13 @@
return fuse_isdeadfs_mp(vnode_mount(vp));
}
+static __inline__
+int
+fuse_iosize(struct vnode *vp)
+{
+ return vp->v_mount->mnt_stat.f_iosize;
+}
+
/* access */
#define FVP_ACCESS_NOOP 0x01
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.c#16 (text+ko) ====
@@ -38,27 +38,32 @@
#include "fuse.h"
#include "fuse_file.h"
#include "fuse_node.h"
+#include "fuse_internal.h"
#include "fuse_ipc.h"
#include "fuse_io.h"
#define FUSE_DEBUG_MODULE IO
#include "fuse_debug.h"
-static int fuse_read_directbackend(struct fuse_io_data *fioda);
-static int fuse_read_biobackend(struct fuse_io_data *fioda);
-static int fuse_write_directbackend(struct fuse_io_data *fioda);
-static int fuse_write_biobackend(struct fuse_io_data *fioda);
-static fuse_buffeater_t fuse_std_buffeater;
+static int fuse_read_directbackend(struct vnode *vp, struct uio *uio,
+ struct ucred *cred, struct fuse_filehandle *fufh);
+static int fuse_read_biobackend(struct vnode *vp, struct uio *uio,
+ struct ucred *cred, struct fuse_filehandle *fufh);
+static int fuse_write_directbackend(struct vnode *vp, struct uio *uio,
+ struct ucred *cred, struct fuse_filehandle *fufh);
+static int fuse_write_biobackend(struct vnode *vp, struct uio *uio,
+ struct ucred *cred, struct fuse_filehandle *fufh);
int
fuse_io_dispatch(struct vnode *vp, struct uio *uio, int ioflag,
struct ucred *cred)
{
struct fuse_filehandle *fufh;
- struct fuse_io_data fioda;
int err, directio;
+ MPASS(vp->v_type == VREG);
+
err = fuse_filehandle_getrw(vp,
(uio->uio_rw == UIO_READ) ? FUFH_RDONLY : FUFH_WRONLY, &fufh);
if (err) {
@@ -66,13 +71,6 @@
return err;
}
- bzero(&fioda, sizeof(fioda));
- fioda.vp = vp;
- fioda.fufh = fufh;
- fioda.uio = uio;
- fioda.cred = cred;
- fioda.td = curthread;
-
/*
* Ideally, when the daemon asks for direct io at open time, the
* standard file flag should be set according to this, so that would
@@ -87,26 +85,23 @@
switch (uio->uio_rw) {
case UIO_READ:
- fioda.opcode = FUSE_READ;
- fioda.buffeater = fuse_std_buffeater;
-
if (directio) {
DEBUG("direct read of vnode %ju via file handle %ju\n",
(uintmax_t)VTOILLU(vp), (uintmax_t)fufh->fh_id);
- err = fuse_read_directbackend(&fioda);
+ err = fuse_read_directbackend(vp, uio, cred, fufh);
} else {
DEBUG("buffered read of vnode %ju\n", (uintmax_t)VTOILLU(vp));
- err = fuse_read_biobackend(&fioda);
+ err = fuse_read_biobackend(vp, uio, cred, fufh);
}
break;
case UIO_WRITE:
if (directio) {
DEBUG("direct write of vnode %ju via file handle %ju\n",
(uintmax_t)VTOILLU(vp), (uintmax_t)fufh->fh_id);
- err = fuse_write_directbackend(&fioda);
+ err = fuse_write_directbackend(vp, uio, cred, fufh);
} else {
DEBUG("buffered write of vnode %ju\n", (uintmax_t)VTOILLU(vp));
- err = fuse_write_biobackend(&fioda);
+ err = fuse_write_biobackend(vp, uio, cred, fufh);
}
break;
default:
@@ -119,30 +114,28 @@
}
static int
-fuse_read_biobackend(struct fuse_io_data *fioda)
+fuse_read_biobackend(struct vnode *vp, struct uio *uio,
+ struct ucred *cred, struct fuse_filehandle *fufh)
{
-
- struct vnode *vp = fioda->vp;
- struct fuse_filehandle *fufh = fioda->fufh;
- struct uio *uio = fioda->uio;
- enum fuse_opcode op = fioda->opcode;
- fuse_buffeater_t *buffe = fioda->buffeater;
- void *param = fioda->param;
-
- int biosize;
struct buf *bp;
daddr_t lbn;
int bcount;
- int bbcount;
int err = 0, n = 0, on = 0;
+ off_t filesize;
+
+ const int biosize = fuse_iosize(vp);
+
+ DEBUG("resid=%zx offset=%jx fsize=%jx\n",
+ uio->uio_resid, uio->uio_offset, VTOFUD(vp)->filesize);
if (uio->uio_resid == 0)
return (0);
+ if (uio->uio_offset < 0)
+ return (EINVAL);
- biosize = vp->v_mount->mnt_stat.f_iosize;
bcount = MIN(MAXBSIZE, biosize);
+ filesize = VTOFUD(vp)->filesize;
- DEBUG2G("entering loop\n");
do {
lbn = uio->uio_offset / biosize;
on = uio->uio_offset & (biosize - 1);
@@ -160,6 +153,11 @@
*
* Note that bcount is *not* DEV_BSIZE aligned.
*/
+ if ((off_t)lbn * biosize >= filesize) {
+ bcount = 0;
+ } else if ((off_t)(lbn + 1) * biosize > filesize) {
+ bcount = filesize - (off_t)lbn * biosize;
+ }
bp = getblk(vp, lbn, bcount, PCATCH, 0, 0);
@@ -174,7 +172,7 @@
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
- err = fuse_io_strategy(vp, bp, fufh, op);
+ err = fuse_io_strategy(vp, bp);
if (err) {
brelse(bp);
return (err);
@@ -190,43 +188,25 @@
*/
n = 0;
- /*
- * If we zero pad the buf, bp->b_resid will be 0, so then
- * just ignore it
- */
- bbcount = bcount - bp->b_resid;
- if (on < bbcount)
- n = bbcount - on;
+ if (on < bcount)
+ n = MIN((unsigned)(bcount - on), uio->uio_resid);
if (n > 0) {
DEBUG2G("feeding buffeater with %d bytes of buffer %p, saying %d was asked for\n",
n, bp->b_data + on, n + (int)bp->b_resid);
-#if 0 && _DEBUG
- prettyprint(bp->b_data + on, n);
- printf("\n");
-#endif
- err = buffe(uio, n + bp->b_resid, bp->b_data + on, n,
- param);
+ err = uiomove(bp->b_data + on, n, uio);
}
brelse(bp);
DEBUG2G("end of turn, err %d, uio->uio_resid %zd, n %d\n",
err, uio->uio_resid, n);
} while (err == 0 && uio->uio_resid > 0 && n > 0);
- return ((err == -1) ? 0 : err);
+ return (err);
}
static int
-fuse_read_directbackend(struct fuse_io_data *fioda)
+fuse_read_directbackend(struct vnode *vp, struct uio *uio,
+ struct ucred *cred, struct fuse_filehandle *fufh)
{
- struct vnode *vp = fioda->vp;
- struct fuse_filehandle *fufh = fioda->fufh;
- struct uio *uio = fioda->uio;
- struct ucred *cred = fioda->cred;
- struct thread *td = fioda->td;
- enum fuse_opcode op = fioda->opcode;
- fuse_buffeater_t *buffe = fioda->buffeater;
- void *param = fioda->param;
-
struct fuse_dispatcher fdi;
struct fuse_read_in *fri;
int err = 0;
@@ -234,8 +214,6 @@
if (uio->uio_resid == 0)
return (0);
- DEBUG("bug daemon for food\n");
-
fdisp_init(&fdi, 0);
/*
@@ -248,7 +226,7 @@
*/
while (uio->uio_resid > 0) {
fdi.iosize = sizeof(*fri);
- fdisp_make_vp(&fdi, op, vp, td, cred);
+ fdisp_make_vp(&fdi, FUSE_READ, vp, uio->uio_td, cred);
fri = fdi.indata;
fri->fh = fufh->fh_id;
fri->offset = uio->uio_offset;
@@ -260,48 +238,31 @@
if ((err = fdisp_wait_answ(&fdi)))
goto out;
- DEBUG2G("%zd bytes asked for from offset %ju, passing on the %jd we got\n",
- uio->uio_resid, (uintmax_t)uio->uio_offset, (uintmax_t)fdi.iosize);
+ DEBUG2G("complete: got iosize=%d, requested fri.size=%zd; "
+ "resid=%zd offset=%ju\n",
+ fri->size, fdi.iosize, uio->uio_resid, (uintmax_t)uio->uio_offset);
- if ((err = buffe(uio, fri->size, fdi.answ, fdi.iosize, param)))
+ if ((err = uiomove(fdi.answ, MIN(fri->size, fdi.iosize), uio)))
break;
+ if (fdi.iosize < fri->size)
+ break;
}
fuse_ticket_drop(fdi.tick);
out:
- return ((err == -1) ? 0 : err);
+ return (err);
}
-/* Simple standard way for transmitting input */
static int
-fuse_std_buffeater(struct uio *uio, size_t reqsize, void *buf, size_t bufsize, void *param)
-{
- int err;
-
- if ((err = uiomove(buf, MIN(reqsize, bufsize), uio)))
- return (err);
-
- if (bufsize < reqsize)
- return (-1);
-
- return (0);
-}
-
-
-static int
-fuse_write_directbackend(struct fuse_io_data *fioda)
+fuse_write_directbackend(struct vnode *vp, struct uio *uio,
+ struct ucred *cred, struct fuse_filehandle *fufh)
{
- struct vnode *vp = fioda->vp;
- uint64_t fh_id = fioda->fufh->fh_id;
- struct uio *uio = fioda->uio;
- struct ucred *cred = fioda->cred;
- struct thread *td = fioda->td;
-
+ struct fuse_vnode_data *fvdat = VTOFUD(vp);
+ struct fuse_write_in *fwi;
+ struct fuse_dispatcher fdi;
size_t chunksize;
int diff;
- struct fuse_write_in *fwi;
- struct fuse_dispatcher fdi;
int err = 0;
if (! uio->uio_resid)
@@ -314,10 +275,10 @@
fuse_get_mpdata(vp->v_mount)->max_write);
fdi.iosize = sizeof(*fwi) + chunksize;
- fdisp_make_vp(&fdi, FUSE_WRITE, vp, td, cred);
+ fdisp_make_vp(&fdi, FUSE_WRITE, vp, uio->uio_td, cred);
fwi = fdi.indata;
- fwi->fh = fh_id;
+ fwi->fh = fufh->fh_id;
fwi->offset = uio->uio_offset;
fwi->size = chunksize;
@@ -336,6 +297,8 @@
uio->uio_resid += diff;
uio->uio_offset -= diff;
+ if (uio->uio_offset > fvdat->filesize)
+ fuse_vnode_setsize(vp, uio->uio_offset);
}
fuse_ticket_drop(fdi.tick);
@@ -344,23 +307,26 @@
}
static int
-fuse_write_biobackend(struct fuse_io_data *fioda)
+fuse_write_biobackend(struct vnode *vp, struct uio *uio,
+ struct ucred *cred, struct fuse_filehandle *fufh)
{
- struct vnode *vp = fioda->vp;
- struct uio *uio = fioda->uio;
- struct ucred *cred = fioda->cred;
struct fuse_vnode_data *fvdat = VTOFUD(vp);
-
- int biosize;
-
struct buf *bp;
daddr_t lbn;
int bcount;
int n, on, err = 0;
- DEBUG2G("fsize %ju\n", (uintmax_t)fvdat->filesize);
+ const int biosize = fuse_iosize(vp);
- biosize = vp->v_mount->mnt_stat.f_iosize;
+ KASSERT(uio->uio_rw == UIO_WRITE, ("ncl_write mode"));
+ DEBUG("resid=%zx offset=%jx fsize=%jx\n",
+ uio->uio_resid, uio->uio_offset, fvdat->filesize);
+ if (vp->v_type != VREG)
+ return (EIO);
+ if (uio->uio_offset < 0)
+ return (EINVAL);
+ if (uio->uio_resid == 0)
+ return (0);
/*
* Find all of this file's B_NEEDCOMMIT buffers. If our writes
@@ -383,7 +349,6 @@
* Handle direct append and file extension cases, calculate
* unaligned buffer size.
*/
-
if (uio->uio_offset == fvdat->filesize && n) {
/*
* Get the buffer (in its pre-append state to maintain
@@ -457,7 +422,7 @@
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
- fuse_io_strategy(vp, bp, NULL, 0);
+ fuse_io_strategy(vp, bp);
if ((err = bp->b_error)) {
brelse(bp);
break;
@@ -476,7 +441,7 @@
*/
if (bp->b_dirtyend > bcount) {
- DEBUG("Fuse append race @%lx:%d\n",
+ DEBUG("FUSE append race @%lx:%d\n",
(long)bp->b_blkno * biosize,
bp->b_dirtyend - bcount);
bp->b_dirtyend = bcount;
@@ -550,8 +515,8 @@
vfs_bio_set_valid(bp, on, n);
}
- bwrite(bp);
- if ((err = bp->b_error))
+ err = bwrite(bp);
+ if (err)
break;
} while (uio->uio_resid > 0 && n > 0);
@@ -559,31 +524,42 @@
}
int
-fuse_io_strategy(struct vnode *vp, struct buf *bp, struct fuse_filehandle *fufh,
- enum fuse_opcode op)
+fuse_io_strategy(struct vnode *vp, struct buf *bp)
{
+ struct fuse_filehandle *fufh;
struct fuse_vnode_data *fvdat = VTOFUD(vp);
- struct fuse_dispatcher fdi;
- struct ucred *cred;
- int err = 0;
- int chunksize, respsize;
- caddr_t bufdat;
- int biosize = vp->v_mount->mnt_stat.f_iosize;
+ struct ucred *cred;
+ struct uio *uiop;
+ struct uio uio;
+ struct iovec io;
+ int error = 0;
+
+ const int biosize = fuse_iosize(vp);
+
+ MPASS(vp->v_type == VREG);
+ MPASS(bp->b_iocmd == BIO_READ || bp->b_iocmd == BIO_WRITE);
+ DEBUG("inode=%jd offset=%jd resid=%jd\n",
+ VTOI(vp), ((off_t)bp->b_blkno) * biosize, bp->b_bcount);
- if (! (vp->v_type == VREG || vp->v_type == VDIR)) {
- DEBUG("for vnode #%ju v_type is %d, dropping\n",
- (uintmax_t)VTOILLU(vp), vp->v_type);
- return (EOPNOTSUPP);
+ error = fuse_filehandle_getrw(vp,
+ (bp->b_iocmd == BIO_READ) ? FUFH_RDONLY : FUFH_WRONLY, &fufh);
+ if (error) {
+ DEBUG("fetching filehandle failed\n");
+ bp->b_ioflags |= BIO_ERROR;
+ bp->b_error = error;
+ return (error);
}
- if (bp->b_iocmd != BIO_READ && bp->b_iocmd != BIO_WRITE) {
- DEBUG("for vnode #%ju bio tried with biocmd %#x, dropping\n",
- (uintmax_t)VTOILLU(vp), bp->b_iocmd);
- return (EOPNOTSUPP);
- }
+ cred = bp->b_iocmd == BIO_READ ? bp->b_rcred : bp->b_wcred;
+
+ uiop = &uio;
+ uiop->uio_iov = &io;
+ uiop->uio_iovcnt = 1;
+ uiop->uio_segflg = UIO_SYSSPACE;
+ uiop->uio_td = curthread;
/*
- * clear BIO_ERROR and B_INVAL state prior to initiating the I/O. We
+ * clear BIO_ERROR and B_INVAL state prior to initiating the I/O. We
* do this here so we do not have to do it in all the code that
* calls us.
*/
@@ -591,157 +567,85 @@
bp->b_ioflags &= ~BIO_ERROR;
KASSERT(!(bp->b_flags & B_DONE),
- ("fuse_strategy: bp %p already marked done", bp));
-
- if (bp->b_bcount == 0)
- return (0);
-
- cred = bp->b_iocmd == BIO_READ ? bp->b_rcred : bp->b_wcred;
-
- err = fuse_filehandle_getrw(vp,
- (bp->b_iocmd == BIO_READ) ? FUFH_RDONLY : FUFH_WRONLY, &fufh);
- if (err) {
- DEBUG("fetching filehandle failed\n");
- goto out;
- }
-
- DEBUG2G("vp #%ju, fufh #%ju\n",
- (uintmax_t)VTOILLU(vp), (uintmax_t)fufh->fh_id);
-
- fdisp_init(&fdi, 0);
-
+ ("fuse_io_strategy: bp %p already marked done", bp));
if (bp->b_iocmd == BIO_READ) {
- struct fuse_read_in *fri;
- int ioff = 0;
+ io.iov_len = uiop->uio_resid = bp->b_bcount;
+ io.iov_base = bp->b_data;
+ uiop->uio_rw = UIO_READ;
- bufdat = bp->b_data;
- bp->b_resid = bp->b_bcount;
- while (bp->b_resid > 0) {
- DEBUG2G("starting bio with resid %ld\n", bp->b_resid);
- chunksize = MIN(bp->b_resid,
- fuse_get_mpdata(vp->v_mount)->max_read);
- fdi.iosize = sizeof(*fri);
- if (! op)
- op = vp->v_type == VDIR ? FUSE_READDIR : FUSE_READ;
- fdisp_make_vp(&fdi, op, vp, curthread, cred);
+ uiop->uio_offset = ((off_t)bp->b_blkno) * biosize;
+ error = fuse_read_directbackend(vp, uiop, cred, fufh);
- fri = fdi.indata;
- fri->fh = fufh->fh_id;
- fri->offset = ((off_t)bp->b_blkno) * biosize + ioff;
- chunksize = MIN(chunksize,
- MIN(fri->offset + bp->b_resid,
- fvdat->filesize) - fri->offset);
- if (chunksize == 0) {
- respsize = -1;
- goto eval;
- }
- fri->size = chunksize;
- fdi.tick->tk_aw_type = FT_A_BUF;
- fdi.tick->tk_aw_bufdata = bufdat;
+ if (!error && uiop->uio_resid) {
+ /*
+ * If we had a short read with no error, we must have
+ * hit a file hole. We should zero-fill the remainder.
+ * This can also occur if the server hits the file EOF.
+ *
+ * Holes used to be able to occur due to pending
+ * writes, but that is not possible any longer.
+ */
+ int nread = bp->b_bcount - uiop->uio_resid;
+ int left = uiop->uio_resid;
- DEBUG("waiting for answer\n");
- if ((err = fdisp_wait_answ(&fdi)))
- goto out;
-
- respsize = fdi.tick->tk_aw_bufsize;
- DEBUG2G("chunksize %d, respsize %d, bp->b_resid %ld, bp->b_bcount %ld\n",
- chunksize, respsize, bp->b_resid, bp->b_bcount);
- bp->b_resid -= respsize;
- bufdat += respsize;
- ioff += respsize;
-
-eval:
- DEBUG2G("%d bytes asked for from offset %llu, passing on the %d we got\n",
- chunksize, (long long unsigned)fri->offset, respsize);
-
- if (respsize < chunksize) {
- /*
- * if we don't get enough data, just fill the
- * rest with zeros.
- */
- DEBUG("zeroing tail of %ld bytes\n",
- bp->b_resid);
- bzero((char *)bp->b_data + bp->b_bcount - bp->b_resid,
- bp->b_resid);
- if (chunksize)
- bp->b_resid = 0;
- break;
- }
- if (respsize > chunksize) {
- fuse_ticket_drop(fdi.tick);
- err = EINVAL;
- goto out;
- }
- DEBUG("bp->b_data %p\n", bp->b_data);
+ if (left > 0)
+ bzero((char *)bp->b_data + nread, left);
+ uiop->uio_resid = 0;
+ }
+ if (error) {
+ bp->b_ioflags |= BIO_ERROR;
+ bp->b_error = error;
}
} else {
- struct fuse_write_in *fwi;
- struct fuse_write_out *fwo;
- int diff;
- int merr = 0;
+ /*
+ * If we only need to commit, try to commit
+ */
+ if (bp->b_flags & B_NEEDCOMMIT) {
+ DEBUG("write: B_NEEDCOMMIT flags set\n");
+ }
- bufdat = bp->b_data + bp->b_dirtyoff;
- while (bp->b_dirtyend > bp->b_dirtyoff) {
- chunksize = MIN(bp->b_dirtyend - bp->b_dirtyoff,
- fuse_get_mpdata(vp->v_mount)->max_write);
+ /*
+ * Setup for actual write
+ */
+ if ((off_t)bp->b_blkno * biosize + bp->b_dirtyend > fvdat->filesize)
+ bp->b_dirtyend = fvdat->filesize - (off_t)bp->b_blkno * biosize;
- fdi.iosize = sizeof(*fwi);
- op = op ?: FUSE_WRITE;
- fdisp_make_vp(&fdi, op, vp, NULL, cred);
+ if (bp->b_dirtyend > bp->b_dirtyoff) {
+ io.iov_len = uiop->uio_resid = bp->b_dirtyend
+ - bp->b_dirtyoff;
+ uiop->uio_offset = (off_t)bp->b_blkno * biosize
+ + bp->b_dirtyoff;
+ io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;
+ uiop->uio_rw = UIO_WRITE;
- fwi = fdi.indata;
- fwi->fh = fufh->fh_id;
- fwi->offset = (off_t)bp->b_blkno * biosize + bp->b_dirtyoff;
- fwi->size = chunksize;
- fdi.tick->tk_ms_type = FT_M_BUF;
- fdi.tick->tk_ms_bufdata = bufdat;
- fdi.tick->tk_ms_bufsize = chunksize;
+ error = fuse_write_directbackend(vp, uiop, cred, fufh);
- if ((err = fdisp_wait_answ(&fdi))) {
- merr = 1;
- break;
- }
+ if (error == EINTR || error == ETIMEDOUT
+ || (!error && (bp->b_flags & B_NEEDCOMMIT))) {
- fwo = fdi.answ;
- diff = chunksize - fwo->size;
- if (diff < 0) {
- err = EINVAL;
- break;
+ bp->b_flags &= ~(B_INVAL|B_NOCACHE);
+ if ((bp->b_flags & B_PAGING) == 0) {
+ bdirty(bp);
+ bp->b_flags &= ~B_DONE;
+ }
+ if ((error == EINTR || error == ETIMEDOUT) &&
+ (bp->b_flags & B_ASYNC) == 0)
+ bp->b_flags |= B_EINTR;
+ } else {
+ if (error) {
+ bp->b_ioflags |= BIO_ERROR;
+ bp->b_flags |= B_INVAL;
+ bp->b_error = error;
+ }
+ bp->b_dirtyoff = bp->b_dirtyend = 0;
}
- if (diff > 0) {
- /*
- * Tolerating a short read would mean
- * keeping dirty data around and we
- * don't do that.
- */
- err = EIO;
- break;
- }
-
- bp->b_dirtyoff += fwo->size;
+ } else {
+ bp->b_resid = 0;
+ bufdone(bp);
+ return (0);
}
-
- if (bp->b_dirtyend == bp->b_dirtyoff)
- bp->b_dirtyend = bp->b_dirtyoff = 0;
-
- bp->b_resid = bp->b_dirtyend - bp->b_dirtyoff;
-
- if (merr)
- goto out;
}
-
- if (fdi.tick)
- fuse_ticket_drop(fdi.tick);
- else
- DEBUG("no ticket on leave\n");
-
-out:
- if (err) {
- bp->b_ioflags |= BIO_ERROR;
- bp->b_error = err;
- }
- DEBUG("calling bufdone\n");
+ bp->b_resid = uiop->uio_resid;
bufdone(bp);
-
- return (err);
-}
+ return (error);
+}
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.h#9 (text+ko) ====
@@ -1,26 +1,8 @@
#ifndef _FUSE_IO_H_
#define _FUSE_IO_H_
-/* prototype for processing an input data buffer and an uio
- for reading related acivities */
-typedef int fuse_buffeater_t(struct uio *uio, size_t reqsize,
- void *buf, size_t bufsize, void *param);
-
-/* data used through an I/O operation */
-struct fuse_io_data {
- struct vnode *vp;
- struct fuse_filehandle *fufh;
- struct uio *uio;
- struct ucred *cred;
- struct thread *td;
- enum fuse_opcode opcode;
- fuse_buffeater_t *buffeater;
- void *param;
-};
-
int fuse_io_dispatch(struct vnode *vp, struct uio *uio, int ioflag,
struct ucred *cred);
-int fuse_io_strategy(struct vnode *vp, struct buf *bp,
- struct fuse_filehandle *fufh, enum fuse_opcode op);
+int fuse_io_strategy(struct vnode *vp, struct buf *bp);
#endif /* _FUSE_IO_H_ */
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.c#15 (text+ko) ====
@@ -33,6 +33,7 @@
#include "fuse.h"
#include "fuse_node.h"
#include "fuse_internal.h"
+#include "fuse_io.h"
#include "fuse_ipc.h"
#define FUSE_DEBUG_MODULE VNOPS
@@ -228,6 +229,18 @@
}
void
+fuse_vnode_refreshsize(struct vnode *vp, struct ucred *cred)
+{
+ struct vattr va;
+
+ if (fuse_isvalid_attr(vp))
+ return;
+
+ VOP_GETATTR(vp, &va, cred);
+ DEBUG("refreshed file size: %jd\n", VTOFUD(vp)->filesize);
+}
+
+void
fuse_vnode_setsize(struct vnode *vp, off_t newsize)
{
struct fuse_vnode_data *fvdat = VTOFUD(vp);
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.h#15 (text+ko) ====
@@ -103,6 +103,8 @@
int32_t fuse_open_flags,
struct thread *td);
+void fuse_vnode_refreshsize(struct vnode *vp, struct ucred *cred);
+
void fuse_vnode_setsize(struct vnode *vp, off_t newsize);
#endif /* _FUSE_NODE_H_ */
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vfsops.c#20 (text+ko) ====
@@ -241,7 +241,7 @@
}
/* We need this here as this slot is used by getnewvnode() */
- mp->mnt_stat.f_iosize = MAXBSIZE;
+ mp->mnt_stat.f_iosize = PAGE_SIZE;
mp->mnt_data = data;
==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#37 (text+ko) ====
@@ -1737,7 +1737,10 @@
return EIO;
}
- (void)fuse_io_strategy(vp, bp, NULL, 0);
+ if (bp->b_iocmd == BIO_WRITE)
+ fuse_vnode_refreshsize(vp, NOCRED);
+
+ (void)fuse_io_strategy(vp, bp);
/*
* This is a dangerous function. If returns error, that might mean a
@@ -1827,6 +1830,8 @@
return EIO;
}
+ fuse_vnode_refreshsize(vp, cred);
+
return fuse_io_dispatch(vp, uio, ioflag, cred);
}
More information about the p4-projects
mailing list