Bug #2277

tmpfs can't be nfs exported

Added by thomas.nikolajsen almost 3 years ago. Updated over 2 years ago.

Status:ResolvedStart date:01/17/2012
Priority:NormalDue date:
Assignee:vsrinivas% Done:

0%

Category:-
Target version:-

Description

Using fresh master (January 17th 2012)
nfs export of tmpfs mount point fails.

Errors from mountd(8) in /var/log/messages are:
can't export /tmp
bad exports list line /tmp -maproot

/etc/exports line: /tmp -maproot=root 127.0.0.1

(nfs export of mfs mount point works)

-thomas

History

#1 Updated by vsrinivas almost 3 years ago

  • Assignee set to vsrinivas

Initial patch, works locally; not extensively tested::

diff --git a/sys/vfs/tmpfs/tmpfs.h b/sys/vfs/tmpfs/tmpfs.h
index 4404cc6..609b1c1 100644
--- a/sys/vfs/tmpfs/tmpfs.h
+++ b/sys/vfs/tmpfs/tmpfs.h
@@ -399,6 +399,8 @@ struct tmpfs_mount {
struct objcache *tm_node_pool;

int tm_flags;
+
+ struct netexport tm_export;
};

#define TMPFS_LOCK(tm) lockmgr(&(tm)->allnode_lock, LK_EXCLUSIVE|LK_RETRY)
diff --git a/sys/vfs/tmpfs/tmpfs_vfsops.c b/sys/vfs/tmpfs/tmpfs_vfsops.c
index 940643a..9ad3084 100644
--- a/sys/vfs/tmpfs/tmpfs_vfsops.c
+++ b/sys/vfs/tmpfs/tmpfs_vfsops.c
@@ -145,12 +145,9 @@ tmpfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
gid_t root_gid = cred->cr_gid;
mode_t root_mode = (VREAD | VWRITE);

- if (mp->mnt_flag & MNT_UPDATE) {
- /* XXX: There is no support yet to update file system
- * settings. Should be added. */
-
- return EOPNOTSUPP;
- }
+ /* XXX */
+ if (mp->mnt_flag & MNT_UPDATE)
+ return (EOPNOTSUPP);

/*
* mount info
@@ -174,6 +171,7 @@ tmpfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
root_mode = args.ta_root_mode;
}

+
/*
* If mount by non-root, then verify that user has necessary
* permissions on the device.
@@ -518,6 +516,27 @@ tmpfs_vptofh(struct vnode *vp, struct fid *fhp)

/* --------------------------------------------------------------------- */

+static int
+tmpfs_checkexp(struct mount *mp, struct sockaddr *nam, int *exflagsp,
+ struct ucred **credanonp)
+{
+ struct tmpfs_mount *tmp;
+ struct netcred *nc;
+
+ tmp = (struct tmpfs_mount *) mp->mnt_data;
+ nc = vfs_export_lookup(mp, &tmp->tm_export, nam);
+ if (nc == NULL)
+ return (EACCES);
+
+ *exflagsp = nc->netc_exflags;
+ *credanonp = &nc->netc_anon;
+
+ return (0);
+}
+
+/* --------------------------------------------------------------------- */
+
+
/*
* tmpfs vfs operations.
*/
@@ -529,7 +548,8 @@ static struct vfsops tmpfs_vfsops = {
.vfs_statfs = tmpfs_statfs,
.vfs_fhtovp = tmpfs_fhtovp,
.vfs_vptofh = tmpfs_vptofh,
- .vfs_sync = vfs_stdsync
+ .vfs_sync = vfs_stdsync,
+ .vfs_checkexp = tmpfs_checkexp,
};

VFS_SET(tmpfs_vfsops, tmpfs, 0);
diff --git a/sys/vfs/tmpfs/tmpfs_vnops.c b/sys/vfs/tmpfs/tmpfs_vnops.c
index 3a5d7a0..9726272 100644
--- a/sys/vfs/tmpfs/tmpfs_vnops.c
+++ b/sys/vfs/tmpfs/tmpfs_vnops.c
@@ -48,6 +48,7 @@
#include <sys/unistd.h>
#include <sys/vfsops.h>
#include <sys/vnode.h>
+#include <sys/mountctl.h>

#include <vm/vm.h>
#include <vm/vm_object.h>
@@ -1680,6 +1681,33 @@ filt_tmpfsvnode(struct knote *kn, long hint)

/* --------------------------------------------------------------------- */

