Blame view

fs/nfsctl.c 2.37 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
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  #include <linux/file.h>
  #include <linux/fs.h>
  #include <linux/sunrpc/svc.h>
  #include <linux/nfsd/nfsd.h>
  #include <linux/nfsd/syscall.h>
  #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)
  {
  	struct nameidata nd;
16b6287a5   Josef 'Jeff' Sipek   nfsctl: use vfs_p...
26
  	struct vfsmount *mnt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
  	int error;
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

16b6287a5   Josef 'Jeff' Sipek   nfsctl: use vfs_p...
32
33
  	error = vfs_path_lookup(mnt->mnt_root, mnt, name, 0, &nd);
  	mntput(mnt);	/* drop do_kern_mount reference */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
  	if (error)
  		return ERR_PTR(error);
  
  	if (flags == O_RDWR)
  		error = may_open(&nd,MAY_READ|MAY_WRITE,FMODE_READ|FMODE_WRITE);
  	else
  		error = may_open(&nd, MAY_WRITE, FMODE_WRITE);
  
  	if (!error)
  		return dentry_open(nd.dentry, nd.mnt, flags);
  
  	path_release(&nd);
  	return ERR_PTR(error);
  }
  
  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)
  	},
  };
  
  long
  asmlinkage sys_nfsservctl(int cmd, struct nfsctl_arg __user *arg, void __user *res)
  {
  	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...
94
  	if (version != NFSCTL_VERSION)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96

e8c96f8c2   Tobias Klauser   [PATCH] fs: Use A...
97
  	if (cmd < 0 || cmd >= ARRAY_SIZE(map) || !map[cmd].name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
98
99
100
101
102
103
104
105
106
107
108
109
110
  		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;
  }