int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
 static void nfs_kill_super(struct super_block *);
 static void nfs_put_super(struct super_block *);
+static int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
 
 static struct file_system_type nfs_fs_type = {
        .owner          = THIS_MODULE,
        .umount_begin   = nfs_umount_begin,
        .show_options   = nfs_show_options,
        .show_stats     = nfs_show_stats,
+       .remount_fs     = nfs_remount,
 };
 
 #ifdef CONFIG_NFS_V4
        .umount_begin   = nfs_umount_begin,
        .show_options   = nfs_show_options,
        .show_stats     = nfs_show_stats,
+       .remount_fs     = nfs_remount,
 };
 #endif
 
        return -EINVAL;
 }
 
+static int
+nfs_compare_remount_data(struct nfs_server *nfss,
+                        struct nfs_parsed_mount_data *data)
+{
+       if (data->flags != nfss->flags ||
+           data->rsize != nfss->rsize ||
+           data->wsize != nfss->wsize ||
+           data->retrans != nfss->client->cl_timeout->to_retries ||
+           data->auth_flavors[0] != nfss->client->cl_auth->au_flavor ||
+           data->acregmin != nfss->acregmin / HZ ||
+           data->acregmax != nfss->acregmax / HZ ||
+           data->acdirmin != nfss->acdirmin / HZ ||
+           data->acdirmax != nfss->acdirmax / HZ ||
+           data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) ||
+           data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen ||
+           memcmp(&data->nfs_server.address, &nfss->nfs_client->cl_addr,
+                  data->nfs_server.addrlen) != 0)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int
+nfs_remount(struct super_block *sb, int *flags, char *raw_data)
+{
+       int error;
+       struct nfs_server *nfss = sb->s_fs_info;
+       struct nfs_parsed_mount_data *data;
+       struct nfs_mount_data *options = (struct nfs_mount_data *)raw_data;
+       struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data;
+
+       /*
+        * Userspace mount programs that send binary options generally send
+        * them populated with default values. We have no way to know which
+        * ones were explicitly specified. Fall back to legacy behavior and
+        * just return success.
+        */
+       if ((sb->s_type == &nfs4_fs_type && options4->version == 1) ||
+           (sb->s_type == &nfs_fs_type && options->version >= 1 &&
+            options->version <= 6))
+               return 0;
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (data == NULL)
+               return -ENOMEM;
+
+       /* fill out struct with values from existing mount */
+       data->flags = nfss->flags;
+       data->rsize = nfss->rsize;
+       data->wsize = nfss->wsize;
+       data->retrans = nfss->client->cl_timeout->to_retries;
+       data->auth_flavors[0] = nfss->client->cl_auth->au_flavor;
+       data->acregmin = nfss->acregmin / HZ;
+       data->acregmax = nfss->acregmax / HZ;
+       data->acdirmin = nfss->acdirmin / HZ;
+       data->acdirmax = nfss->acdirmax / HZ;
+       data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ;
+       data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen;
+       memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr,
+               data->nfs_server.addrlen);
+
+       /* overwrite those values with any that were specified */
+       error = nfs_parse_mount_options((char *)options, data);
+       if (error < 0)
+               goto out;
+
+       /* compare new mount options with old ones */
+       error = nfs_compare_remount_data(nfss, data);
+out:
+       kfree(data);
+       return error;
+}
+
 /*
  * Initialise the common bits of the superblock
  */