From: Andreas Dilger Date: Fri, 19 Jun 2015 07:43:03 +0000 (-0600) Subject: LU-6747 osd-zfs: initialize obd_statfs in osd_statfs() X-Git-Tag: 2.7.57~45 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=1ef0185e8c12aa11a4c87c4956b1ba408c0e3d08;p=fs%2Flustre-release.git LU-6747 osd-zfs: initialize obd_statfs in osd_statfs() The osd-zfs osd_statfs() method wasn't initializing all of the fields of struct obd_statfs, and in some cases could be returning random data to the client. For most of the fields this doesn't matter, but the os_state field could contain OS_STATE_READONLY and prevent the MDS from allocating objects there. Reorder the assignment of struct obd_statfs fields to be in struct order so that it is more clear which fields have already been set. Also fixup osd-ldiskfs obd_statfs() to initialize os_maxbytes as osd-zfs does, even though it currently isn't used. Signed-off-by: Olaf Faaland Signed-off-by: Andreas Dilger Change-Id: If4ec6b5fc9c31676267e63be34d00275b4ac8dfb Signed-off-by: Nathaniel Clark Reviewed-on: http://review.whamcloud.com/15346 Tested-by: Jenkins Tested-by: Maloo --- diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 738dceb..6bce54c 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -1234,10 +1234,14 @@ int osd_statfs(const struct lu_env *env, struct dt_device *d, result = sb->s_op->statfs(sb->s_root, ksfs); if (likely(result == 0)) { /* N.B. statfs can't really fail */ statfs_pack(sfs, ksfs); - if (sb->s_flags & MS_RDONLY) + if (unlikely(sb->s_flags & MS_RDONLY)) sfs->os_state = OS_STATE_READONLY; + if (LDISKFS_HAS_INCOMPAT_FEATURE(sb, + LDISKFS_FEATURE_INCOMPAT_EXTENTS)) + sfs->os_maxbytes = sb->s_maxbytes; + else + sfs->os_maxbytes = LDISKFS_SB(sb)->s_bitmap_maxbytes; } - spin_unlock(&osd->od_osfs_lock); if (unlikely(env == NULL)) @@ -1284,7 +1288,10 @@ static void osd_conf_get(const struct lu_env *env, param->ddp_max_nlink = LDISKFS_LINK_MAX; param->ddp_block_shift = sb->s_blocksize_bits; param->ddp_mount_type = LDD_MT_LDISKFS; - param->ddp_maxbytes = sb->s_maxbytes; + if (LDISKFS_HAS_INCOMPAT_FEATURE(sb, LDISKFS_FEATURE_INCOMPAT_EXTENTS)) + param->ddp_maxbytes = sb->s_maxbytes; + else + param->ddp_maxbytes = LDISKFS_SB(sb)->s_bitmap_maxbytes; /* Overhead estimate should be fairly accurate, so we really take a tiny * error margin which also avoids fragmenting the filesystem too much */ param->ddp_grant_reserved = 2; /* end up to be 1.9% after conversion */ diff --git a/lustre/osd-zfs/osd_handler.c b/lustre/osd-zfs/osd_handler.c index 4ad7051..c73184e 100644 --- a/lustre/osd-zfs/osd_handler.c +++ b/lustre/osd-zfs/osd_handler.c @@ -441,6 +441,11 @@ static int osd_objset_statfs(struct osd_device *osd, struct obd_statfs *osfs) dmu_objset_space(os, &refdbytes, &availbytes, &usedobjs, &availobjs); + memset(osfs, 0, sizeof(*osfs)); + + /* We're a zfs filesystem. */ + osfs->os_type = UBERBLOCK_MAGIC; + /* * ZFS allows multiple block sizes. For statfs, Linux makes no * proper distinction between bsize and frsize. For calculations @@ -465,7 +470,7 @@ static int osd_objset_statfs(struct osd_device *osd, struct obd_statfs *osfs) * Rather than report this via os_bavail (which makes users unhappy if * they can't fill the filesystem 100%), reduce os_blocks as well. * - * Reserve 0.78% of total space, at least 4MB for small filesystems, + * Reserve 0.78% of total space, at least 16MB for small filesystems, * for internal files to be created/unlinked when space is tight. */ CLASSERT(OSD_STATFS_RESERVED_SIZE > 0); @@ -494,18 +499,15 @@ static int osd_objset_statfs(struct osd_device *osd, struct obd_statfs *osfs) /* ZFS XXX: fill in backing dataset FSID/UUID memcpy(osfs->os_fsid, .... );*/ - /* We're a zfs filesystem. */ - osfs->os_type = UBERBLOCK_MAGIC; + osfs->os_namelen = MAXNAMELEN; + osfs->os_maxbytes = OBD_OBJECT_EOF; /* ZFS XXX: fill in appropriate OS_STATE_{DEGRADED,READONLY} flags osfs->os_state = vf_to_stf(vfsp->vfs_flag); if (sb->s_flags & MS_RDONLY) - osfs->os_state = OS_STATE_READONLY; + osfs->os_state |= OS_STATE_READONLY; */ - osfs->os_namelen = MAXNAMELEN; - osfs->os_maxbytes = OBD_OBJECT_EOF; - return 0; }