Set mtime on symbolic links
[zfs.git] / module / zfs / zfs_vfsops.c
index e0987e9..b115dcd 100644 (file)
@@ -600,6 +600,12 @@ 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;
@@ -709,8 +715,9 @@ out:
        kmem_free(zsb, sizeof (zfs_sb_t));
        return (error);
 }
+EXPORT_SYMBOL(zfs_sb_create);
 
-static int
+int
 zfs_sb_setup(zfs_sb_t *zsb, boolean_t mounting)
 {
        int error;
@@ -791,6 +798,7 @@ zfs_sb_setup(zfs_sb_t *zsb, boolean_t mounting)
 
        return (0);
 }
+EXPORT_SYMBOL(zfs_sb_setup);
 
 void
 zfs_sb_free(zfs_sb_t *zsb)
@@ -799,6 +807,7 @@ 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);
@@ -809,6 +818,7 @@ zfs_sb_free(zfs_sb_t *zsb)
                mutex_destroy(&zsb->z_hold_mtx[i]);
        kmem_free(zsb, sizeof (zfs_sb_t));
 }
+EXPORT_SYMBOL(zfs_sb_free);
 
 static void
 zfs_set_fuid_feature(zfs_sb_t *zsb)
@@ -892,6 +902,7 @@ zfs_check_global_label(const char *dsname, const char *hexsl)
        }
        return (EACCES);
 }
+EXPORT_SYMBOL(zfs_check_global_label);
 #endif /* HAVE_MLSLABEL */
 
 int
@@ -937,7 +948,7 @@ zfs_statvfs(struct dentry *dentry, struct kstatfs *statp)
         * For f_ffree, report the smaller of the number of object available
         * and the number of blocks (each object will take at least a block).
         */
-       statp->f_ffree = MIN(availobjs, statp->f_bfree);
+       statp->f_ffree = MIN(availobjs, availbytes >> DNODE_SHIFT);
        statp->f_files = statp->f_ffree + usedobjs;
        statp->f_fsid.val[0] = dentry->d_sb->s_dev;
        statp->f_fsid.val[1] = 0;
@@ -979,7 +990,7 @@ EXPORT_SYMBOL(zfs_root);
  * and 'z_teardown_inactive_lock' held.
  */
 int
-zfsvfs_teardown(zfs_sb_t *zsb, boolean_t unmounting)
+zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting)
 {
        znode_t *zp;
 
@@ -1076,6 +1087,11 @@ zfsvfs_teardown(zfs_sb_t *zsb, boolean_t unmounting)
 
        return (0);
 }
+EXPORT_SYMBOL(zfs_sb_teardown);
+
+#ifdef HAVE_BDI
+static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0);
+#endif /* HAVE_BDI */
 
 int
 zfs_domount(struct super_block *sb, void *data, int silent)
@@ -1102,6 +1118,7 @@ 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);
 
        /* Set callback operations for the file system. */
        sb->s_op = &zpl_super_operations;
@@ -1126,6 +1143,16 @@ 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);
@@ -1163,9 +1190,14 @@ zfs_umount(struct super_block *sb)
        zfs_sb_t *zsb = sb->s_fs_info;
        objset_t *os;
 
-       VERIFY(zfsvfs_teardown(zsb, B_TRUE) == 0);
+       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);
+       }
+
        /*
         * z_os will be NULL if there was an error in
         * attempting to reopen zsb.
@@ -1305,7 +1337,7 @@ zfs_suspend_fs(zfs_sb_t *zsb)
 {
        int error;
 
-       if ((error = zfsvfs_teardown(zsb, B_FALSE)) != 0)
+       if ((error = zfs_sb_teardown(zsb, B_FALSE)) != 0)
                return (error);
        dmu_objset_disown(zsb->z_os, zsb);
 
@@ -1485,6 +1517,7 @@ zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value)
        }
        return (error);
 }
+EXPORT_SYMBOL(zfs_get_zplprop);
 
 void
 zfs_init(void)