X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fzfs_vfsops.c;h=fb319a547a93d9b305bb39df77979d5c5ed66e69;hb=c8df41538db3723edf3536379a78fbaf68f037d0;hp=b115dcd66d1ecf8d6928a6866a326ab9cae1462f;hpb=86f35f34f419f6eaff53b25f463c13f72186b103;p=zfs.git diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index b115dcd..fb319a5 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -140,10 +140,16 @@ xattr_changed_cb(void *arg, uint64_t newval) { zfs_sb_t *zsb = arg; - if (newval == TRUE) - zsb->z_flags |= ZSB_XATTR; - else + if (newval == ZFS_XATTR_OFF) { zsb->z_flags &= ~ZSB_XATTR; + } else { + zsb->z_flags |= ZSB_XATTR; + + if (newval == ZFS_XATTR_SA) + zsb->z_xattr_sa = B_TRUE; + else + zsb->z_xattr_sa = B_FALSE; + } } static void @@ -600,12 +606,6 @@ zfs_sb_create(const char *osname, zfs_sb_t **zsbp) zsb->z_show_ctldir = ZFS_SNAPDIR_VISIBLE; zsb->z_os = os; - error = -bdi_init(&zsb->z_bdi); - if (error) { - kmem_free(zsb, sizeof (zfs_sb_t)); - return (error); - } - error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zsb->z_version); if (error) { goto out; @@ -646,7 +646,11 @@ zfs_sb_create(const char *osname, zfs_sb_t **zsbp) error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS, 8, 1, &sa_obj); if (error) - return (error); + goto out; + + error = zfs_get_zplprop(os, ZFS_PROP_XATTR, &zval); + if ((error == 0) && (zval == ZFS_XATTR_SA)) + zsb->z_xattr_sa = B_TRUE; } else { /* * Pre SA versions file systems should never touch @@ -807,7 +811,6 @@ zfs_sb_free(zfs_sb_t *zsb) zfs_fuid_destroy(zsb); - bdi_destroy(&zsb->z_bdi); mutex_destroy(&zsb->z_znodes_lock); mutex_destroy(&zsb->z_lock); list_destroy(&zsb->z_all_znodes); @@ -983,6 +986,26 @@ zfs_root(zfs_sb_t *zsb, struct inode **ipp) } EXPORT_SYMBOL(zfs_root); +#ifdef HAVE_SHRINK +int +zfs_sb_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects) +{ + zfs_sb_t *zsb = sb->s_fs_info; + struct shrinker *shrinker = &sb->s_shrink; + struct shrink_control sc = { + .nr_to_scan = nr_to_scan, + .gfp_mask = GFP_KERNEL, + }; + + ZFS_ENTER(zsb); + *objects = (*shrinker->shrink)(shrinker, &sc); + ZFS_EXIT(zsb); + + return (0); +} +EXPORT_SYMBOL(zfs_sb_prune); +#endif /* HAVE_SHRINK */ + /* * Teardown the zfs_sb_t::z_os. * @@ -1089,9 +1112,9 @@ zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting) } EXPORT_SYMBOL(zfs_sb_teardown); -#ifdef HAVE_BDI -static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0); -#endif /* HAVE_BDI */ +#if defined(HAVE_BDI) && !defined(HAVE_BDI_SETUP_AND_REGISTER) +atomic_long_t zfs_bdi_seq = ATOMIC_LONG_INIT(0); +#endif /* HAVE_BDI && !HAVE_BDI_SETUP_AND_REGISTER */ int zfs_domount(struct super_block *sb, void *data, int silent) @@ -1118,7 +1141,23 @@ zfs_domount(struct super_block *sb, void *data, int silent) sb->s_time_gran = 1; sb->s_blocksize = recordsize; sb->s_blocksize_bits = ilog2(recordsize); - bdi_put_sb(sb, NULL); + +#ifdef HAVE_BDI + /* + * 2.6.32 API change, + * Added backing_device_info (BDI) per super block interfaces. A BDI + * must be configured when using a non-device backed filesystem for + * proper writeback. This is not required for older pdflush kernels. + * + * NOTE: Linux read-ahead is disabled in favor of zfs read-ahead. + */ + zsb->z_bdi.ra_pages = 0; + sb->s_bdi = &zsb->z_bdi; + + error = -bdi_setup_and_register(&zsb->z_bdi, "zfs", BDI_CAP_MAP_COPY); + if (error) + goto out; +#endif /* HAVE_BDI */ /* Set callback operations for the file system. */ sb->s_op = &zpl_super_operations; @@ -1143,16 +1182,6 @@ zfs_domount(struct super_block *sb, void *data, int silent) dmu_objset_set_user(zsb->z_os, zsb); mutex_exit(&zsb->z_os->os_user_ptr_lock); } else { - /* Disable Linux read-ahead handled by lower layers */ - zsb->z_bdi.ra_pages = 0; - - error = -bdi_register(&zsb->z_bdi, NULL, "zfs-%d", - atomic_long_inc_return(&bdi_seq)); - if (error) - goto out; - - bdi_put_sb(sb, &zsb->z_bdi); - error = zfs_sb_setup(zsb, B_TRUE); #ifdef HAVE_SNAPSHOT (void) zfs_snap_create(zsb); @@ -1193,10 +1222,9 @@ zfs_umount(struct super_block *sb) VERIFY(zfs_sb_teardown(zsb, B_TRUE) == 0); os = zsb->z_os; - if (bdi_get_sb(sb)) { - bdi_unregister(bdi_get_sb(sb)); - bdi_put_sb(sb, NULL); - } +#ifdef HAVE_BDI + bdi_destroy(sb->s_bdi); +#endif /* HAVE_BDI */ /* * z_os will be NULL if there was an error in @@ -1525,6 +1553,7 @@ zfs_init(void) zfs_znode_init(); dmu_objset_register_type(DMU_OST_ZFS, zfs_space_delta_cb); register_filesystem(&zpl_fs_type); + (void) arc_add_prune_callback(zpl_prune_sbs, NULL); } void