+static int
+tmpfs_mountctl(struct vop_mountctl_args *ap)
+{
+ struct tmpfs_mount *tmp;
+ struct mount *mp;
+ int rc;
+
+ switch (ap->a_op) {
+ case (MOUNTCTL_SET_EXPORT):
+ mp = ap->a_head.a_ops->head.vv_mount;
+ tmp = (struct tmpfs_mount *) mp->mnt_data;
+
+ if (ap->a_ctllen != sizeof(struct export_args))
+ rc = (EINVAL);
+ else
+ rc = vfs_export(mp, &tmp->tm_export,
+ (struct export_args *) ap->a_ctl);
+ break;
+ default:
+ rc = vop_stdmountctl(ap);
+ break;
+ }
+ return (rc);
+}
+
+/* --------------------------------------------------------------------- */
+
/*
* vnode operations vector used for files stored in a tmpfs file system.
*/
@@ -1699,6 +1727,7 @@ struct vop_ops tmpfs_vnode_vops = {
.vop_read = tmpfs_read,
.vop_write = tmpfs_write,
.vop_fsync = tmpfs_fsync,
+ .vop_mountctl = tmpfs_mountctl,
.vop_nremove = tmpfs_nremove,
.vop_nlink = tmpfs_nlink,
.vop_nrename = tmpfs_nrename,

#2 Updated by thomas.nikolajsen over 2 years ago

On current master (you did commit patch)
nfs mount on tmpfs now works somewhat:
- nfs export works
- nfs mount works
- 'cp /FILE /nfs' works (also 'cpdup /etc /nfs/etc')
- 'ls -la /nfs/FILE' works
- 'cat /nfs/FILE' works
- 'ls -la /nfs' doesn't show anything: no '.', '..' or 'FILE'

#3 Updated by vsrinivas over 2 years ago

Hmm, what OS for NFS client? How did you mount the tmpfs? I tested w/ a Linux 3.0.0-15 client, no such problems. Even ran fsx against it for a day before committing.

---

venkatesh@atlantis:/tmp/x$ cat ../typescript
Script started on Thu 02 Feb 2012 05:49:51 PM EST
atlantis% cp /tmp/qvsf.c /tmp/x
atlantis% ls -la /tmp/x/qvsf.c
-rw-r--r-- 1 me root 3922 2012-02-02 17:50 /tmp/x/qvsf.c
atlantis% cat /tmp/x/qvsf.c
/*-
* Quad-midvalue selection filter (QMVS) SF
*
* From four sensors, each of which can have noise, how do you select a
* correct value, given that sensors can fail?
....

atlantis% ls -la /tmp/x
total 8
drwxrwxrwt 25 root root 4096 2012-02-02 17:50 ..
-rw-r--r-- 1 me root 3922 2012-02-02 17:50 qvsf.c
atlantis% exit

Script done on Thu 02 Feb 2012 05:50:33 PM EST

#4 Updated by thomas.nikolajsen over 2 years ago

I use DragonFly for NFS client.
Setup like in original problem description;
but it behaves the same with remote DragonFly NFS server.

It turns out that it works w/o ReaddirPlus,
which is on by default on DragonFly.
(or using NFS protocol version 2, which doesn't support ReaddirPlus)

mount -o nordirplus /tmp-nfs

- fstab
127.0.0.1:/tmp /tmp-nfs nfs rw

#5 Updated by vsrinivas over 2 years ago

I repeated the test w/ a Linux NFS client, making sure to use NFS v3, over TCP, with readdirplus on. I made sure readdirplus requests were being issued via nfsstat. It still works fine... perhaps something is upsetting our nfs client?

#6 Updated by vsrinivas over 2 years ago

Some notes:

1) fsx on Linux itself complains of 'no extend on truncate! not posix!', with or without readdirplus
This complaint is present on HAMMER shares also.

ftruncate(fd, 0); ftruncate(fd, 100000); fstat(fd, &sb);
sb.st_size != 100000.

This problem goes away when -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 is used on Linux, even though all file sizes in the test would fit w/o large file support.

strace cannot trace fsx when its binary is present on a HAMMER or tmpfs share; strace can't be built w/ the necessary LARGEFILE/FILE_OFFSET stuff.

2) with a DragonFly vkernel as the nfs client, fsx also passes, with both readdirplus and non-readdirplus mounts. With readdirplus on, I wasn't able to reproduce the problem you had above?

3)
(/tmp/x is an NFS mount of tmpfs; DF 2.13-DEVELOPMENT DragonFly 2.13-DEVELOPMENT #7: Sat Dec 31 01:21:33 EST 2011 on client, -master on server).

$ ls
$ cp /tmp/bb.c /tmp/x
$ ls -la /tmp/x/bb.c
-rw-r--r-- 1 me wheel 3922 Feb 4 00:17 /tmp/x/bb.c
$ ls -la /tmp/x
total 5101
drwxrwxrwt 6 root wheel 512 Feb 4 00:17 ..
-rw-r--r-- 1 me wheel 0 Feb 3 23:29 22
-rw-rw-r-- 1 me wheel 5087764 Feb 3 23:13 CT_Course_Maps_20110313.pdf
-rw-r--r-- 1 me wheel 3922 Feb 4 00:16 aa.c
-rw-r--r-- 1 me wheel 3922 Feb 4 00:17 bb.c
-rwxr-xr-x 1 me wheel 23939 Feb 4 00:11 dfsx
-rw-r--r-- 1 me wheel 169 Feb 3 23:28 f.c
-rw-r--r-- 1 me wheel 24298 Feb 4 00:10 fsx-linux.c
-rwxr-xr-x 1 me wheel 26463 Feb 3 23:56 fsx128
-rw-r--r-- 1 me wheel 3922 Feb 4 00:16 qvsf.c
-rw-r--r-- 1 me wheel 331 Feb 3 23:40 t.c
$

#7 Updated by vsrinivas over 2 years ago

I'd like to close this bug as fixed; are there any failures left? Any reason we shouldn't?

#8 Updated by thomas.nikolajsen over 2 years ago

  • Status changed from New to Resolved

Closing;
tmpfs can be NFS exported now, thanks.

A minor problem, as described on issue log,
is that readdirplus isn't supported from DragonFly NFS client.
This is used by default on DragonFly NFS client.
Will update tmpfs.5 with info on NFS support & this issue.

Will also MFC to rel3_0.

Also available in: Atom PDF