summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1994-01-31 20:25:06 +0000
committerMichael I. Bushnell <mib@gnu.org>1994-01-31 20:25:06 +0000
commit95b2e875b680c66de7b61915a9c7b075de88bc4a (patch)
treeae687e3e46d91cf71dd0cd804316ed541d57c9ae
parent5d3b78819c628a24025d004918ae905142ac4652 (diff)
Initial revision
-rw-r--r--libdiskfs/dir-link.c82
-rw-r--r--libdiskfs/dir-mkdir.c2
-rw-r--r--libdiskfs/dir-rename.c182
-rw-r--r--libdiskfs/dir-rmdir.c83
-rw-r--r--libdiskfs/dir-unlink.c2
-rw-r--r--libdiskfs/file-chauthor.c4
-rw-r--r--libdiskfs/file-chflags.c30
-rw-r--r--libdiskfs/file-chmod.c4
-rw-r--r--libdiskfs/file-chown.c8
-rw-r--r--libdiskfs/file-get-trans.c41
-rw-r--r--libdiskfs/file-get-transcntl.c2
-rw-r--r--libdiskfs/file-getcontrol.c41
-rw-r--r--libdiskfs/file-getfh.c2
-rw-r--r--libdiskfs/file-getlinknode.c41
-rw-r--r--libdiskfs/file-set-size.c2
-rw-r--r--libdiskfs/file-set-trans.c2
-rw-r--r--libdiskfs/file-statfs.c30
-rw-r--r--libdiskfs/file-sync.c2
-rw-r--r--libdiskfs/file-syncfs.c2
-rw-r--r--libdiskfs/file-utimes.c2
-rw-r--r--libdiskfs/io-pathconf.c31
-rw-r--r--libdiskfs/node-create.c98
22 files changed, 676 insertions, 17 deletions
diff --git a/libdiskfs/dir-link.c b/libdiskfs/dir-link.c
new file mode 100644
index 00000000..dbc4677b
--- /dev/null
+++ b/libdiskfs/dir-link.c
@@ -0,0 +1,82 @@
+/* libdiskfs implementation of fs.defs: dir_link
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "priv.h"
+
+/* Implement dir_link as described in <hurd/fs.defs>. */
+error_t
+diskfs_S_dir_link (struct protid *filecred,
+ struct protid *dircred,
+ char *name)
+{
+ struct node *np;
+ struct node *dnp;
+ struct dirstat *ds = alloca (diskfs_dirstat_size);
+ error_t error;
+
+ if (!filecred)
+ return EOPNOTSUPP;
+
+ np = filecred->po->np;
+ if (readonly)
+ return EROFS;
+
+ if (!dircred)
+ return EXDEV;
+
+ dnp = dircred->po->np;
+ mutex_lock (&dnp->lock);
+ /* This lock is safe since a non-directory is inherently a leaf */
+ /* XXX But we don't know yet that it is a non-directory */
+ mutex_lock (&np->lock);
+
+ if (S_ISDIR (np->dn_stat.st_mode))
+ error = EISDIR;
+ else if (np->dn_stat.st_nlink == LINK_MAX - 1)
+ error = EMLINK;
+ if (error)
+ goto out;
+
+ error = diskfs_lookup (dnp, name, CREATE, 0, ds, dircred);
+
+ if (error == EAGAIN)
+ error = EEXIST;
+ if (!error)
+ error = EEXIST;
+ if (error != ENOENT)
+ {
+ diskfs_drop_dirstat (ds);
+ goto out;
+ }
+
+ np->dn_stat.st_nlink++;
+ np->dn_set_ctime = 1;
+
+ diskfs_node_update (np, 1);
+
+ error = diskfs_direnter (dnp, name, np, ds, dircred);
+ if (error)
+ {
+ np->dn_stat.st_nlink--;
+ np->dn_set_ctime = 1;
+ }
+
+ out:
+ mutex_unlock (&dnp->lock);
+ mutex_unlock (&np->lock);
+ return error;
+}
diff --git a/libdiskfs/dir-mkdir.c b/libdiskfs/dir-mkdir.c
index 17ce9db1..27d88602 100644
--- a/libdiskfs/dir-mkdir.c
+++ b/libdiskfs/dir-mkdir.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: dir_mkdir
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
diff --git a/libdiskfs/dir-rename.c b/libdiskfs/dir-rename.c
new file mode 100644
index 00000000..e6985e10
--- /dev/null
+++ b/libdiskfs/dir-rename.c
@@ -0,0 +1,182 @@
+/* libdiskfs implementation of fs.defs: dir_rename
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "priv.h"
+
+/* To avoid races in checkpath, and to prevent a directory from being
+ simultaneously renamed by two processes, we serialize all renames of
+ directores with this lock */
+static struct mutex renamedirlock = MUTEX_INITIALIZER;
+static int renamedirinit;
+
+/* Implement dir_rename as described in <hurd/fs.defs>. */
+error_t
+diskfs_S_dir_rename (struct protid *fromcred,
+ char *fromname,
+ struct protid *tocred,
+ char *toname)
+{
+ struct node *fdp, *tdp, *fnp, *tnp, *tmpnp;
+ error_t err;
+ volatile int isdir;
+ struct dirstat *ds = alloca (diskfs_dirstat_size);
+
+ if (!fromcred)
+ return EOPNOTSUPP;
+
+ /* Verify that tocred really is a port to us XXX */
+ if (!tocred)
+ return EXDEV;
+
+ if (readonly)
+ return EROFS;
+
+ fdp = fromcred->po->np;
+ tdp = tocred->po->np;
+
+ tryagain:
+ /* Acquire the source; hold a reference to it. This
+ will prevent anyone from deleting it before we create
+ the new link. */
+ mutex_lock (&fdp->lock);
+ err = diskfs_lookup (fdp, fromname, LOOKUP, &fnp, 0, fromcred);
+ mutex_unlock (&fdp->lock);
+ if (err)
+ return err;
+
+ if (S_ISDIR (fnp->dn_stat.st_mode))
+ {
+ mutex_unlock (&fnp->lock);
+ if (!mutex_try_lock (&renamedirlock))
+ {
+ diskfs_nrele (fnp);
+ mutex_lock (&renamedirlock);
+ goto try_again;
+ }
+ err = diskfs_rename_dir (fdp, fnp, fromname, tdp, toname);
+ diskfs_nrele (fnp);
+ mutex_unlock (&renamedirlock);
+ return err;
+ }
+
+ mutex_unlock (&fnp->lock);
+
+ /* We now hold no locks */
+
+ /* Link the node into the new directory. */
+ mutex_lock (&tdp->lock);
+
+ err = diskfs_lookup (tdp, toname, RENAME, &tnp, ds, tocred);
+ if (err && err != ENOENT)
+ {
+ diskfs_drop_dirstat (ds);
+ diskfs_nrele (fnp);
+ mutex_unlock (&tdp->lock);
+ return err;
+ }
+
+ /* rename("foo", "link-to-foo") is guaranteed to return 0 and
+ do nothing by Posix. */
+ if (tnp == fnp)
+ {
+ diskfs_drop_dirstat (ds);
+ diskfs_nrele (fnp);
+ diskfs_nput (tnp);
+ mutex_unlock (&tdp->lock);
+ return 0;
+ }
+
+ /* rename("foo", dir) should fail. */
+ if (tnp && S_ISDIR (tnp->dn_stat.st_mode))
+ {
+ diskfs_drop_dirstat (ds);
+ diskfs_nrele (fnp);
+ mutex_unlock (&tdp->lock);
+ return EISDIR;
+ }
+
+ mutex_lock (&fnp->lock);
+
+ /* Increment the link count for the upcoming link */
+ if (fnp->dn_stat.st_nlink == LINK_MAX - 1)
+ {
+ diskfs_drop_dirstat (ds);
+ diskfs_nput (fnp);
+ mutex_unlock (&tdp->lock);
+ return EMLINK;
+ }
+ fnp->dn_stat.st_nlink++;
+ fnp->dn_set_ctime = 1;
+ diskfs_node_update (fnp, 1);
+
+ if (tnp)
+ {
+ err = diskfs_dirrewrite (tdp, fnp, ds);
+ if (!err)
+ {
+ tnp->dn_stat.st_nlink--;
+ tnp->dn_set_ctime = 1;
+ }
+ diskfs_nput (tnp);
+ }
+ else
+ err = diskfs_direnter (tdp, toname, fnp, ds, tocred);
+
+ mutex_unlock (&tdp->lock);
+ mutex_unlock (&fnp->lock);
+ if (err)
+ {
+ diskfs_nrele (fnp);
+ return err;
+ }
+
+ /* We now hold no locks */
+
+ /* Now we remove the source. Unfortunately, we haven't held
+ fdp locked (nor could we), so someone else might have already
+ removed it. */
+ mutex_lock (&fdp->lock);
+ err = diskfs_lookup (fdp, fromname, REMOVE, &tmpnp, ds, fromcred);
+ if (err)
+ {
+ diskfs_drop_dirstat (ds);
+ mutex_unlock (&fdp->lock);
+ diskfs_nrele (fnp);
+ return err;
+ }
+
+ if (tmpnp != fnp)
+ {
+ /* This is no longer the node being renamed, so just return. */
+ diskfs_drop_dirstat (ds);
+ diskfs_nput (tmpnp);
+ diskfs_nrele (fnp);
+ mutex_unlock (&fdp->lock);
+ return 0;
+ }
+
+ diskfs_nrele (tmpnp);
+
+ err = diskfs_dirremove (fdp, ds);
+
+ fnp->dn_stat.st_nlink--;
+ fnp->dn_set_ctime = 1;
+ diskfs_nput (fnp);
+ mutex_unlock (&fdp->lock);
+ return err;
+}
+#endif
diff --git a/libdiskfs/dir-rmdir.c b/libdiskfs/dir-rmdir.c
new file mode 100644
index 00000000..d34feaf4
--- /dev/null
+++ b/libdiskfs/dir-rmdir.c
@@ -0,0 +1,83 @@
+/* libdsikfs implementation of fs.defs: dir_rmdir
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "priv.h"
+
+/* Implement dir_rmdir as described in <hurd/fs.defs>. */
+error_t
+diskfs_S_dir_rmdir (struct protid *dircred,
+ char *name)
+{
+ struct node *dnp;
+ struct node *np = 0;
+ struct dirstat *ds = alloca (diskfs_dirstat_size);
+ error_t error;
+
+ if (!dircred)
+ return EOPNOTSUPP;
+
+ dnp = dircred->po->np;
+ if (readonly)
+ return EROFS;
+
+ mutex_lock (&dnp->lock);
+
+ error = diskfs_lookup (dnp, name, REMOVE, &np, ds, dircred);
+ if (error == EAGAIN)
+ error = ENOTEMPTY;
+ if (error)
+ {
+ mutex_unlock (&dnp->lock);
+ diskfs_drop_dirstat (ds);
+ return error;
+ }
+
+ /* Attempt to rmdir(".") */
+ if (dnp == np)
+ {
+ diskfs_nrele (np);
+ diskfs_drop_dirstat (ds);
+ mutex_unlock (&dnp->lock);
+ return EINVAL;
+ }
+
+ /* Verify the directory is empty (and valid). (Rmdir ".." won't be
+ valid since ".." will contain a reference to the current directory and
+ thus be non-empty). */
+ if (!diskfs_dirempty (np, dircred))
+ {
+ diskfs_nput (np);
+ diskfs_drop_dirstat (ds);
+ mutex_unlock (&dnp->lock);
+ return ENOTEMPTY;
+ }
+
+ error = diskfs_dirremove (dnp, ds);
+
+ if (!error)
+ {
+ np->dn_stat.st_nlink--;
+ np->dn_set_ctime = 1;
+ }
+
+ if (!error)
+ diskfs_clear_directory (np, dnp, dircred);
+
+ diskfs_nput (np);
+ mutex_unlock (&dnp->lock);
+ return 0;
+}
diff --git a/libdiskfs/dir-unlink.c b/libdiskfs/dir-unlink.c
index 76526832..f1a2f604 100644
--- a/libdiskfs/dir-unlink.c
+++ b/libdiskfs/dir-unlink.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: dir_unlink
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1993, 1994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
diff --git a/libdiskfs/file-chauthor.c b/libdiskfs/file-chauthor.c
index bbcb05f5..dfd5850e 100644
--- a/libdiskfs/file-chauthor.c
+++ b/libdiskfs/file-chauthor.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_chauthor
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -19,7 +19,7 @@
/* Implement file_chauthor as described in <hurd/fs.defs>. */
error_t
-diskfs_S_file_chauthor (struct protid *cred,
+S_file_chauthor (struct protid *cred,
uid_t author)
{
CHANGE_NODE_FIELD (cred,
diff --git a/libdiskfs/file-chflags.c b/libdiskfs/file-chflags.c
new file mode 100644
index 00000000..6fbef450
--- /dev/null
+++ b/libdiskfs/file-chflags.c
@@ -0,0 +1,30 @@
+/* libdiskfs implementation of fs.defs:file_chflags
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "priv.h"
+
+/* Implement file_chflags as described in <hurd/fs.defs>. */
+error_t
+dikfs_S_file_chflags (struct protid *cred,
+ int flags)
+{
+ CHANGE_NODE_FIELD (cred,
+ ({
+ if (!(err = isowner (np, cred)))
+ np->dn_stat.st_flags = flags;
+ }));
+}
diff --git a/libdiskfs/file-chmod.c b/libdiskfs/file-chmod.c
index cdb6b1c7..ee91189f 100644
--- a/libdiskfs/file-chmod.c
+++ b/libdiskfs/file-chmod.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_chmod
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -19,7 +19,7 @@
/* Implement file_chmod as described in <hurd/fs.defs>. */
error_t
-diskfs_S_file_chmod (struct protid *cred,
+S_file_chmod (struct protid *cred,
mode_t mode)
{
mode &= ~(S_IFMT | S_ISPARE);
diff --git a/libdiskfs/file-chown.c b/libdiskfs/file-chown.c
index 985b84ca..35893622 100644
--- a/libdiskfs/file-chown.c
+++ b/libdiskfs/file-chown.c
@@ -1,5 +1,5 @@
/* libdiskfs implementetation of fs.defs: file_chown
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -19,9 +19,9 @@
/* Implement file_chown as described in <hurd/fs.defs>. */
error_t
-diskfs_S_file_chown (struct protid *cred,
- uid_t uid,
- gid_t gid)
+S_file_chown (struct protid *cred,
+ uid_t uid,
+ gid_t gid)
{
CHANGE_NODE_FIELD (cred,
({
diff --git a/libdiskfs/file-get-trans.c b/libdiskfs/file-get-trans.c
new file mode 100644
index 00000000..2ff7fd33
--- /dev/null
+++ b/libdiskfs/file-get-trans.c
@@ -0,0 +1,41 @@
+/* libdiskfs implementation of fs.defs: file_get_translator
+ Copyright (C) 1993, 1994 Free Software Foundation
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "priv.h"
+
+/* Implement file_get_translator as described in <hurd/fs.defs>. */
+error_t
+diskfs_S_file_get_translator (struct protid *cred,
+ vm_address_t *trans)
+{
+ struct node *np;
+ error_t error;
+
+ if (!cred)
+ return EOPNOTSUPP;
+
+ np = cred->po->np;
+
+ mutex_lock (&np->lock);
+ if (!diskfs_node_translated (np))
+ error = EINVAL;
+ else
+ error = diskfs_get_translator (np, trans);
+ mutex_unlock (&np->lock);
+
+ return error;
+}
diff --git a/libdiskfs/file-get-transcntl.c b/libdiskfs/file-get-transcntl.c
index 539e3843..296bb046 100644
--- a/libdiskfs/file-get-transcntl.c
+++ b/libdiskfs/file-get-transcntl.c
@@ -1,5 +1,5 @@
/* libkdiskfs implementation of fs.defs: file_get_translator_cntl
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1993, 1994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
diff --git a/libdiskfs/file-getcontrol.c b/libdiskfs/file-getcontrol.c
new file mode 100644
index 00000000..ef6d3b4e
--- /dev/null
+++ b/libdiskfs/file-getcontrol.c
@@ -0,0 +1,41 @@
+/* libdiskfs implementation of fs.defs:file_getcontrol.c
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "priv.h"
+
+/* Implement file_getcontrol as described in <hurd/fs.defs>. */
+error_t
+diskfs_S_file_getcontrol (struct protid *cred,
+ mach_port_t *control,
+ mach_msg_type_name_t *controltype)
+{
+ int error = 0;;
+
+ if (!cred)
+ return EOPNOTSUPP;
+
+ if (!isuid (0, cred))
+ error = EPERM;
+ else
+ {
+ /* XXX nosenders race */
+ *control = fs_control_port;
+ *controltype = MACH_MSG_TYPE_MAKE_SEND;
+ }
+
+ return error;
+}
diff --git a/libdiskfs/file-getfh.c b/libdiskfs/file-getfh.c
index 637bfcde..899bc66b 100644
--- a/libdiskfs/file-getfh.c
+++ b/libdiskfs/file-getfh.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_getfh
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1993, 1994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
diff --git a/libdiskfs/file-getlinknode.c b/libdiskfs/file-getlinknode.c
new file mode 100644
index 00000000..2e284d43
--- /dev/null
+++ b/libdiskfs/file-getlinknode.c
@@ -0,0 +1,41 @@
+/* libdiskfs implementation of fs.defs: file_getlinknode
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "priv.h"
+
+/* Implement file_getlinknode as described in <hurd/fs.defs>. */
+error_t
+diskfs_S_file_getlinknode (struct protid *cred,
+ file_t *port,
+ mach_msg_type_name_t *portpoly)
+{
+ struct inode *np;
+
+ if (!cred)
+ return EOPNOTSUPP;
+
+ np = cred->po->np;
+ if (np->i_number == diskfs_root_node_number)
+ return EBUSY;
+
+ /* XXX -- this is wrong; port management code for protids
+ only allows a port to be given out once; we need to
+ send a new protid unfortunately. */
+ *port = cred->fspt.pi.port;
+ *portpoly = MACH_MSG_TYPE_MAKE_SEND;
+ return 0;
+}
diff --git a/libdiskfs/file-set-size.c b/libdiskfs/file-set-size.c
index be6c520f..2364a46c 100644
--- a/libdiskfs/file-set-size.c
+++ b/libdiskfs/file-set-size.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_truncate
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1993, 1994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
diff --git a/libdiskfs/file-set-trans.c b/libdiskfs/file-set-trans.c
index f63b9583..8cb790b0 100644
--- a/libdiskfs/file-set-trans.c
+++ b/libdiskfs/file-set-trans.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_set_translator
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1993, 1994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
diff --git a/libdiskfs/file-statfs.c b/libdiskfs/file-statfs.c
new file mode 100644
index 00000000..65931c1d
--- /dev/null
+++ b/libdiskfs/file-statfs.c
@@ -0,0 +1,30 @@
+/* libdiskfs implementation of fs.defs: file_statfs
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "priv.h"
+
+/* Implement file_getcontrol as described in <hurd/fs.defs>. */
+diskfs_S_file_statfs (struct protid *file,
+ fsys_statfsbuf_t *statbuf)
+{
+ if (!file)
+ return EOPNOTSUPP;
+
+ diskfs_set_statfs (statbuf);
+
+ return 0;
+}
diff --git a/libdiskfs/file-sync.c b/libdiskfs/file-sync.c
index 9c5a90d8..2e17bbd5 100644
--- a/libdiskfs/file-sync.c
+++ b/libdiskfs/file-sync.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_seek
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1993, 1994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
diff --git a/libdiskfs/file-syncfs.c b/libdiskfs/file-syncfs.c
index 8a63e218..45720f10 100644
--- a/libdiskfs/file-syncfs.c
+++ b/libdiskfs/file-syncfs.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_syncfs
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 1993, 1994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
diff --git a/libdiskfs/file-utimes.c b/libdiskfs/file-utimes.c
index 3952a266..7798d641 100644
--- a/libdiskfs/file-utimes.c
+++ b/libdiskfs/file-utimes.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_utimes
- Copyright (C) 1992, 1993, 1994 Free Software Foundation
+ Copyright (C) 19921994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
diff --git a/libdiskfs/io-pathconf.c b/libdiskfs/io-pathconf.c
new file mode 100644
index 00000000..8c09c55b
--- /dev/null
+++ b/libdiskfs/io-pathconf.c
@@ -0,0 +1,31 @@
+/* libdiskfs implementation of fs.defs: file_pathconf
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "priv.h"
+
+/* Implement file_pathconf as described in <hurd/fs.defs>. */
+error_t
+diskfs_S_file_pathconf (struct protid *cred,
+ int name,
+ int *value)
+ {
+ if (!cred)
+ return EOPNOTSUPP;
+
+ *value = 0; /* XXX */
+ return 0;
+}
diff --git a/libdiskfs/node-create.c b/libdiskfs/node-create.c
new file mode 100644
index 00000000..8a76e3d8
--- /dev/null
+++ b/libdiskfs/node-create.c
@@ -0,0 +1,98 @@
+/* Making new files
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "priv.h"
+
+/* Create a new node and link it into DIR with as NAME. Give it MODE;
+ if that includes IFDIR, also initialize `.' and `..' in the new
+ directory. Return the node in NPP. CRED identifies the user responsible
+ for the call, and DS is the result of a prior diskfs_lookup for creation. */
+error_t
+diskfs_create_and_link (struct node *dir,
+ char *name,
+ mode_t mode,
+ struct node **newnode,
+ struct protid *cred,
+ struct dirstat *ds)
+{
+ struct node *np;
+ error_t err;
+ int dirinc = 0;
+ int number;
+
+ /* Make the node */
+ err = diskfs_alloc_node (dir, mode, &number);
+ if (err)
+ {
+ diskfs_drop_dirstat (ds);
+ return err;
+ }
+ *newnode = np = diskfs_nget (newnode);
+
+ /* Initialize the on-disk fields. */
+
+ if (cred->nuids)
+ np->dn_stat.st_uid = cred->uids[0];
+ else
+ {
+ np->dn_stat.st_uid = dir->dn_stat.st_uid;
+ mode &= ~S_ISUID;
+ }
+
+ if (groupmember (dir->dn_stat.st_gid, cred))
+ np->dn_stat.st_gid = dir->dn_stat.st_gid;
+ else if (cred->ngids)
+ np->dn_stat.st_gid = cred->gids[0];
+ else
+ {
+ np->dn_stat.st_gid = dir->dn_stat.st_gid;
+ mode &= ~S_ISGID;
+ }
+
+ np->dn_stat.st_rdev = 0;
+ np->dn_stat.st_nlink = 1;
+ np->dn_stat.st_mode = mode;
+
+ np->dn_stat.st_blocks = 0;
+ np->dn_stat.st_size = 0;
+ np->dn_stat.st_flags = 0;
+ np->dn_set_atime = 1;
+ np->dn_set_mtime = 1;
+ np->dn_set_ctime = 1;
+
+ if (S_ISDIR (mode))
+ err = diskfs_init_dir (np, dir);
+
+ diskfs_node_update (np, 1);
+
+ if (err)
+ {
+ diskfs_drop_dirstat (ds);
+ return err;
+ }
+
+ err = diskfs_direnter (dir, name, np, ds, cred);
+ if (err)
+ {
+ if (S_ISDIR (mode))
+ diskfs_clear_directory (np);
+ np->dn_stat.st_nlink = 0;
+ np->dn_set_ctime = 1;
+ diskfs_nput (np);
+ }
+ return err;
+}