]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/nfs/super.c
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux.git] / fs / nfs / super.c
index c27ac96a95bd3535bc893493492fdc7681aba1fe..d6c687419a818d61ee49420ccc248803ee14d0a8 100644 (file)
@@ -78,7 +78,7 @@
 
 enum {
        /* Mount options that take no arguments */
-       Opt_soft, Opt_hard,
+       Opt_soft, Opt_softerr, Opt_hard,
        Opt_posix, Opt_noposix,
        Opt_cto, Opt_nocto,
        Opt_ac, Opt_noac,
@@ -125,6 +125,7 @@ static const match_table_t nfs_mount_option_tokens = {
        { Opt_sloppy, "sloppy" },
 
        { Opt_soft, "soft" },
+       { Opt_softerr, "softerr" },
        { Opt_hard, "hard" },
        { Opt_deprecated, "intr" },
        { Opt_deprecated, "nointr" },
@@ -309,7 +310,7 @@ struct file_system_type nfs_xdev_fs_type = {
 
 const struct super_operations nfs_sops = {
        .alloc_inode    = nfs_alloc_inode,
-       .destroy_inode  = nfs_destroy_inode,
+       .free_inode     = nfs_free_inode,
        .write_inode    = nfs_write_inode,
        .drop_inode     = nfs_drop_inode,
        .statfs         = nfs_statfs,
@@ -628,7 +629,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
                const char *str;
                const char *nostr;
        } nfs_info[] = {
-               { NFS_MOUNT_SOFT, ",soft", ",hard" },
+               { NFS_MOUNT_SOFT, ",soft", "" },
+               { NFS_MOUNT_SOFTERR, ",softerr", "" },
                { NFS_MOUNT_POSIX, ",posix", "" },
                { NFS_MOUNT_NOCTO, ",nocto", "" },
                { NFS_MOUNT_NOAC, ",noac", "" },
@@ -658,6 +660,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
                seq_printf(m, ",acdirmin=%u", nfss->acdirmin/HZ);
        if (nfss->acdirmax != NFS_DEF_ACDIRMAX*HZ || showdefaults)
                seq_printf(m, ",acdirmax=%u", nfss->acdirmax/HZ);
+       if (!(nfss->flags & (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)))
+                       seq_puts(m, ",hard");
        for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
                if (nfss->flags & nfs_infop->flag)
                        seq_puts(m, nfs_infop->str);
@@ -1239,10 +1243,15 @@ static int nfs_parse_mount_options(char *raw,
                 */
                case Opt_soft:
                        mnt->flags |= NFS_MOUNT_SOFT;
+                       mnt->flags &= ~NFS_MOUNT_SOFTERR;
                        break;
-               case Opt_hard:
+               case Opt_softerr:
+                       mnt->flags |= NFS_MOUNT_SOFTERR;
                        mnt->flags &= ~NFS_MOUNT_SOFT;
                        break;
+               case Opt_hard:
+                       mnt->flags &= ~(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR);
+                       break;
                case Opt_posix:
                        mnt->flags |= NFS_MOUNT_POSIX;
                        break;
@@ -2476,6 +2485,21 @@ static int nfs_compare_super_address(struct nfs_server *server1,
        return 1;
 }
 
+static int nfs_compare_userns(const struct nfs_server *old,
+               const struct nfs_server *new)
+{
+       const struct user_namespace *oldns = &init_user_ns;
+       const struct user_namespace *newns = &init_user_ns;
+
+       if (old->client && old->client->cl_cred)
+               oldns = old->client->cl_cred->user_ns;
+       if (new->client && new->client->cl_cred)
+               newns = new->client->cl_cred->user_ns;
+       if (oldns != newns)
+               return 0;
+       return 1;
+}
+
 static int nfs_compare_super(struct super_block *sb, void *data)
 {
        struct nfs_sb_mountdata *sb_mntdata = data;
@@ -2489,6 +2513,8 @@ static int nfs_compare_super(struct super_block *sb, void *data)
                return 0;
        if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0)
                return 0;
+       if (!nfs_compare_userns(old, server))
+               return 0;
        return nfs_compare_mount_options(sb, server, mntflags);
 }