Linux 2.6.39 compat, invalidate_inodes()
[zfs.git] / module / zfs / zfs_vfsops.c
index 1763d17..8a82d9d 100644 (file)
 
 /*ARGSUSED*/
 int
-zfs_sync(zfs_sb_t *zsb, short flag, cred_t *cr)
+zfs_sync(struct super_block *sb, int wait, cred_t *cr)
 {
+       zfs_sb_t *zsb = sb->s_fs_info;
+
        /*
         * Data integrity is job one.  We don't want a compromised kernel
         * writing to the storage pool, so we never sync during panic.
@@ -78,6 +80,13 @@ zfs_sync(zfs_sb_t *zsb, short flag, cred_t *cr)
        if (unlikely(oops_in_progress))
                return (0);
 
+       /*
+        * Semantically, the only requirement is that the sync be initiated.
+        * The DMU syncs out txgs frequently, so there's nothing to do.
+        */
+       if (!wait)
+               return (0);
+
        if (zsb != NULL) {
                /*
                 * Sync a specific filesystem.
@@ -87,19 +96,14 @@ zfs_sync(zfs_sb_t *zsb, short flag, cred_t *cr)
                ZFS_ENTER(zsb);
                dp = dmu_objset_pool(zsb->z_os);
 
-#ifdef HAVE_SHUTDOWN
                /*
                 * If the system is shutting down, then skip any
                 * filesystems which may exist on a suspended pool.
-                *
-                * XXX: This can be implemented using the Linux reboot
-                *      notifiers: {un}register_reboot_notifier().
                 */
-               if (sys_shutdown && spa_suspended(dp->dp_spa)) {
+               if (spa_suspended(dp->dp_spa)) {
                        ZFS_EXIT(zsb);
                        return (0);
                }
-#endif /* HAVE_SHUTDOWN */
 
                if (zsb->z_log != NULL)
                        zil_commit(zsb->z_log, 0);
@@ -997,11 +1001,15 @@ zfs_statvfs(struct dentry *dentry, struct kstatfs *statp)
            &refdbytes, &availbytes, &usedobjs, &availobjs);
 
        /*
-        * The underlying storage pool actually uses multiple block sizes.
-        * We report the fragsize as the smallest block size we support,
-        * and we report our blocksize as the filesystem's maximum blocksize.
+        * The underlying storage pool actually uses multiple block
+        * size.  Under Solaris frsize (fragment size) is reported as
+        * the smallest block size we support, and bsize (block size)
+        * as the filesystem's maximum block size.  Unfortunately,
+        * under Linux the fragment size and block size are often used
+        * interchangeably.  Thus we are forced to report both of them
+        * as the filesystem's maximum block size.
         */
-       statp->f_frsize = 1UL << SPA_MINBLOCKSHIFT;
+       statp->f_frsize = zsb->z_max_blksz;
        statp->f_bsize = zsb->z_max_blksz;
        bshift = fls(statp->f_bsize) - 1;
 
@@ -1025,7 +1033,7 @@ zfs_statvfs(struct dentry *dentry, struct kstatfs *statp)
         */
        statp->f_ffree = MIN(availobjs, statp->f_bfree);
        statp->f_files = statp->f_ffree + usedobjs;
-       statp->f_fsid.val[0] = 0; /* XXX: Map up some unique ID */
+       statp->f_fsid.val[0] = dentry->d_sb->s_dev;
        statp->f_fsid.val[1] = 0;
        statp->f_type = ZFS_SUPER_MAGIC;
        statp->f_namelen = ZFS_MAXNAMELEN;
@@ -1071,17 +1079,17 @@ zfsvfs_teardown(zfs_sb_t *zsb, boolean_t unmounting)
 
        rrw_enter(&zsb->z_teardown_lock, RW_WRITER, FTAG);
 
-#ifdef HAVE_DNLC
        if (!unmounting) {
                /*
-                * We purge the parent filesystem's vfsp as the parent
-                * filesystem and all of its snapshots have their vnode's
-                * v_vfsp set to the parent's filesystem's vfsp.  Note,
-                * 'z_parent' is self referential for non-snapshots.
+                * We purge the parent filesystem's super block as the
+                * parent filesystem and all of its snapshots have their
+                * inode's super block set to the parent's filesystem's
+                * super block.  Note,  'z_parent' is self referential
+                * for non-snapshots.
                 */
-               (void) dnlc_purge_vfsp(zsb->z_parent->z_vfs, 0);
+               shrink_dcache_sb(zsb->z_parent->z_sb);
+               (void) spl_invalidate_inodes(zsb->z_parent->z_sb, 0);
        }
-#endif /* HAVE_DNLC */
 
        /*
         * Close the zil. NB: Can't close the zil while zfs_inactive
@@ -1284,6 +1292,46 @@ zfs_umount(struct super_block *sb)
 EXPORT_SYMBOL(zfs_umount);
 
 int
+zfs_remount(struct super_block *sb, int *flags, char *data)
+{
+       zfs_sb_t *zsb = sb->s_fs_info;
+       boolean_t readonly = B_FALSE;
+       boolean_t setuid = B_TRUE;
+       boolean_t exec = B_TRUE;
+       boolean_t devices = B_TRUE;
+       boolean_t atime = B_TRUE;
+
+       if (*flags & MS_RDONLY)
+               readonly = B_TRUE;
+
+       if (*flags & MS_NOSUID) {
+               devices = B_FALSE;
+               setuid = B_FALSE;
+       } else {
+               if (*flags & MS_NODEV)
+                       devices = B_FALSE;
+       }
+
+       if (*flags & MS_NOEXEC)
+               exec = B_FALSE;
+
+       if (*flags & MS_NOATIME)
+               atime = B_FALSE;
+
+       /*
+        * Invoke our callbacks to set required flags.
+        */
+       readonly_changed_cb(zsb, readonly);
+       setuid_changed_cb(zsb, setuid);
+       exec_changed_cb(zsb, exec);
+       devices_changed_cb(zsb, devices);
+       atime_changed_cb(zsb, atime);
+
+       return (0);
+}
+EXPORT_SYMBOL(zfs_remount);
+
+int
 zfs_vget(struct vfsmount *vfsp, struct inode **ipp, fid_t *fidp)
 {
        zfs_sb_t        *zsb = VTOZSB(vfsp);