]> err.no Git - linux-2.6/blobdiff - fs/nfs/super.c
NFS: eliminate NIPQUAD(clp->cl_addr.sin_addr)
[linux-2.6] / fs / nfs / super.c
index ea929207f27412e24a04631a301339b5990f7830..75f3cbf922a30a5b6c2b107fa0d0b27ba4535e8a 100644 (file)
@@ -83,8 +83,8 @@ enum {
        Opt_actimeo,
        Opt_namelen,
        Opt_mountport,
-       Opt_mountprog, Opt_mountvers,
-       Opt_nfsprog, Opt_nfsvers,
+       Opt_mountvers,
+       Opt_nfsvers,
 
        /* Mount options that take string arguments */
        Opt_sec, Opt_proto, Opt_mountproto,
@@ -137,9 +137,7 @@ static match_table_t nfs_mount_option_tokens = {
        { Opt_userspace, "retry=%u" },
        { Opt_namelen, "namlen=%u" },
        { Opt_mountport, "mountport=%u" },
-       { Opt_mountprog, "mountprog=%u" },
        { Opt_mountvers, "mountvers=%u" },
-       { Opt_nfsprog, "nfsprog=%u" },
        { Opt_nfsvers, "nfsvers=%u" },
        { Opt_nfsvers, "vers=%u" },
 
@@ -202,6 +200,7 @@ static int nfs_get_sb(struct file_system_type *, int, const char *, void *, stru
 static int nfs_xdev_get_sb(struct file_system_type *fs_type,
                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 struct file_system_type nfs_fs_type = {
        .owner          = THIS_MODULE,
@@ -223,6 +222,7 @@ static const struct super_operations nfs_sops = {
        .alloc_inode    = nfs_alloc_inode,
        .destroy_inode  = nfs_destroy_inode,
        .write_inode    = nfs_write_inode,
+       .put_super      = nfs_put_super,
        .statfs         = nfs_statfs,
        .clear_inode    = nfs_clear_inode,
        .umount_begin   = nfs_umount_begin,
@@ -325,6 +325,28 @@ void __exit unregister_nfs_fs(void)
        unregister_filesystem(&nfs_fs_type);
 }
 
+void nfs_sb_active(struct nfs_server *server)
+{
+       atomic_inc(&server->active);
+}
+
+void nfs_sb_deactive(struct nfs_server *server)
+{
+       if (atomic_dec_and_test(&server->active))
+               wake_up(&server->active_wq);
+}
+
+static void nfs_put_super(struct super_block *sb)
+{
+       struct nfs_server *server = NFS_SB(sb);
+       /*
+        * Make sure there are no outstanding ops to this server.
+        * If so, wait for them to finish before allowing the
+        * unmount to continue.
+        */
+       wait_event(server->active_wq, atomic_read(&server->active) == 0);
+}
+
 /*
  * Deliver file system statistics to userspace
  */
@@ -469,8 +491,9 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
 
        nfs_show_mount_options(m, nfss, 0);
 
-       seq_printf(m, ",addr="NIPQUAD_FMT,
-               NIPQUAD(nfss->nfs_client->cl_addr.sin_addr));
+       seq_printf(m, ",addr=%s",
+                       rpc_peeraddr2str(nfss->nfs_client->cl_rpcclient,
+                                                       RPC_DISPLAY_ADDR));
 
        return 0;
 }
@@ -507,7 +530,7 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
        seq_printf(m, ",namelen=%d", nfss->namelen);
 
 #ifdef CONFIG_NFS_V4
-       if (nfss->nfs_client->cl_nfsversion == 4) {
+       if (nfss->nfs_client->rpc_ops->version == 4) {
                seq_printf(m, "\n\tnfsv4:\t");
                seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
                seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]);
@@ -763,13 +786,6 @@ static int nfs_parse_mount_options(char *raw,
                                return 0;
                        mnt->mount_server.port = option;
                        break;
-               case Opt_mountprog:
-                       if (match_int(args, &option))
-                               return 0;
-                       if (option < 0)
-                               return 0;
-                       mnt->mount_server.program = option;
-                       break;
                case Opt_mountvers:
                        if (match_int(args, &option))
                                return 0;
@@ -777,13 +793,6 @@ static int nfs_parse_mount_options(char *raw,
                                return 0;
                        mnt->mount_server.version = option;
                        break;
-               case Opt_nfsprog:
-                       if (match_int(args, &option))
-                               return 0;
-                       if (option < 0)
-                               return 0;
-                       mnt->nfs_server.program = option;
-                       break;
                case Opt_nfsvers:
                        if (match_int(args, &option))
                                return 0;
@@ -1043,9 +1052,6 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
  *
  * + breaking back: trying proto=udp after proto=tcp, v2 after v3,
  *   mountproto=tcp after mountproto=udp, and so on
- *
- * XXX: as far as I can tell, changing the NFS program number is not
- *      supported in the NFS client.
  */
 static int nfs_validate_mount_data(void *options,
                                   struct nfs_parsed_mount_data *args,
@@ -1069,9 +1075,7 @@ static int nfs_validate_mount_data(void *options,
        args->acdirmin          = 30;
        args->acdirmax          = 60;
        args->mount_server.protocol = XPRT_TRANSPORT_UDP;
-       args->mount_server.program = NFS_MNT_PROGRAM;
        args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
-       args->nfs_server.program = NFS_PROGRAM;
 
        switch (data->version) {
        case 1:
@@ -1475,7 +1479,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
                error = PTR_ERR(mntroot);
                goto error_splat_super;
        }
-       if (mntroot->d_inode->i_op != server->nfs_client->rpc_ops->dir_inode_ops) {
+       if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
                dput(mntroot);
                error = -ESTALE;
                goto error_splat_super;
@@ -1619,6 +1623,8 @@ static int nfs4_validate_mount_data(void *options,
                if (nfs_parse_mount_options((char *)options, args) == 0)
                        return -EINVAL;
 
+               if (args->nfs_server.address.sin_port == 0)
+                       args->nfs_server.address.sin_port = htons(NFS_PORT);
                if (!nfs_verify_server_address((struct sockaddr *)
                                                &args->nfs_server.address))
                        return -EINVAL;
@@ -1643,21 +1649,16 @@ static int nfs4_validate_mount_data(void *options,
                len = c - dev_name;
                if (len > NFS4_MAXNAMLEN)
                        return -ENAMETOOLONG;
-               args->nfs_server.hostname = kzalloc(len, GFP_KERNEL);
-               if (args->nfs_server.hostname == NULL)
-                       return -ENOMEM;
-               strncpy(args->nfs_server.hostname, dev_name, len - 1);
+               /* N.B. caller will free nfs_server.hostname in all cases */
+               args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL);
 
                c++;                    /* step over the ':' */
                len = strlen(c);
                if (len > NFS4_MAXPATHLEN)
                        return -ENAMETOOLONG;
-               args->nfs_server.export_path = kzalloc(len + 1, GFP_KERNEL);
-               if (args->nfs_server.export_path == NULL)
-                       return -ENOMEM;
-               strncpy(args->nfs_server.export_path, c, len);
+               args->nfs_server.export_path = kstrndup(c, len, GFP_KERNEL);
 
-               dprintk("MNTPATH: %s\n", args->nfs_server.export_path);
+               dprintk("NFS: MNTPATH: '%s'\n", args->nfs_server.export_path);
 
                if (args->client_address == NULL)
                        goto out_no_client_address;
@@ -1826,6 +1827,11 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
                error = PTR_ERR(mntroot);
                goto error_splat_super;
        }
+       if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
+               dput(mntroot);
+               error = -ESTALE;
+               goto error_splat_super;
+       }
 
        s->s_flags |= MS_ACTIVE;
        mnt->mnt_sb = s;
@@ -1900,6 +1906,11 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
                error = PTR_ERR(mntroot);
                goto error_splat_super;
        }
+       if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
+               dput(mntroot);
+               error = -ESTALE;
+               goto error_splat_super;
+       }
 
        s->s_flags |= MS_ACTIVE;
        mnt->mnt_sb = s;