=============
Fix block size of getattr call. Depends on Mohan's iounit patch.
Signed-off-by: Sripathi Kodi <sripathik@in.ibm.com>
---
fs/9p/vfs_inode.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
@@ -955,6 +955,8 @@ v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
v9fs_stat2inode_dotl(st, dentry->d_inode);
generic_fillattr(dentry->d_inode, stat);
+ /* Change block size to what the server returned */
+ stat->blksize = st->st_blksize;
kfree(st);
return 0;
QEMU patch:
===========
Fix block size of getattr call. Depends on Mohan's iounit patch.
Signed-off-by: Sripathi Kodi <sripathik@in.ibm.com>
---
hw/virtio-9p.c | 55 +++++++++++++++++++++++++++++++------------------------
hw/virtio-9p.h | 1 +
2 files changed, 32 insertions(+), 24 deletions(-)
@@ -1180,6 +1180,26 @@ out:
qemu_free(vs);
}
+static int32_t get_iounit(V9fsState *s, V9fsString *name)
+{
+ struct statfs stbuf;
+ int32_t iounit = 0;
+
+ /*
+ * iounit should be multiples of f_bsize (host filesystem block size
+ * and as well as less than (client msize - P9_IOHDRSZ))
+ */
+ if (!v9fs_do_statfs(s, name, &stbuf)) {
+ iounit = stbuf.f_bsize;
+ iounit *= (s->msize - P9_IOHDRSZ)/stbuf.f_bsize;
+ }
+
+ if (!iounit) {
+ iounit = s->msize - P9_IOHDRSZ;
+ }
+ return iounit;
+}
+
static void v9fs_getattr_post_lstat(V9fsState *s, V9fsStatStateDotl *vs,
int err)
{
@@ -1188,7 +1208,15 @@ static void v9fs_getattr_post_lstat(V9fsState *s, V9fsStatStateDotl *vs,
goto out;
}
+ /* Recalculate block size and number of blocks based on iounit */
stat_to_v9stat_dotl(s, &vs->stbuf, &vs->v9stat_dotl);
+ vs->v9stat_dotl.st_blksize = get_iounit(s, &vs->fidp->path);
+ vs->v9stat_dotl.st_blocks = vs->v9stat_dotl.st_size /
+ vs->v9stat_dotl.st_blksize;
+ if (vs->v9stat_dotl.st_size % vs->v9stat_dotl.st_blksize) {
+ vs->v9stat_dotl.st_blocks++;
+ }
+
vs->offset += pdu_marshal(vs->pdu, vs->offset, "A", &vs->v9stat_dotl);
err = vs->offset;
@@ -1202,7 +1230,6 @@ static void v9fs_getattr(V9fsState *s, V9fsPDU *pdu)
int32_t fid;
V9fsStatStateDotl *vs;
ssize_t err = 0;
- V9fsFidState *fidp;
vs = qemu_malloc(sizeof(*vs));
vs->pdu = pdu;
@@ -1212,13 +1239,13 @@ static void v9fs_getattr(V9fsState *s, V9fsPDU *pdu)
pdu_unmarshal(vs->pdu, vs->offset, "d", &fid);
- fidp = lookup_fid(s, fid);
- if (fidp == NULL) {
+ vs->fidp = lookup_fid(s, fid);
+ if (vs->fidp == NULL) {
err = -ENOENT;
goto out;
}
- err = v9fs_do_lstat(s, &fidp->path, &vs->stbuf);
+ err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
v9fs_getattr_post_lstat(s, vs, err);
return;
@@ -1390,26 +1417,6 @@ out:
v9fs_walk_complete(s, vs, err);
}
-static int32_t get_iounit(V9fsState *s, V9fsString *name)
-{
- struct statfs stbuf;
- int32_t iounit = 0;
-
- /*
- * iounit should be multiples of f_bsize (host filesystem block size
- * and as well as less than (client msize - P9_IOHDRSZ))
- */
- if (!v9fs_do_statfs(s, name, &stbuf)) {
- iounit = stbuf.f_bsize;
- iounit *= (s->msize - P9_IOHDRSZ)/stbuf.f_bsize;
- }
-
- if (!iounit) {
- iounit = s->msize - P9_IOHDRSZ;
- }
- return iounit;
-}
-
static void v9fs_open_post_opendir(V9fsState *s, V9fsOpenState *vs, int err)
{
if (vs->fidp->dir == NULL) {
@@ -211,6 +211,7 @@ typedef struct V9fsStatDotl {
typedef struct V9fsStatStateDotl {
V9fsPDU *pdu;
size_t offset;
+ V9fsFidState *fidp;
V9fsStatDotl v9stat_dotl;
struct stat stbuf;
} V9fsStatStateDotl;