diff options
author | Michael I. Bushnell <mib@gnu.org> | 1994-01-31 20:25:06 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1994-01-31 20:25:06 +0000 |
commit | 95b2e875b680c66de7b61915a9c7b075de88bc4a (patch) | |
tree | ae687e3e46d91cf71dd0cd804316ed541d57c9ae | |
parent | 5d3b78819c628a24025d004918ae905142ac4652 (diff) |
Initial revision
-rw-r--r-- | libdiskfs/dir-link.c | 82 | ||||
-rw-r--r-- | libdiskfs/dir-mkdir.c | 2 | ||||
-rw-r--r-- | libdiskfs/dir-rename.c | 182 | ||||
-rw-r--r-- | libdiskfs/dir-rmdir.c | 83 | ||||
-rw-r--r-- | libdiskfs/dir-unlink.c | 2 | ||||
-rw-r--r-- | libdiskfs/file-chauthor.c | 4 | ||||
-rw-r--r-- | libdiskfs/file-chflags.c | 30 | ||||
-rw-r--r-- | libdiskfs/file-chmod.c | 4 | ||||
-rw-r--r-- | libdiskfs/file-chown.c | 8 | ||||
-rw-r--r-- | libdiskfs/file-get-trans.c | 41 | ||||
-rw-r--r-- | libdiskfs/file-get-transcntl.c | 2 | ||||
-rw-r--r-- | libdiskfs/file-getcontrol.c | 41 | ||||
-rw-r--r-- | libdiskfs/file-getfh.c | 2 | ||||
-rw-r--r-- | libdiskfs/file-getlinknode.c | 41 | ||||
-rw-r--r-- | libdiskfs/file-set-size.c | 2 | ||||
-rw-r--r-- | libdiskfs/file-set-trans.c | 2 | ||||
-rw-r--r-- | libdiskfs/file-statfs.c | 30 | ||||
-rw-r--r-- | libdiskfs/file-sync.c | 2 | ||||
-rw-r--r-- | libdiskfs/file-syncfs.c | 2 | ||||
-rw-r--r-- | libdiskfs/file-utimes.c | 2 | ||||
-rw-r--r-- | libdiskfs/io-pathconf.c | 31 | ||||
-rw-r--r-- | libdiskfs/node-create.c | 98 |
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; +} |