minix/lib/libsffs/verify.c
David van Moolenbroek ef7b484e5c Create SFFS library out of HGFS
This Shared Folders File System library (libsffs) now contains all the
file system logic originally in HGFS. The actual HGFS server code is
now a stub that passes on all the work to libsffs. The libhgfs library
is changed accordingly.
2012-04-09 18:08:26 +02:00

120 lines
3.9 KiB
C

/* This file contains routines that verify inodes and paths against the host.
*
* The entry points into this file are:
* verify_path check whether a path,inode pair is still valid
* verify_inode construct a path for an inode and verify the inode
* verify_dentry check a directory inode and look for a directory entry
*
* Created:
* April 2009 (D.C. van Moolenbroek)
*/
#include "inc.h"
/*===========================================================================*
* verify_path *
*===========================================================================*/
int verify_path(path, ino, attr, stale)
char path[PATH_MAX];
struct inode *ino;
struct sffs_attr *attr;
int *stale;
{
/* Given a path, and the inode associated with that path, verify if the inode
* still matches the real world. Obtain the attributes of the file identified
* by the given path, and see if they match. If not, possibly mark the inode
* as deleted and return an error. Only upon success is the inode guaranteed
* to be usable.
*
* The caller must set the a_mask field of the passed attr struct.
* If 'stale' is not NULL, the value it points to must be initialized to 0,
* and will be set to 1 if the path was valid but the inode wasn't.
*/
int r;
attr->a_mask |= SFFS_ATTR_MODE;
r = sffs_table->t_getattr(path, attr);
dprintf(("%s: verify_path: getattr('%s') returned %d\n",
sffs_name, path, r));
if (r != OK) {
/* If we are told that the path does not exist, delete the inode */
if (r == ENOENT || r == ENOTDIR)
del_dentry(ino);
return r; /* path isn't valid */
}
/* If the file type (reg, dir) isn't what we thought, delete the inode */
if ((ino->i_flags & I_DIR) != MODE_TO_DIRFLAG(attr->a_mode)) {
del_dentry(ino);
if (stale != NULL) *stale = 1;
return ENOENT; /* path is valid, inode wasn't */
}
return OK; /* path and inode are valid */
}
/*===========================================================================*
* verify_inode *
*===========================================================================*/
int verify_inode(ino, path, attr)
struct inode *ino; /* inode to verify */
char path[PATH_MAX]; /* buffer in which to store the path */
struct sffs_attr *attr; /* buffer for attributes, or NULL */
{
/* Given an inode, construct a path identifying the inode, and check whether
* that path is still valid for that inode (as far as we can tell). As a side
* effect, store attributes in the given attribute structure if not NULL (its
* a_mask member must then be set).
*/
struct sffs_attr attr2;
int r;
if ((r = make_path(path, ino)) != OK) return r;
if (attr == NULL) {
attr2.a_mask = 0;
attr = &attr2;
}
return verify_path(path, ino, attr, NULL);
}
/*===========================================================================*
* verify_dentry *
*===========================================================================*/
int verify_dentry(parent, name, path, res_ino)
struct inode *parent; /* parent inode: the inode to verify */
char name[NAME_MAX+1]; /* the given directory entry path component */
char path[PATH_MAX]; /* buffer to store the resulting path in */
struct inode **res_ino; /* pointer for addressed inode (or NULL) */
{
/* Given a directory inode and a name, construct a path identifying that
* directory entry, check whether the path to the parent is still valid, and
* check whether there is an inode pointed to by the full path. Upon success,
* res_ino will contain either the inode for the full path, with increased
* refcount, or NULL if no such inode exists.
*/
int r;
if ((r = verify_inode(parent, path, NULL)) != OK)
return r;
dprintf(("%s: verify_dentry: given path is '%s', name '%s'\n",
sffs_name, path, name));
if ((r = push_path(path, name)) != OK)
return r;
dprintf(("%s: verify_dentry: path now '%s'\n", sffs_name, path));
*res_ino = lookup_dentry(parent, name);
return OK;
}