]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/zpl_super.c
Prune metadata from ghost lists in arc_adjust_meta
[mirror_zfs.git] / module / zfs / zpl_super.c
index 98d0a03127de36cf14df75cf22489a13423ee7c7..45639a6dd5d4c8489c13ee06a6ab05105b9910c3 100644 (file)
@@ -44,10 +44,29 @@ zpl_inode_alloc(struct super_block *sb)
 static void
 zpl_inode_destroy(struct inode *ip)
 {
-        ASSERT(atomic_read(&ip->i_count) == 0);
+       ASSERT(atomic_read(&ip->i_count) == 0);
        zfs_inode_destroy(ip);
 }
 
+/*
+ * Called from __mark_inode_dirty() to reflect that something in the
+ * inode has changed.  We use it to ensure the znode system attributes
+ * are always strictly update to date with respect to the inode.
+ */
+#ifdef HAVE_DIRTY_INODE_WITH_FLAGS
+static void
+zpl_dirty_inode(struct inode *ip, int flags)
+{
+       zfs_dirty_inode(ip, flags);
+}
+#else
+static void
+zpl_dirty_inode(struct inode *ip)
+{
+       zfs_dirty_inode(ip, 0);
+}
+#endif /* HAVE_DIRTY_INODE_WITH_FLAGS */
+
 /*
  * When ->drop_inode() is called its return value indicates if the
  * inode should be evicted from the inode cache.  If the inode is
@@ -64,10 +83,15 @@ zpl_inode_destroy(struct inode *ip)
  * This elaborate mechanism was replaced by ->evict_inode() which
  * does the job of both ->delete_inode() and ->clear_inode().  It
  * will be called exactly once, and when it returns the inode must
- * be in a state where it can simply be freed.  The ->evict_inode()
- * callback must minimally truncate the inode pages, and call
- * end_writeback() to complete all outstanding writeback for the
- * inode.  After this is complete evict inode can cleanup any
+ * be in a state where it can simply be freed.i
+ *
+ * The ->evict_inode() callback must minimally truncate the inode pages,
+ * and call clear_inode().  For 2.6.35 and later kernels this will
+ * simply update the inode state, with the sync occurring before the
+ * truncate in evict().  For earlier kernels clear_inode() maps to
+ * end_writeback() which is responsible for completing all outstanding
+ * write back.  In either case, once this is done it is safe to cleanup
+ * any remaining inode specific data via zfs_inactive().
  * remaining filesystem specific data.
  */
 #ifdef HAVE_EVICT_INODE
@@ -75,7 +99,7 @@ static void
 zpl_evict_inode(struct inode *ip)
 {
        truncate_setsize(ip, 0);
-       end_writeback(ip);
+       clear_inode(ip);
        zfs_inactive(ip);
 }
 
@@ -155,28 +179,50 @@ zpl_umount_begin(struct super_block *sb)
 }
 
 /*
- * The Linux VFS automatically handles the following flags:
- * MNT_NOSUID, MNT_NODEV, MNT_NOEXEC, MNT_NOATIME, MNT_READONLY
+ * ZFS specific features must be explicitly handled here, the VFS will
+ * automatically handled the following generic functionality.
+ *
+ *   MNT_NOSUID,
+ *   MNT_NODEV,
+ *   MNT_NOEXEC,
+ *   MNT_NOATIME,
+ *   MNT_NODIRATIME,
+ *   MNT_READONLY,
+ *   MNT_STRICTATIME,
+ *   MS_SYNCHRONOUS,
+ *   MS_DIRSYNC,
+ *   MS_MANDLOCK.
  */
-#ifdef HAVE_SHOW_OPTIONS_WITH_DENTRY
 static int
-zpl_show_options(struct seq_file *seq, struct dentry *root)
+__zpl_show_options(struct seq_file *seq, zfs_sb_t *zsb)
 {
-       zfs_sb_t *zsb = root->d_sb->s_fs_info;
-
        seq_printf(seq, ",%s", zsb->z_flags & ZSB_XATTR ? "xattr" : "noxattr");
 
+#ifdef CONFIG_FS_POSIX_ACL
+       switch (zsb->z_acl_type) {
+       case ZFS_ACLTYPE_POSIXACL:
+               seq_puts(seq, ",posixacl");
+               break;
+       default:
+               seq_puts(seq, ",noacl");
+               break;
+       }
+#endif /* CONFIG_FS_POSIX_ACL */
+
        return (0);
 }
