xref: /minix3/minix/lib/libsffs/verify.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc /* This file contains routines that verify inodes and paths against the host.
2*433d6423SLionel Sambuc  *
3*433d6423SLionel Sambuc  * The entry points into this file are:
4*433d6423SLionel Sambuc  *   verify_path	check whether a path,inode pair is still valid
5*433d6423SLionel Sambuc  *   verify_inode	construct a path for an inode and verify the inode
6*433d6423SLionel Sambuc  *   verify_dentry	check a directory inode and look for a directory entry
7*433d6423SLionel Sambuc  *
8*433d6423SLionel Sambuc  * Created:
9*433d6423SLionel Sambuc  *   April 2009 (D.C. van Moolenbroek)
10*433d6423SLionel Sambuc  */
11*433d6423SLionel Sambuc 
12*433d6423SLionel Sambuc #include "inc.h"
13*433d6423SLionel Sambuc 
14*433d6423SLionel Sambuc /*===========================================================================*
15*433d6423SLionel Sambuc  *				verify_path				     *
16*433d6423SLionel Sambuc  *===========================================================================*/
verify_path(char path[PATH_MAX],struct inode * ino,struct sffs_attr * attr,int * stale)17*433d6423SLionel Sambuc int verify_path(char path[PATH_MAX], struct inode *ino,
18*433d6423SLionel Sambuc 	struct sffs_attr *attr, int *stale)
19*433d6423SLionel Sambuc {
20*433d6423SLionel Sambuc /* Given a path, and the inode associated with that path, verify if the inode
21*433d6423SLionel Sambuc  * still matches the real world. Obtain the attributes of the file identified
22*433d6423SLionel Sambuc  * by the given path, and see if they match. If not, possibly mark the inode
23*433d6423SLionel Sambuc  * as deleted and return an error. Only upon success is the inode guaranteed
24*433d6423SLionel Sambuc  * to be usable.
25*433d6423SLionel Sambuc  *
26*433d6423SLionel Sambuc  * The caller must set the a_mask field of the passed attr struct.
27*433d6423SLionel Sambuc  * If 'stale' is not NULL, the value it points to must be initialized to 0,
28*433d6423SLionel Sambuc  * and will be set to 1 if the path was valid but the inode wasn't.
29*433d6423SLionel Sambuc  */
30*433d6423SLionel Sambuc   int r;
31*433d6423SLionel Sambuc 
32*433d6423SLionel Sambuc   attr->a_mask |= SFFS_ATTR_MODE;
33*433d6423SLionel Sambuc 
34*433d6423SLionel Sambuc   r = sffs_table->t_getattr(path, attr);
35*433d6423SLionel Sambuc 
36*433d6423SLionel Sambuc   dprintf(("%s: verify_path: getattr('%s') returned %d\n",
37*433d6423SLionel Sambuc 	sffs_name, path, r));
38*433d6423SLionel Sambuc 
39*433d6423SLionel Sambuc   if (r != OK) {
40*433d6423SLionel Sambuc 	/* If we are told that the path does not exist, delete the inode */
41*433d6423SLionel Sambuc 	if (r == ENOENT || r == ENOTDIR)
42*433d6423SLionel Sambuc 		del_dentry(ino);
43*433d6423SLionel Sambuc 
44*433d6423SLionel Sambuc 	return r; /* path isn't valid */
45*433d6423SLionel Sambuc   }
46*433d6423SLionel Sambuc 
47*433d6423SLionel Sambuc   /* If the file type (reg, dir) isn't what we thought, delete the inode */
48*433d6423SLionel Sambuc   if ((ino->i_flags & I_DIR) != MODE_TO_DIRFLAG(attr->a_mode)) {
49*433d6423SLionel Sambuc 	del_dentry(ino);
50*433d6423SLionel Sambuc 
51*433d6423SLionel Sambuc 	if (stale != NULL) *stale = 1;
52*433d6423SLionel Sambuc 	return ENOENT; /* path is valid, inode wasn't */
53*433d6423SLionel Sambuc   }
54*433d6423SLionel Sambuc 
55*433d6423SLionel Sambuc   return OK; /* path and inode are valid */
56*433d6423SLionel Sambuc }
57*433d6423SLionel Sambuc 
58*433d6423SLionel Sambuc /*===========================================================================*
59*433d6423SLionel Sambuc  *				verify_inode				     *
60*433d6423SLionel Sambuc  *===========================================================================*/
verify_inode(struct inode * ino,char path[PATH_MAX],struct sffs_attr * attr)61*433d6423SLionel Sambuc int verify_inode(
62*433d6423SLionel Sambuc 	struct inode *ino,    	/* inode to verify */
63*433d6423SLionel Sambuc 	char path[PATH_MAX],  	/* buffer in which to store the path */
64*433d6423SLionel Sambuc 	struct sffs_attr *attr	/* buffer for attributes, or NULL */
65*433d6423SLionel Sambuc )
66*433d6423SLionel Sambuc {
67*433d6423SLionel Sambuc /* Given an inode, construct a path identifying the inode, and check whether
68*433d6423SLionel Sambuc  * that path is still valid for that inode (as far as we can tell). As a side
69*433d6423SLionel Sambuc  * effect, store attributes in the given attribute structure if not NULL (its
70*433d6423SLionel Sambuc  * a_mask member must then be set).
71*433d6423SLionel Sambuc  */
72*433d6423SLionel Sambuc   struct sffs_attr attr2;
73*433d6423SLionel Sambuc   int r;
74*433d6423SLionel Sambuc 
75*433d6423SLionel Sambuc   if ((r = make_path(path, ino)) != OK) return r;
76*433d6423SLionel Sambuc 
77*433d6423SLionel Sambuc   if (attr == NULL) {
78*433d6423SLionel Sambuc 	attr2.a_mask = 0;
79*433d6423SLionel Sambuc 
80*433d6423SLionel Sambuc 	attr = &attr2;
81*433d6423SLionel Sambuc   }
82*433d6423SLionel Sambuc 
83*433d6423SLionel Sambuc   return verify_path(path, ino, attr, NULL);
84*433d6423SLionel Sambuc }
85*433d6423SLionel Sambuc 
86*433d6423SLionel Sambuc /*===========================================================================*
87*433d6423SLionel Sambuc  *				verify_dentry				     *
88*433d6423SLionel Sambuc  *===========================================================================*/
verify_dentry(struct inode * parent,char name[NAME_MAX+1],char path[PATH_MAX],struct inode ** res_ino)89*433d6423SLionel Sambuc int verify_dentry(
90*433d6423SLionel Sambuc 	struct inode *parent, 	/* parent inode: the inode to verify */
91*433d6423SLionel Sambuc 	char name[NAME_MAX+1],	/* the given directory entry path component */
92*433d6423SLionel Sambuc 	char path[PATH_MAX],  	/* buffer to store the resulting path in */
93*433d6423SLionel Sambuc 	struct inode **res_ino	/* pointer for addressed inode (or NULL) */
94*433d6423SLionel Sambuc )
95*433d6423SLionel Sambuc {
96*433d6423SLionel Sambuc /* Given a directory inode and a name, construct a path identifying that
97*433d6423SLionel Sambuc  * directory entry, check whether the path to the parent is still valid, and
98*433d6423SLionel Sambuc  * check whether there is an inode pointed to by the full path. Upon success,
99*433d6423SLionel Sambuc  * res_ino will contain either the inode for the full path, with increased
100*433d6423SLionel Sambuc  * refcount, or NULL if no such inode exists.
101*433d6423SLionel Sambuc  */
102*433d6423SLionel Sambuc   int r;
103*433d6423SLionel Sambuc 
104*433d6423SLionel Sambuc   if ((r = verify_inode(parent, path, NULL)) != OK)
105*433d6423SLionel Sambuc 	return r;
106*433d6423SLionel Sambuc 
107*433d6423SLionel Sambuc   dprintf(("%s: verify_dentry: given path is '%s', name '%s'\n",
108*433d6423SLionel Sambuc 	sffs_name, path, name));
109*433d6423SLionel Sambuc 
110*433d6423SLionel Sambuc   if ((r = push_path(path, name)) != OK)
111*433d6423SLionel Sambuc 	return r;
112*433d6423SLionel Sambuc 
113*433d6423SLionel Sambuc   dprintf(("%s: verify_dentry: path now '%s'\n", sffs_name, path));
114*433d6423SLionel Sambuc 
115*433d6423SLionel Sambuc   *res_ino = lookup_dentry(parent, name);
116*433d6423SLionel Sambuc 
117*433d6423SLionel Sambuc   return OK;
118*433d6423SLionel Sambuc }
119