#include "config.h"
#include <string.h>
+#include <sys/types.h>
+#include <asm/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
#include "nfslib.h"
+ /* if /proc/net/rpc/... exists, then
+ * write to it, as that interface is more stable.
+ * Write:
+ * client fsidtype fsid path
+ * to /proc/net/rpc/nfsd.fh/channel
+ * and
+ * client path expiry flags anonuid anongid fsid
+ * to /proc/net/rpc/nfsd.export/channel
+ */
+
+static int
+exp_unexp(struct nfsctl_export *exp, int export)
+{
+ FILE *f;
+ struct stat stb;
+ __u32 fsid;
+ char fsidstr[8];
+ __u16 dev;
+ __u32 inode;
+
+
+ f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
+ if (f == NULL) return -1;
+ qword_print(f, exp->ex_client);
+ qword_print(f, exp->ex_path);
+ if (export) {
+ qword_printint(f, 0x7fffffff);
+ qword_printint(f, exp->ex_flags);
+ qword_printint(f, exp->ex_anon_uid);
+ qword_printint(f, exp->ex_anon_gid);
+ qword_printint(f, exp->ex_dev);
+ } else
+ qword_printint(f, 1);
+
+ qword_eol(f);
+ fclose(f);
+
+ if (stat(exp->ex_path, &stb) != 0)
+ return -1;
+ f = fopen("/proc/net/rpc/nfsd.fh/channel", "w");
+ if (f==NULL) return -1;
+ if (exp->ex_flags & NFSEXP_FSID) {
+ qword_print(f,exp->ex_client);
+ qword_printint(f,1);
+ fsid = exp->ex_dev;
+ qword_printhex(f, (char*)&fsid, 4);
+ if (export) {
+ qword_printint(f, 0x7fffffff);
+ qword_print(f, exp->ex_path);
+ } else
+ qword_printint(f, 1);
+
+ qword_eol(f);
+ }
+ qword_print(f,exp->ex_client);
+ qword_printint(f,0);
+ dev = htons(major(stb.st_dev)); memcpy(fsidstr, &dev, 2);
+ dev = htons(minor(stb.st_dev)); memcpy(fsidstr+2, &dev, 2);
+ inode = stb.st_ino; memcpy(fsidstr+4, &inode, 4);
+
+ qword_printhex(f, fsidstr, 8);
+ if (export) {
+ qword_printint(f, 0x7fffffff);
+ qword_print(f, exp->ex_path);
+ } else
+ qword_printint(f, 1);
+ qword_eol(f);
+ fclose(f);
+ return 0;
+}
+
int
nfsexport(struct nfsctl_export *exp)
{
struct nfsctl_arg arg;
-
+ int fd;
+ if ((fd=open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY))>= 0) {
+ close(fd);
+ return exp_unexp(exp, 1);
+ }
arg.ca_version = NFSCTL_VERSION;
memcpy(&arg.ca_export, exp, sizeof(arg.ca_export));
return nfsctl(NFSCTL_EXPORT, &arg, NULL);
{
struct nfsctl_arg arg;
+ int fd;
+ if ((fd=open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY))>= 0) {
+ close(fd);
+ return exp_unexp(exp, 0);
+ }
+
arg.ca_version = NFSCTL_VERSION;
memcpy(&arg.ca_export, exp, sizeof(arg.ca_export));
return nfsctl(NFSCTL_UNEXPORT, &arg, NULL);