linux-bk/fs/nfsctl.c
<<
>>
Prefs
   1/*
   2 *      fs/nfsctl.c
   3 *
   4 *      This should eventually move to userland.
   5 *
   6 */
   7#include <linux/config.h>
   8#include <linux/file.h>
   9#include <linux/fs.h>
  10#include <linux/sunrpc/svc.h>
  11#include <linux/nfsd/nfsd.h>
  12#include <linux/nfsd/syscall.h>
  13#include <linux/linkage.h>
  14#include <linux/namei.h>
  15#include <asm/uaccess.h>
  16
  17/*
  18 * open a file on nfsd fs
  19 */
  20
  21struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
  22
  23static struct file *do_open(char *name, int flags)
  24{
  25        struct nameidata nd;
  26        int error;
  27
  28        nd.mnt = do_kern_mount("nfsd", 0, "nfsd", NULL);
  29
  30        if (IS_ERR(nd.mnt))
  31                return (struct file *)nd.mnt;
  32
  33        nd.dentry = dget(nd.mnt->mnt_root);
  34        nd.last_type = LAST_ROOT;
  35        nd.flags = 0;
  36
  37        error = path_walk(name, &nd);
  38        if (error)
  39                return ERR_PTR(error);
  40
  41        if (flags == O_RDWR)
  42                error = may_open(&nd,MAY_READ|MAY_WRITE,FMODE_READ|FMODE_WRITE);
  43        else
  44                error = may_open(&nd, MAY_WRITE, FMODE_WRITE);
  45
  46        if (!error)
  47                return dentry_open(nd.dentry, nd.mnt, flags);
  48
  49        path_release(&nd);
  50        return ERR_PTR(error);
  51}
  52
  53static struct {
  54        char *name; int wsize; int rsize;
  55} map[] = {
  56        [NFSCTL_SVC]={"svc", sizeof(struct nfsctl_svc)},
  57        [NFSCTL_ADDCLIENT]={"add", sizeof(struct nfsctl_client)},
  58        [NFSCTL_DELCLIENT]={"del", sizeof(struct nfsctl_client)},
  59        [NFSCTL_EXPORT]={"export", sizeof(struct nfsctl_export)},
  60        [NFSCTL_UNEXPORT]={"unexport", sizeof(struct nfsctl_export)},
  61#ifdef notyet
  62        [NFSCTL_UGIDUPDATE]={"ugid", sizeof(struct nfsctl_uidmap)},
  63#endif
  64        [NFSCTL_GETFD]={"getfd", sizeof(struct nfsctl_fdparm), NFS_FHSIZE},
  65        [NFSCTL_GETFS]={"getfs", sizeof(struct nfsctl_fsparm), sizeof(struct knfsd_fh)},
  66};
  67
  68long
  69asmlinkage sys_nfsservctl(int cmd, struct nfsctl_arg *arg, void *res)
  70{
  71        struct file *file;
  72        void *p = &arg->u;
  73        int version;
  74        int err;
  75
  76        if (copy_from_user(&version, &arg->ca_version, sizeof(int)))
  77                return -EFAULT;
  78
  79        if (version != NFSCTL_VERSION) {
  80                printk(KERN_WARNING "nfsd: incompatible version in syscall.\n");
  81                return -EINVAL;
  82        }
  83
  84        if (cmd < 0 || cmd >= sizeof(map)/sizeof(map[0]) || !map[cmd].name)
  85                return -EINVAL;
  86
  87        file = do_open(map[cmd].name, map[cmd].rsize ? O_RDWR : O_WRONLY);      
  88        if (IS_ERR(file))
  89                return PTR_ERR(file);
  90        err = file->f_op->write(file, p, map[cmd].wsize, &file->f_pos);
  91        if (err >= 0 && map[cmd].rsize)
  92                err = file->f_op->read(file, res, map[cmd].rsize, &file->f_pos);
  93        if (err >= 0)
  94                err = 0;
  95        fput(file);
  96        return err;
  97}
  98
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.