Blame view

fs/nfsctl.c 2.08 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
  /*
   *	fs/nfsctl.c
   *
   *	This should eventually move to userland.
   *
   */
715b49ef2   Alan Cox   [PATCH] EDAC: ato...
7
  #include <linux/types.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
  #include <linux/file.h>
  #include <linux/fs.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
  #include <linux/nfsd/syscall.h>
9789cfe22   Randy Dunlap   nfsctl: add heade...
11
12
  #include <linux/cred.h>
  #include <linux/sched.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
18
19
20
21
22
23
24
  #include <linux/linkage.h>
  #include <linux/namei.h>
  #include <linux/mount.h>
  #include <linux/syscalls.h>
  #include <asm/uaccess.h>
  
  /*
   * open a file on nfsd fs
   */
  
  static struct file *do_open(char *name, int flags)
  {
16b6287a5   Josef 'Jeff' Sipek   nfsctl: use vfs_p...
25
  	struct vfsmount *mnt;
73d049a40   Al Viro   open-style analog...
26
  	struct file *file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27

16b6287a5   Josef 'Jeff' Sipek   nfsctl: use vfs_p...
28
29
30
  	mnt = do_kern_mount("nfsd", 0, "nfsd", NULL);
  	if (IS_ERR(mnt))
  		return (struct file *)mnt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31

73d049a40   Al Viro   open-style analog...
32
  	file = file_open_root(mnt->mnt_root, mnt, name, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33

73d049a40   Al Viro   open-style analog...
34
35
  	mntput(mnt);	/* drop do_kern_mount reference */
  	return file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  }
  
  static struct {
  	char *name; int wsize; int rsize;
  } map[] = {
  	[NFSCTL_SVC] = {
  		.name	= ".svc",
  		.wsize	= sizeof(struct nfsctl_svc)
  	},
  	[NFSCTL_ADDCLIENT] = {
  		.name	= ".add",
  		.wsize	= sizeof(struct nfsctl_client)
  	},
  	[NFSCTL_DELCLIENT] = {
  		.name	= ".del",
  		.wsize	= sizeof(struct nfsctl_client)
  	},
  	[NFSCTL_EXPORT] = {
  		.name	= ".export",
  		.wsize	= sizeof(struct nfsctl_export)
  	},
  	[NFSCTL_UNEXPORT] = {
  		.name	= ".unexport",
  		.wsize	= sizeof(struct nfsctl_export)
  	},
  	[NFSCTL_GETFD] = {
  		.name	= ".getfd",
  		.wsize	= sizeof(struct nfsctl_fdparm),
  		.rsize	= NFS_FHSIZE
  	},
  	[NFSCTL_GETFS] = {
  		.name	= ".getfs",
  		.wsize	= sizeof(struct nfsctl_fsparm),
  		.rsize	= sizeof(struct knfsd_fh)
  	},
  };
1e7bfb213   Heiko Carstens   [CVE-2009-0029] S...
72
73
  SYSCALL_DEFINE3(nfsservctl, int, cmd, struct nfsctl_arg __user *, arg,
  		void __user *, res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
76
77
78
79
80
81
  {
  	struct file *file;
  	void __user *p = &arg->u;
  	int version;
  	int err;
  
  	if (copy_from_user(&version, &arg->ca_version, sizeof(int)))
  		return -EFAULT;
85c6932ef   Peter Staubach   [PATCH] nfsservct...
82
  	if (version != NFSCTL_VERSION)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84

e8c96f8c2   Tobias Klauser   [PATCH] fs: Use A...
85
  	if (cmd < 0 || cmd >= ARRAY_SIZE(map) || !map[cmd].name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
88
89
90
91
92
93
94
95
96
97
98
  		return -EINVAL;
  
  	file = do_open(map[cmd].name, map[cmd].rsize ? O_RDWR : O_WRONLY);	
  	if (IS_ERR(file))
  		return PTR_ERR(file);
  	err = file->f_op->write(file, p, map[cmd].wsize, &file->f_pos);
  	if (err >= 0 && map[cmd].rsize)
  		err = file->f_op->read(file, res, map[cmd].rsize, &file->f_pos);
  	if (err >= 0)
  		err = 0;
  	fput(file);
  	return err;
  }