servers/hgfs/hgfs_server => servers/hgfs servers/hgfs/libhgfs => lib/libhgfs servers/rs/service => commands/service drivers/memory/memory_driver => drivers/memory drivers/memory/ramdisk => drivers/ramdisk
		
			
				
	
	
		
			119 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			119 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				     *
 | 
						|
 *===========================================================================*/
 | 
						|
PUBLIC int verify_path(path, ino, attr, stale)
 | 
						|
char path[PATH_MAX];
 | 
						|
struct inode *ino;
 | 
						|
struct hgfs_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 |= HGFS_ATTR_MODE;
 | 
						|
 | 
						|
  r = hgfs_getattr(path, attr);
 | 
						|
 | 
						|
  dprintf(("HGFS: verify_path: getattr('%s') returned %d\n", 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				     *
 | 
						|
 *===========================================================================*/
 | 
						|
PUBLIC int verify_inode(ino, path, attr)
 | 
						|
struct inode *ino;		/* inode to verify */
 | 
						|
char path[PATH_MAX];		/* buffer in which to store the path */
 | 
						|
struct hgfs_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 hgfs_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				     *
 | 
						|
 *===========================================================================*/
 | 
						|
PUBLIC 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(("HGFS: verify_dentry: given path is '%s', name '%s'\n", path,
 | 
						|
	name));
 | 
						|
 | 
						|
  if ((r = push_path(path, name)) != OK)
 | 
						|
	return r;
 | 
						|
 | 
						|
  dprintf(("HGFS: verify_dentry: path now '%s'\n", path));
 | 
						|
 | 
						|
  *res_ino = lookup_dentry(parent, name);
 | 
						|
 | 
						|
  return OK;
 | 
						|
}
 |