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