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,
{ 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" },
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,
.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,
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
*/
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;
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;
*
* + 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,
{
struct nfs_mount_data *data = (struct nfs_mount_data *)options;
+ memset(args, 0, sizeof(*args));
+
if (data == NULL)
goto out_no_data;
- memset(args, 0, sizeof(*args));
args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
args->rsize = NFS_MAX_FILE_IO_SIZE;
args->wsize = NFS_MAX_FILE_IO_SIZE;
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:
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;
struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
char *c;
+ memset(args, 0, sizeof(*args));
+
if (data == NULL)
goto out_no_data;
- memset(args, 0, sizeof(*args));
args->rsize = NFS_MAX_FILE_IO_SIZE;
args->wsize = NFS_MAX_FILE_IO_SIZE;
args->timeo = 600;
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;
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;
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;