+
+#ifdef HAVE_SHOW_OPTIONS_WITH_DENTRY
+static int
+zpl_show_options(struct seq_file *seq, struct dentry *root)
+{
+       return (__zpl_show_options(seq, root->d_sb->s_fs_info));
+}
 #else
 static int
 zpl_show_options(struct seq_file *seq, struct vfsmount *vfsp)
 {
-       zfs_sb_t *zsb = vfsp->mnt_sb->s_fs_info;
-
-       seq_printf(seq, ",%s", zsb->z_flags & ZSB_XATTR ? "xattr" : "noxattr");
-
-       return (0);
+       return (__zpl_show_options(seq, vfsp->mnt_sb->s_fs_info));
 }
 #endif /* HAVE_SHOW_OPTIONS_WITH_DENTRY */
 
@@ -198,7 +244,7 @@ zpl_mount(struct file_system_type *fs_type, int flags,
 {
        zpl_mount_data_t zmd = { osname, data };
 
-       return mount_nodev(fs_type, flags, &zmd, zpl_fill_super);
+       return (mount_nodev(fs_type, flags, &zmd, zpl_fill_super));
 }
 #else
 static int
@@ -207,7 +253,7 @@ zpl_get_sb(struct file_system_type *fs_type, int flags,
 {
        zpl_mount_data_t zmd = { osname, data };
 
-       return get_sb_nodev(fs_type, flags, &zmd, zpl_fill_super, mnt);
+       return (get_sb_nodev(fs_type, flags, &zmd, zpl_fill_super, mnt));
 }
 #endif /* HAVE_MOUNT_NODEV */
 
@@ -216,6 +262,10 @@ zpl_kill_sb(struct super_block *sb)
 {
        zfs_preumount(sb);
        kill_anon_super(sb);
+
+#ifdef HAVE_S_INSTANCES_LIST_HEAD
+       sb->s_instances.next = &(zpl_fs_type.fs_supers);
+#endif /* HAVE_S_INSTANCES_LIST_HEAD */
 }
 
 #ifdef HAVE_SHRINK
@@ -237,14 +287,12 @@ zpl_prune_sb(struct super_block *sb, void *arg)
 
        error = -zfs_sb_prune(sb, *(unsigned long *)arg, &objects);
        ASSERT3S(error, <=, 0);
-
-       return;
 }
 
 void
 zpl_prune_sbs(int64_t bytes_to_scan, void *private)
 {
-       unsigned long nr_to_scan = (bytes_to_scan / sizeof(znode_t));
+       unsigned long nr_to_scan = (bytes_to_scan / sizeof (znode_t));
 
        iterate_supers_type(&zpl_fs_type, zpl_prune_sb, &nr_to_scan);
        kmem_reap();
@@ -261,11 +309,11 @@ zpl_prune_sbs(int64_t bytes_to_scan, void *private)
 void
 zpl_prune_sbs(int64_t bytes_to_scan, void *private)
 {
-       unsigned long nr_to_scan = (bytes_to_scan / sizeof(znode_t));
+       unsigned long nr_to_scan = (bytes_to_scan / sizeof (znode_t));
 
-        shrink_dcache_memory(nr_to_scan, GFP_KERNEL);
-        shrink_icache_memory(nr_to_scan, GFP_KERNEL);
-        kmem_reap();
+       shrink_dcache_memory(nr_to_scan, GFP_KERNEL);
+       shrink_icache_memory(nr_to_scan, GFP_KERNEL);
+       kmem_reap();
 }
 #endif /* HAVE_SHRINK */
 
@@ -294,14 +342,14 @@ zpl_nr_cached_objects(struct super_block *sb)
 static void
 zpl_free_cached_objects(struct super_block *sb, int nr_to_scan)
 {
-       arc_adjust_meta(nr_to_scan * sizeof(znode_t), B_FALSE);
+       /* noop */
 }
 #endif /* HAVE_FREE_CACHED_OBJECTS */
 
 const struct super_operations zpl_super_operations = {
        .alloc_inode            = zpl_inode_alloc,
        .destroy_inode          = zpl_inode_destroy,
-       .dirty_inode            = NULL,
+       .dirty_inode            = zpl_dirty_inode,
        .write_inode            = NULL,
        .drop_inode             = NULL,
 #ifdef HAVE_EVICT_INODE
@@ -311,7 +359,6 @@ const struct super_operations zpl_super_operations = {
        .delete_inode           = zpl_inode_delete,
 #endif /* HAVE_EVICT_INODE */
        .put_super              = zpl_put_super,
-       .write_super            = NULL,
        .sync_fs                = zpl_sync_fs,
        .statfs                 = zpl_statfs,
        .remount_fs             = zpl_remount_fs,