dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / fs.d / nfs / nfslog / fhtab.c
blob737d642ffd00c671e0605c51fe82562ed8e1407c
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
28 * Code to maintain the runtime and on-disk filehandle mapping table for
29 * nfslog.
32 #include <assert.h>
33 #include <errno.h>
34 #include <nfs/nfs.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <syslog.h>
39 #include <libintl.h>
40 #include <unistd.h>
41 #include <nfs/nfs.h>
42 #include <nfs/nfs_log.h>
43 #include "fhtab.h"
44 #include "nfslogd.h"
46 #define ROUNDUP32(val) (((val) + 3) & ~3)
48 #define IS_DOT_FILENAME(name) \
49 ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0))
51 #define PRINT_LINK_DATA(fp, func, dfh, name, str) \
52 (void) fprintf(fp, "%s: name '%s', dfh ", \
53 func, (((name) != NULL) ? name : "")); \
54 debug_opaque_print(fp, dfh, sizeof (*(dfh))); \
55 (void) fprintf(fp, "%s\n", str);
58 #define PRINT_FULL_DATA(fp, func, dfh, fh, name, str) \
59 (void) fprintf(fp, "%s: name '%s', dfh ", \
60 func, (((name) != NULL) ? name : "")); \
61 debug_opaque_print(fp, dfh, sizeof (*(dfh))); \
62 if ((fh) != NULL) { \
63 (void) fprintf(fp, ", fh "); \
64 debug_opaque_print(fp, fh, sizeof (*(fh))); \
65 } \
66 (void) fprintf(fp, "%s\n", str);
69 * export handle cache
71 struct export_handle_cache {
72 fhandle_t fh;
73 char *name;
74 struct export_handle_cache *next;
77 static struct export_handle_cache *exp_handle_cache = NULL;
79 extern bool_t nfsl_prin_fh;
81 static int fh_add(char *, fhandle_t *, fhandle_t *, char *);
83 static char *get_export_path(fhandle_t *, char *);
84 static void sprint_fid(char *, uint_t, const fhandle_t *);
85 static void fh_print_all_keys(char *fhpath, fhandle_t *fh);
86 static int fh_compare(fhandle_t *fh1, fhandle_t *fh2);
87 static fhlist_ent *fh_lookup(char *fhpath, fhandle_t *fh, fhlist_ent *fhrecp,
88 int *errorp);
89 static int fh_remove_mc_link(char *fhpath, fhandle_t *dfh, char *name,
90 char **pathp);
91 static int fh_remove(char *fhpath, fhandle_t *dfh, char *name, char **pathp);
92 static int fh_rename(char *fhpath, fhandle_t *from_dfh, char *from_name,
93 char **from_pathp, fhandle_t *to_dfh, char *to_name);
95 static fhlist_ent *fh_lookup_link(char *fhpath, fhandle_t *dfh, fhandle_t *fh,
96 char *name, fhlist_ent *fhrecp, int *errorp);
97 static struct nfsl_fh_proc_disp *nfslog_find_fh_dispatch(
98 nfslog_request_record *);
99 static struct export_handle_cache *find_fh_in_export_cache(fhandle_t *fh);
100 static void add_fh_to_export_cache(fhandle_t *fh, char *path);
101 static char *update_export_point(char *fhpath, fhandle_t *fh, char *path);
102 static char *fh_print_absolute(char *fhpath, fhandle_t *fh, char *name);
103 static void nfslog_null_fhargs(caddr_t *nfsl_args, caddr_t *nfsl_res,
104 char *fhpath, char **pathp1, char **pathp2);
105 static void nfslog_LOOKUP_calc(fhandle_t *dfh, char *name, fhandle_t *fh,
106 char *fhpath, char **pathp1, char **pathp2, char *str);
109 * NFS VERSION 2
113 * Functions for updating the fhtable for fhtoppath and for returning
114 * the absolute pathname
116 static void nfslog_GETATTR2_fhargs(fhandle_t *,
117 nfsstat *, char *fhpath, char **, char **);
118 static void nfslog_SETATTR2_fhargs(nfslog_setattrargs *, nfsstat *,
119 char *, char **, char **);
120 static void nfslog_LOOKUP2_fhargs(nfslog_diropargs *, nfslog_diropres *,
121 char *, char **, char **);
122 static void nfslog_READLINK2_fhargs(fhandle_t *, nfslog_rdlnres *,
123 char *, char **, char **);
124 static void nfslog_READ2_fhargs(nfslog_nfsreadargs *, nfslog_rdresult *,
125 char *, char **, char **);
126 static void nfslog_WRITE2_fhargs(nfslog_writeargs *, nfslog_writeresult *,
127 char *, char **, char **);
128 static void nfslog_CREATE2_fhargs(nfslog_createargs *, nfslog_diropres*,
129 char *, char **, char **);
130 static void nfslog_REMOVE2_fhargs(nfslog_diropargs *, nfsstat *,
131 char *, char **, char **);
132 static void nfslog_RENAME2_fhargs(nfslog_rnmargs *, nfsstat *,
133 char *, char **, char **);
134 static void nfslog_LINK2_fhargs(nfslog_linkargs *, nfsstat *,
135 char *, char **, char **);
136 static void nfslog_SYMLINK2_fhargs(nfslog_symlinkargs *, nfsstat *,
137 char *, char **, char **);
138 static void nfslog_READDIR2_fhargs(nfslog_rddirargs *, nfslog_rddirres *,
139 char *, char **, char **);
140 static void nfslog_STATFS2_fhargs(fhandle_t *, nfsstat *,
141 char *, char **, char **);
144 * NFS VERSION 3
146 * Functions for updating the fhtable for fhtoppath
148 static void nfslog_GETATTR3_fhargs(nfs_fh3 *, nfsstat3 *,
149 char *, char **, char **);
150 static void nfslog_SETATTR3_fhargs(nfslog_SETATTR3args *, nfsstat3 *,
151 char *, char **, char **);
152 static void nfslog_LOOKUP3_fhargs(nfslog_diropargs3 *, nfslog_LOOKUP3res *,
153 char *, char **, char **);
154 static void nfslog_ACCESS3_fhargs(nfs_fh3 *, nfsstat3 *,
155 char *, char **, char **);
156 static void nfslog_READLINK3_fhargs(nfs_fh3 *, nfslog_READLINK3res *,
157 char *, char **, char **);
158 static void nfslog_READ3_fhargs(nfslog_READ3args *, nfslog_READ3res *,
159 char *, char **, char **);
160 static void nfslog_WRITE3_fhargs(nfslog_WRITE3args *, nfslog_WRITE3res *,
161 char *, char **, char **);
162 static void nfslog_CREATE3_fhargs(nfslog_CREATE3args *, nfslog_CREATE3res *,
163 char *, char **, char **);
164 static void nfslog_MKDIR3_fhargs(nfslog_MKDIR3args *, nfslog_MKDIR3res *,
165 char *, char **, char **);
166 static void nfslog_SYMLINK3_fhargs(nfslog_SYMLINK3args *, nfslog_SYMLINK3res *,
167 char *, char **, char **);
168 static void nfslog_MKNOD3_fhargs(nfslog_MKNOD3args *, nfslog_MKNOD3res *,
169 char *, char **, char **);
170 static void nfslog_REMOVE3_fhargs(nfslog_REMOVE3args *, nfsstat3 *,
171 char *, char **, char **);
172 static void nfslog_RMDIR3_fhargs(nfslog_RMDIR3args *, nfsstat3 *,
173 char *, char **, char **);
174 static void nfslog_RENAME3_fhargs(nfslog_RENAME3args *, nfsstat3 *,
175 char *, char **, char **);
176 static void nfslog_LINK3_fhargs(nfslog_LINK3args *, nfsstat3 *,
177 char *, char **, char **);
178 static void nfslog_READDIR3_fhargs(nfs_fh3 *, nfsstat3 *,
179 char *, char **, char **);
180 static void nfslog_READDIRPLUS3_fhargs(nfslog_READDIRPLUS3args *,
181 nfslog_READDIRPLUS3res *,
182 char *, char **, char **);
183 static void nfslog_FSSTAT3_fhargs(nfs_fh3 *, nfsstat3 *,
184 char *, char **, char **);
185 static void nfslog_FSINFO3_fhargs(nfs_fh3 *, nfsstat3 *,
186 char *, char **, char **);
187 static void nfslog_PATHCONF3_fhargs(nfs_fh3 *, nfsstat3 *,
188 char *, char **, char **);
189 static void nfslog_COMMIT3_fhargs(nfslog_COMMIT3args *, nfsstat3 *,
190 char *, char **, char **);
193 * NFSLOG VERSION 1
195 * Functions for updating the fhtable for fhtoppath
197 static void nfslog_SHARE_fhargs(nfslog_sharefsargs *, nfslog_sharefsres *,
198 char *, char **, char **);
199 static void nfslog_UNSHARE_fhargs(nfslog_sharefsargs *, nfslog_sharefsres *,
200 char *, char **, char **);
201 static void nfslog_GETFH_fhargs(nfslog_getfhargs *, nfsstat *,
202 char *, char **, char **);
205 * Define the actions taken per prog/vers/proc:
207 * In some cases, the nl types are the same as the nfs types and a simple
208 * bcopy should suffice. Rather that define tens of identical procedures,
209 * simply define these to bcopy. Similarly this takes care of different
210 * procs that use same parameter struct.
213 static struct nfsl_fh_proc_disp nfsl_fh_proc_v2[] = {
215 * NFS VERSION 2
218 /* RFS_NULL = 0 */
219 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0},
221 /* RFS_GETATTR = 1 */
222 {nfslog_GETATTR2_fhargs, xdr_fhandle, xdr_nfsstat,
223 sizeof (fhandle_t), sizeof (nfsstat)},
225 /* RFS_SETATTR = 2 */
226 {nfslog_SETATTR2_fhargs, xdr_nfslog_setattrargs, xdr_nfsstat,
227 sizeof (nfslog_setattrargs), sizeof (nfsstat)},
229 /* RFS_ROOT = 3 *** NO LONGER SUPPORTED *** */
230 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0},
232 /* RFS_LOOKUP = 4 */
233 {nfslog_LOOKUP2_fhargs, xdr_nfslog_diropargs, xdr_nfslog_diropres,
234 sizeof (nfslog_diropargs), sizeof (nfslog_diropres)},
236 /* RFS_READLINK = 5 */
237 {nfslog_READLINK2_fhargs, xdr_fhandle, xdr_nfslog_rdlnres,
238 sizeof (fhandle_t), sizeof (nfslog_rdlnres)},
240 /* RFS_READ = 6 */
241 {nfslog_READ2_fhargs, xdr_nfslog_nfsreadargs, xdr_nfslog_rdresult,
242 sizeof (nfslog_nfsreadargs), sizeof (nfslog_rdresult)},
244 /* RFS_WRITECACHE = 7 *** NO LONGER SUPPORTED *** */
245 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0},
247 /* RFS_WRITE = 8 */
248 {nfslog_WRITE2_fhargs, xdr_nfslog_writeargs, xdr_nfslog_writeresult,
249 sizeof (nfslog_writeargs), sizeof (nfslog_writeresult)},
251 /* RFS_CREATE = 9 */
252 {nfslog_CREATE2_fhargs, xdr_nfslog_createargs, xdr_nfslog_diropres,
253 sizeof (nfslog_createargs), sizeof (nfslog_diropres)},
255 /* RFS_REMOVE = 10 */
256 {nfslog_REMOVE2_fhargs, xdr_nfslog_diropargs, xdr_nfsstat,
257 sizeof (nfslog_diropargs), sizeof (nfsstat)},
259 /* RFS_RENAME = 11 */
260 {nfslog_RENAME2_fhargs, xdr_nfslog_rnmargs, xdr_nfsstat,
261 sizeof (nfslog_rnmargs), sizeof (nfsstat)},
263 /* RFS_LINK = 12 */
264 {nfslog_LINK2_fhargs, xdr_nfslog_linkargs, xdr_nfsstat,
265 sizeof (nfslog_linkargs), sizeof (nfsstat)},
267 /* RFS_SYMLINK = 13 */
268 {nfslog_SYMLINK2_fhargs, xdr_nfslog_symlinkargs, xdr_nfsstat,
269 sizeof (nfslog_symlinkargs), sizeof (nfsstat)},
271 /* RFS_MKDIR = 14 */
272 {nfslog_CREATE2_fhargs, xdr_nfslog_createargs, xdr_nfslog_diropres,
273 sizeof (nfslog_createargs), sizeof (nfslog_diropres)},
275 /* RFS_RMDIR = 15 */
276 {nfslog_REMOVE2_fhargs, xdr_nfslog_diropargs, xdr_nfsstat,
277 sizeof (nfslog_diropargs), sizeof (nfsstat)},
279 /* RFS_READDIR = 16 */
280 {nfslog_READDIR2_fhargs, xdr_nfslog_rddirargs, xdr_nfslog_rddirres,
281 sizeof (nfslog_rddirargs), sizeof (nfslog_rddirres)},
283 /* RFS_STATFS = 17 */
284 {nfslog_STATFS2_fhargs, xdr_fhandle, xdr_nfsstat,
285 sizeof (fhandle_t), sizeof (nfsstat)},
290 * NFS VERSION 3
293 static struct nfsl_fh_proc_disp nfsl_fh_proc_v3[] = {
295 /* RFS_NULL = 0 */
296 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0},
298 /* RFS3_GETATTR = 1 */
299 {nfslog_GETATTR3_fhargs, xdr_nfs_fh3, xdr_nfsstat3,
300 sizeof (nfs_fh3), sizeof (nfsstat3)},
302 /* RFS3_SETATTR = 2 */
303 {nfslog_SETATTR3_fhargs, xdr_nfslog_SETATTR3args, xdr_nfsstat3,
304 sizeof (nfslog_SETATTR3args), sizeof (nfsstat3)},
306 /* RFS3_LOOKUP = 3 */
307 {nfslog_LOOKUP3_fhargs, xdr_nfslog_diropargs3, xdr_nfslog_LOOKUP3res,
308 sizeof (nfslog_diropargs3), sizeof (nfslog_LOOKUP3res)},
310 /* RFS3_ACCESS = 4 */
311 {nfslog_ACCESS3_fhargs, xdr_nfs_fh3, xdr_nfsstat3,
312 sizeof (nfs_fh3), sizeof (nfsstat3)},
314 /* RFS3_READLINK = 5 */
315 {nfslog_READLINK3_fhargs, xdr_nfs_fh3, xdr_nfslog_READLINK3res,
316 sizeof (nfs_fh3), sizeof (nfslog_READLINK3res)},
318 /* RFS3_READ = 6 */
319 {nfslog_READ3_fhargs, xdr_nfslog_READ3args, xdr_nfslog_READ3res,
320 sizeof (nfslog_READ3args), sizeof (nfslog_READ3res)},
322 /* RFS3_WRITE = 7 */
323 {nfslog_WRITE3_fhargs, xdr_nfslog_WRITE3args, xdr_nfslog_WRITE3res,
324 sizeof (nfslog_WRITE3args), sizeof (nfslog_WRITE3res)},
326 /* RFS3_CREATE = 8 */
327 {nfslog_CREATE3_fhargs, xdr_nfslog_CREATE3args, xdr_nfslog_CREATE3res,
328 sizeof (nfslog_CREATE3args), sizeof (nfslog_CREATE3res)},
330 /* RFS3_MKDIR = 9 */
331 {nfslog_MKDIR3_fhargs, xdr_nfslog_MKDIR3args, xdr_nfslog_MKDIR3res,
332 sizeof (nfslog_MKDIR3args), sizeof (nfslog_MKDIR3res)},
334 /* RFS3_SYMLINK = 10 */
335 {nfslog_SYMLINK3_fhargs, xdr_nfslog_SYMLINK3args,
336 xdr_nfslog_SYMLINK3res,
337 sizeof (nfslog_SYMLINK3args), sizeof (nfslog_SYMLINK3res)},
339 /* RFS3_MKNOD = 11 */
340 {nfslog_MKNOD3_fhargs, xdr_nfslog_MKNOD3args, xdr_nfslog_MKNOD3res,
341 sizeof (nfslog_MKNOD3args), sizeof (nfslog_MKNOD3res)},
343 /* RFS3_REMOVE = 12 */
344 {nfslog_REMOVE3_fhargs, xdr_nfslog_REMOVE3args, xdr_nfsstat3,
345 sizeof (nfslog_REMOVE3args), sizeof (nfsstat3)},
347 /* RFS3_RMDIR = 13 */
348 {nfslog_RMDIR3_fhargs, xdr_nfslog_RMDIR3args, xdr_nfsstat3,
349 sizeof (nfslog_RMDIR3args), sizeof (nfsstat3)},
351 /* RFS3_RENAME = 14 */
352 {nfslog_RENAME3_fhargs, xdr_nfslog_RENAME3args, xdr_nfsstat3,
353 sizeof (nfslog_RENAME3args), sizeof (nfsstat3)},
355 /* RFS3_LINK = 15 */
356 {nfslog_LINK3_fhargs, xdr_nfslog_LINK3args, xdr_nfsstat3,
357 sizeof (nfslog_LINK3args), sizeof (nfsstat3)},
359 /* RFS3_READDIR = 16 */
360 {nfslog_READDIR3_fhargs, xdr_nfs_fh3, xdr_nfsstat3,
361 sizeof (nfs_fh3), sizeof (nfsstat3)},
363 /* RFS3_READDIRPLUS = 17 */
364 {nfslog_READDIRPLUS3_fhargs,
365 xdr_nfslog_READDIRPLUS3args, xdr_nfslog_READDIRPLUS3res,
366 sizeof (nfslog_READDIRPLUS3args),
367 sizeof (nfslog_READDIRPLUS3res)},
369 /* RFS3_FSSTAT = 18 */
370 {nfslog_FSSTAT3_fhargs, xdr_nfs_fh3, xdr_nfsstat3,
371 sizeof (nfs_fh3), sizeof (nfsstat3)},
373 /* RFS3_FSINFO = 19 */
374 {nfslog_FSINFO3_fhargs, xdr_nfs_fh3, xdr_nfsstat3,
375 sizeof (nfs_fh3), sizeof (nfsstat3)},
377 /* RFS3_PATHCONF = 20 */
378 {nfslog_PATHCONF3_fhargs, xdr_nfs_fh3, xdr_nfsstat3,
379 sizeof (nfs_fh3), sizeof (nfsstat3)},
381 /* RFS3_COMMIT = 21 */
382 {nfslog_COMMIT3_fhargs, xdr_nfslog_COMMIT3args, xdr_nfsstat3,
383 sizeof (nfslog_COMMIT3args), sizeof (nfsstat3)},
387 * NFSLOG VERSION 1
390 static struct nfsl_fh_proc_disp nfsl_log_fh_proc_v1[] = {
392 /* NFSLOG_NULL = 0 */
393 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0},
395 /* NFSLOG_SHARE = 1 */
396 {nfslog_SHARE_fhargs, xdr_nfslog_sharefsargs, xdr_nfslog_sharefsres,
397 sizeof (nfslog_sharefsargs), sizeof (nfslog_sharefsres)},
399 /* NFSLOG_UNSHARE = 2 */
400 {nfslog_UNSHARE_fhargs, xdr_nfslog_sharefsargs, xdr_nfslog_sharefsres,
401 sizeof (nfslog_sharefsargs), sizeof (nfslog_sharefsres)},
403 /* NFSLOG_LOOKUP3 = 3 */
404 {nfslog_LOOKUP3_fhargs, xdr_nfslog_diropargs3, xdr_nfslog_LOOKUP3res,
405 sizeof (nfslog_diropargs3), sizeof (nfslog_LOOKUP3res)},
407 /* NFSLOG_GETFH = 4 */
408 {nfslog_GETFH_fhargs, xdr_nfslog_getfhargs, xdr_nfsstat,
409 sizeof (nfslog_getfhargs), sizeof (nfsstat)},
412 static struct nfsl_fh_vers_disp nfsl_fh_vers_disptable[] = {
413 {sizeof (nfsl_fh_proc_v2) / sizeof (nfsl_fh_proc_v2[0]),
414 nfsl_fh_proc_v2},
415 {sizeof (nfsl_fh_proc_v3) / sizeof (nfsl_fh_proc_v3[0]),
416 nfsl_fh_proc_v3},
419 static struct nfsl_fh_vers_disp nfsl_log_fh_vers_disptable[] = {
420 {sizeof (nfsl_log_fh_proc_v1) / sizeof (nfsl_log_fh_proc_v1[0]),
421 nfsl_log_fh_proc_v1},
424 static struct nfsl_fh_prog_disp nfsl_fh_dispatch_table[] = {
425 {NFS_PROGRAM,
426 NFS_VERSMIN,
427 sizeof (nfsl_fh_vers_disptable) /
428 sizeof (nfsl_fh_vers_disptable[0]),
429 nfsl_fh_vers_disptable},
430 {NFSLOG_PROGRAM,
431 NFSLOG_VERSMIN,
432 sizeof (nfsl_log_fh_vers_disptable) /
433 sizeof (nfsl_log_fh_vers_disptable[0]),
434 nfsl_log_fh_vers_disptable},
437 static int nfsl_fh_dispatch_table_arglen =
438 sizeof (nfsl_fh_dispatch_table) /
439 sizeof (nfsl_fh_dispatch_table[0]);
441 extern int debug;
444 * print the fid into the given string as a series of hex digits.
445 * XXX Ideally, we'd like to just convert the filehandle into an i-number,
446 * but the fid encoding is a little tricky (see nfs_fhtovp() and
447 * ufs_vget()) and may be private to UFS.
450 static void
451 sprint_fid(char *buf, uint_t buflen, const fhandle_t *fh)
453 int i;
454 uchar_t byte;
455 uint_t fhlen;
458 * If the filehandle somehow got corrupted, only print the part
459 * that makes sense.
461 if (fh->fh_len > NFS_FHMAXDATA)
462 fhlen = NFS_FHMAXDATA;
463 else
464 fhlen = fh->fh_len;
465 assert(2 * fhlen < buflen);
467 for (i = 0; i < fhlen; i++) {
468 byte = fh->fh_data[i];
469 (void) sprintf(buf + 2 * i, "%02x", byte);
473 static void
474 fh_print_all_keys(char *fhpath, fhandle_t *fh)
476 if ((fhpath == NULL) || (fh == NULL) || (debug <= 1))
477 return;
478 (void) printf("\nBegin all database keys\n");
479 db_print_all_keys(fhpath, &fh->fh_fsid, stdout);
480 (void) printf("\nEnd all database keys\n");
483 #define FH_ADD(path, dfh, fh, name) \
484 fh_add(path, dfh, fh, name)
487 * Add the filehandle "fh", which has the name "name" and lives in
488 * directory "dfh", to the table "fhlist". "fhlist" will be updated if the
489 * entry is added to the front of the list.
490 * Return 0 for success, error code otherwise.
492 static int
493 fh_add(char *fhpath, fhandle_t *dfh, fhandle_t *fh, char *name)
495 uint_t flags = 0;
496 int error;
498 if (IS_DOT_FILENAME(name)) {
499 /* we don't insert these to the database but not an error */
500 if (debug > 3) {
501 PRINT_FULL_DATA(stdout, "fh_add", dfh, fh, name,
502 " - no dot files")
504 return (0);
506 if (dfh && (memcmp(fh, dfh, NFS_FHSIZE) == 0)) {
507 flags |= EXPORT_POINT;
510 /* Add to database */
511 error = db_add(fhpath, dfh, name, fh, flags);
512 if (debug > 1) {
513 if (error != 0) {
514 (void) printf("db_add error %s:\n",
515 ((error >= 0) ? strerror(error) : "Unknown"));
516 PRINT_FULL_DATA(stdout, "fh_add", dfh, fh, name, "")
517 } else if (debug > 2) {
518 PRINT_FULL_DATA(stdout, "fh_add", dfh, fh, name, "")
521 return (error);
525 * fh_compare returns 0 if the file handles match, error code otherwise
527 static int
528 fh_compare(fhandle_t *fh1, fhandle_t *fh2)
530 if (memcmp(fh1, fh2, NFS_FHSIZE))
531 return (errno);
532 else
533 return (0);
537 * Try to find the filehandle "fh" in the table. Returns 0 and the
538 * corresponding table entry if found, error otherwise.
539 * If successfull and fhrecpp is non-null then *fhrecpp points to the
540 * returned record. If *fhrecpp was initially null, that record had
541 * been malloc'd and must be freed by caller.
544 static fhlist_ent *
545 fh_lookup(char *fhpath, fhandle_t *fh, fhlist_ent *fhrecp, int *errorp)
547 if (debug > 3) {
548 (void) printf("fh_lookup: fh ");
549 debug_opaque_print(stdout, fh, sizeof (*fh));
550 (void) printf("\n");
552 return (db_lookup(fhpath, fh, fhrecp, errorp));
556 * Remove the mc link if exists when removing a regular link.
557 * Return 0 for success, error code otherwise.
559 static int
560 fh_remove_mc_link(char *fhpath, fhandle_t *dfh, char *name, char **pathp)
562 int error;
563 char *str, *str1;
565 /* Delete the multi-component path if exists */
566 if ((pathp == NULL) || (*pathp == NULL)) {
567 str = nfslog_get_path(dfh, name, fhpath, "remove_mc_link");
568 str1 = str;
569 } else {
570 str = *pathp;
571 str1 = NULL;
573 error = db_delete_link(fhpath, &public_fh, str);
574 free(str1);
575 return (error);
579 * Remove the link entry from the fh table.
580 * Return 0 for success, error code otherwise.
582 static int
583 fh_remove(char *fhpath, fhandle_t *dfh, char *name, char **pathp)
586 * disconnect element from list
588 * Remove the link entry for the file. Remove fh entry if last link.
590 if (IS_DOT_FILENAME(name)) {
591 /* we don't insert these to the database but not an error */
592 if (debug > 2) {
593 PRINT_LINK_DATA(stdout, "fh_remove", dfh, name,
594 " - no dot files")
596 return (0);
598 if (debug > 2) {
599 PRINT_LINK_DATA(stdout, "fh_remove", dfh, name, "")
601 /* Delete the multi-component path if exists */
602 (void) fh_remove_mc_link(fhpath, dfh, name, pathp);
603 return (db_delete_link(fhpath, dfh, name));
607 * fh_rename - renames a link in the database (adds the new one if from link
608 * did not exist).
609 * Return 0 for success, error code otherwise.
611 static int
612 fh_rename(char *fhpath, fhandle_t *from_dfh, char *from_name, char **from_pathp,
613 fhandle_t *to_dfh, char *to_name)
615 if (debug > 2) {
616 PRINT_LINK_DATA(stdout, "fh_rename: from:", from_dfh,
617 from_name, "")
618 PRINT_LINK_DATA(stdout, "fh_rename: to :", to_dfh,
619 to_name, "")
622 * if any of these are dot files (should not happen), the rename
623 * becomes a "delete" or "add" operation because the dot files
624 * don't get in the database
626 if (IS_DOT_FILENAME(to_name)) {
627 /* it is just a delete op */
628 if (debug > 2) {
629 (void) printf("to: no dot files\nDelete from: '%s'\n",
630 from_name);
632 return (fh_remove(fhpath, from_dfh, from_name, from_pathp));
633 } else if (IS_DOT_FILENAME(from_name)) {
634 /* we don't insert these to the database */
635 if (debug > 2) {
636 (void) printf("rename - from: no dot files\n");
638 /* can't insert the target, because don't have a handle */
639 return (EINVAL);
641 /* Delete the multi-component path if exists */
642 (void) fh_remove_mc_link(fhpath, from_dfh, from_name, from_pathp);
643 return (db_rename_link(fhpath, from_dfh, from_name, to_dfh, to_name));
647 * fh_lookup_link - search the fhtable for the link defined by (dfh,name,fh).
648 * Return 0 and set *fhrecpp to the fhlist item corresponding to it if found,
649 * or error if not found.
650 * Possible configurations:
651 * 1. dfh, fh, name are all non-null: Only exact match accepted.
652 * 2. dfh,name non-null, fh null: return first match found.
653 * 3. fh,name non-null, dfh null: return first match found.
654 * 3. fh non-null, dfh, name null: return first match found.
655 * If successfull and fhrecpp is non-null then *fhrecpp points to the
656 * returned record. If *fhrecpp was initially null, that record had
657 * been malloc'd and must be freed by caller.
659 static fhlist_ent *
660 fh_lookup_link(char *fhpath, fhandle_t *dfh, fhandle_t *fh, char *name,
661 fhlist_ent *fhrecp, int *errorp)
663 fhlist_ent *in_fhrecp = fhrecp;
665 if ((name != NULL) && IS_DOT_FILENAME(name)) {
666 /* we don't insert these to the database but not an error */
667 if (debug > 2) {
668 PRINT_FULL_DATA(stdout, "fh_lookup_link", dfh, fh, name,
669 " - no dot files\n")
671 *errorp = 0;
672 return (NULL);
674 if (debug > 3) {
675 PRINT_FULL_DATA(stdout, "fh_lookup_link", dfh, fh, name, "")
677 /* Add to database */
678 if (fh != NULL) {
679 fhrecp = db_lookup(fhpath, fh, fhrecp, errorp);
680 if (fhrecp == NULL) {
681 if (debug > 3)
682 (void) printf("fh_lookup_link: fh not found\n");
683 return (NULL);
685 /* Check if name and dfh match, if not search link */
686 if (((dfh == NULL) || !fh_compare(dfh, &fhrecp->dfh)) &&
687 ((name == NULL) || (strcmp(name, fhrecp->name) == 0))) {
688 /* found it */
689 goto exit;
691 /* Found the primary record, but it's a different link */
692 if (debug == 3) { /* Only log if >2 but already printed */
693 PRINT_FULL_DATA(stdout, "fh_lookup_link", dfh, fh,
694 name, "")
696 if (debug > 2) {
697 PRINT_LINK_DATA(stdout, "Different primary link",
698 &fhrecp->dfh, fhrecp->name, "")
700 /* can now free the record unless it was supplied by caller */
701 if (fhrecp != in_fhrecp) {
702 free(fhrecp);
703 fhrecp = NULL;
706 /* If here, we must search by link */
707 if ((dfh == NULL) || (name == NULL)) {
708 if (debug > 2)
709 (void) printf("fh_lookup_link: invalid params\n");
710 *errorp = EINVAL;
711 return (NULL);
713 fhrecp = db_lookup_link(fhpath, dfh, name, fhrecp, errorp);
714 if (fhrecp == NULL) {
715 if (debug > 3)
716 (void) printf("fh_lookup_link: link not found: %s\n",
717 ((*errorp >= 0) ? strerror(*errorp) : "Unknown"));
718 return (NULL);
720 /* If all args supplied, check if an exact match */
721 if ((fh != NULL) && fh_compare(fh, &fhrecp->fh)) {
722 if (debug > 2) {
723 PRINT_FULL_DATA(stderr, "fh_lookup_link", dfh, fh,
724 name, "")
725 PRINT_LINK_DATA(stderr, "Different primary link",
726 &fhrecp->dfh, fhrecp->name, "")
728 if (fhrecp != in_fhrecp)
729 free(fhrecp);
730 *errorp = EINVAL;
731 return (NULL);
733 exit:
734 if (debug > 3)
735 (void) printf("lookup: found '%s' in fhtable\n", name);
736 *errorp = 0;
737 return (fhrecp);
741 * Export handle cache is maintained if we see an export handle that either
742 * cannot have the path for it determined, or we failed store it.
743 * Usually the path of an export handle can be identified in the NFSLOGTAB
744 * and since every path for that filesystem will be affected, it's worth
745 * caching the ones we had problem identifying.
749 * find_fh_in_export_cache - given an export fh, find it in the cache and
750 * return the handle
752 static struct export_handle_cache *
753 find_fh_in_export_cache(fhandle_t *fh)
755 struct export_handle_cache *p;
757 for (p = exp_handle_cache; p != NULL; p = p->next) {
758 if (memcmp(fh, &p->fh, sizeof (*fh)) == 0)
759 break;
761 return (p);
764 static void
765 add_fh_to_export_cache(fhandle_t *fh, char *path)
767 struct export_handle_cache *new;
769 if ((new = malloc(sizeof (*new))) == NULL) {
770 syslog(LOG_ERR, gettext(
771 "add_fh_to_export_cache: alloc new for '%s' Error %s\n"),
772 ((path != NULL) ? path : ""), strerror(errno));
773 return;
775 if (path != NULL) {
776 if ((new->name = malloc(strlen(path) + 1)) == NULL) {
777 syslog(LOG_ERR, gettext(
778 "add_fh_to_export_cache: alloc '%s'"
779 " Error %s\n"), path, strerror(errno));
780 free(new);
781 return;
783 (void) strcpy(new->name, path);
784 } else {
785 new->name = NULL;
787 (void) memcpy(&new->fh, fh, sizeof (*fh));
788 new->next = exp_handle_cache;
789 exp_handle_cache = new;
793 * update_export_point - called when the path for fh cannot be determined.
794 * In the past it called get_export_path() to get the name of the
795 * export point given a filehandle. This was a hack, since there's no
796 * reason why the filehandle should be lost.
798 * If a match is found, insert the path to the database.
799 * Return the inserted fhrecp is found,
800 * and NULL if not. If it is an exported fs but not in the list, log a
801 * error.
802 * If input fhrecp is non-null, it is a valid address for result,
803 * otherwise malloc it.
805 static char *
806 update_export_point(char *fhpath, fhandle_t *fh, char *path)
808 struct export_handle_cache *p;
810 if ((fh == NULL) || memcmp(&fh->fh_data, &fh->fh_xdata, fh->fh_len)) {
811 /* either null fh or not the root of a shared directory */
812 return (NULL);
814 /* Did we already see (and fail) this one? */
815 if ((p = find_fh_in_export_cache(fh)) != NULL) {
816 /* Found it! */
817 if (debug > 2) {
818 PRINT_LINK_DATA(stdout, "update_export_point",
819 fh, ((p->name != NULL) ? p->name : ""), "");
821 if (p->name == NULL)
822 return (NULL);
824 * We should not normally be here - only add to cache if
825 * fh_add failed.
827 if ((path == NULL) &&
828 ((path = malloc(strlen(p->name) + 1)) == NULL)) {
829 syslog(LOG_ERR, gettext(
830 "update_export_point: malloc '%s' Error %s"),
831 p->name, strerror(errno));
832 return (NULL);
834 (void) strcpy(path, p->name);
835 return (path);
837 if ((path = get_export_path(fh, path)) == NULL) {
838 add_fh_to_export_cache(fh, NULL);
839 return (NULL);
841 /* Found it! */
842 if (debug > 2) {
843 PRINT_LINK_DATA(stdout, "update_export_point", fh, path, "")
845 if (FH_ADD(fhpath, fh, fh, path)) {
846 /* cache this handle so we don't repeat the search */
847 add_fh_to_export_cache(fh, path);
849 return (path);
853 * HACK!!! To get rid of get_export_path() use
855 /* ARGSUSED */
856 static char *
857 get_export_path(fhandle_t *fh, char *path)
859 return (NULL);
863 * Return the absolute pathname for the filehandle "fh", using the mapping
864 * table "fhlist". The caller must free the return string.
865 * name is an optional dir component name, to be appended at the end
866 * (if name is non-null, the function assumes the fh is the parent directory)
868 * Note: The original code was recursive, which was much more elegant but
869 * ran out of stack...
872 static char *
873 fh_print_absolute(char *fhpath, fhandle_t *fh, char *name)
875 char *str, *rootname, parent[MAXPATHLEN];
876 int i, j, k, len, error;
877 fhlist_ent fhrec, *fhrecp;
878 fhandle_t prevfh;
879 int namelen;
881 if (debug > 3)
882 (void) printf("fh_print_absolute: input name '%s'\n",
883 ((name != NULL) ? name : ""));
884 /* If name starts with '/' we are done */
885 if ((name != NULL) && (name[0] == '/')) {
886 if ((str = strdup(name)) == NULL) {
887 syslog(LOG_ERR, gettext(
888 "fh_print_absolute: strdup '%s' error %s\n"),
889 name, strerror(errno));
891 return (str);
893 namelen = ((name != NULL) ? strlen(name) + 2 : 0);
894 parent[0] = '\0';
896 /* remember the last filehandle we've seen */
897 (void) memcpy((void *) &prevfh, (void *) fh, sizeof (*fh));
898 fh = &prevfh;
900 /* dump all names in reverse order */
901 while ((fhrecp = fh_lookup(fhpath, fh, &fhrec, &error)) != NULL &&
902 !(fhrecp->flags & (EXPORT_POINT | PUBLIC_PATH))) {
904 if (debug > 3) {
905 (void) printf("fh_print_absolute: name '%s'%s\n",
906 fhrecp->name,
907 ((fhrecp->flags & EXPORT_POINT) ? "root" : ""));
909 if (memcmp(&prevfh, &fhrecp->dfh, sizeof (*fh)) == 0) {
910 /* dfh == prevfh but not an export point */
911 if (debug > 1) {
912 (void) printf(
913 "fh_print_absolute: fhrec loop:\n");
914 debug_opaque_print(stdout, fhrecp,
915 fhrecp->reclen);
917 break;
919 (void) strcat(parent, "/");
920 (void) strcat(parent, fhrecp->name);
922 /* remember the last filehandle we've seen */
923 (void) memcpy(&prevfh, &fhrecp->dfh, sizeof (fhrecp->dfh));
925 assert(fh == &prevfh);
927 if (fhrecp != NULL) {
928 rootname = fhrecp->name;
929 } else {
930 /* Check if export point, just in case... */
931 /* There should be enough room in parent, leave the '\0' */
932 rootname = update_export_point(
933 fhpath, fh, &parent[strlen(parent) + 1]);
935 /* Now need to reverse the order */
936 if (rootname != NULL) { /* *fhrecp is the export point */
937 len = strlen(rootname) + 2;
938 } else {
939 len = 2 * (NFS_FHMAXDATA + fh->fh_len); /* fid instead */
941 len = ROUNDUP32(len + namelen + strlen(parent));
942 if ((str = malloc(len)) == NULL) {
943 syslog(LOG_ERR, gettext(
944 "fh_print_absolute: malloc %d error %s\n"),
945 len, strerror(errno));
946 return (NULL);
948 /* first put the export point path in */
949 if (rootname != NULL) { /* *fhrecp is the export point */
950 (void) strcpy(str, rootname);
951 } else {
952 sprint_fid(str, len, fh);
954 for (k = strlen(str), i = strlen(parent); (k < len) && (i >= 0); i--) {
955 for (j = i; (j >= 0) && (parent[j] != '/'); j--);
956 if (j < 0)
957 break;
958 (void) strcpy(&str[k], &parent[j]);
959 k += strlen(&str[k]);
960 parent[j] = '\0';
962 if ((name != NULL) && ((k + namelen) <= len)) {
963 str[k] = '/';
964 (void) strcpy(&str[k + 1], name);
966 if (debug > 3)
967 (void) printf("fh_print_absolute: path '%s'\n", str);
968 return (str);
972 * nfslog_find_fh_dispatch - get the dispatch struct for this request
974 static struct nfsl_fh_proc_disp *
975 nfslog_find_fh_dispatch(nfslog_request_record *logrec)
977 nfslog_record_header *logrechdr = &logrec->re_header;
978 struct nfsl_fh_prog_disp *progtable; /* prog struct */
979 struct nfsl_fh_vers_disp *verstable; /* version struct */
980 int i, vers;
982 /* Find prog element - search because can't use prog as array index */
983 for (i = 0; (i < nfsl_fh_dispatch_table_arglen) &&
984 (logrechdr->rh_prognum != nfsl_fh_dispatch_table[i].nfsl_dis_prog);
985 i++);
986 if (i >= nfsl_fh_dispatch_table_arglen) { /* program not logged */
987 /* not an error */
988 return (NULL);
990 progtable = &nfsl_fh_dispatch_table[i];
991 /* Find vers element - no validity check - if here it's valid vers */
992 vers = logrechdr->rh_version - progtable->nfsl_dis_versmin;
993 verstable = &progtable->nfsl_dis_vers_table[vers];
994 /* Find proc element - no validity check - if here it's valid proc */
995 return (&verstable->nfsl_dis_proc_table[logrechdr->rh_procnum]);
998 /* ARGSUSED */
999 static void
1000 nfslog_null_fhargs(caddr_t *nfsl_args, caddr_t *nfsl_res,
1001 char *fhpath, char **pathp1, char **pathp2)
1003 *pathp1 = NULL;
1004 *pathp2 = NULL;
1008 * nfslog_LOOKUP_calc - called by both lookup3 and lookup2. Handles the
1009 * mclookup as well as normal lookups.
1011 /* ARGSUSED */
1012 static void
1013 nfslog_LOOKUP_calc(fhandle_t *dfh, char *name, fhandle_t *fh,
1014 char *fhpath, char **pathp1, char **pathp2, char *str)
1016 int error;
1017 fhlist_ent fhrec;
1018 char *name1 = NULL;
1020 if (fh == &public_fh) {
1021 /* a fake lookup to inform us of the public fs path */
1022 if (error = FH_ADD(fhpath, fh, fh, name)) {
1023 syslog(LOG_ERR, gettext(
1024 "%s: Add Public fs '%s' failed: %s\n"),
1025 str, name,
1026 ((error >= 0) ? strerror(error) : "Unknown"));
1028 if (pathp1 != NULL) {
1029 *pathp1 = nfslog_get_path(dfh, NULL, fhpath, str);
1030 *pathp2 = NULL;
1032 return;
1034 if (pathp1 != NULL) {
1035 *pathp1 = nfslog_get_path(dfh, name, fhpath, str);
1036 *pathp2 = NULL;
1039 /* If public fh mclookup, then insert complete path */
1040 if (dfh == &public_fh) {
1041 if (pathp1 != NULL) {
1042 name = *pathp1;
1043 } else {
1044 name = nfslog_get_path(dfh, name, fhpath, str);
1045 name1 = name;
1048 if (fh_lookup_link(fhpath, dfh, fh, name, &fhrec, &error) != NULL) {
1049 /* link already in table */
1050 free(name1);
1051 return;
1053 /* A new link so add it */
1054 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1055 syslog(LOG_ERR, gettext(
1056 "%s: Add fh for '%s' failed: %s\n"), str,
1057 name, ((error >= 0) ? strerror(error) : "Unknown"));
1059 free(name1);
1063 * NFS VERSION 2
1066 /* Functions for updating the fhtable for fhtoppath */
1069 * nfslog_GETATTR2_fhargs - updates path1 but no fhtable changes
1071 /* ARGSUSED */
1072 static void
1073 nfslog_GETATTR2_fhargs(fhandle_t *args, nfsstat *res,
1074 char *fhpath, char **pathp1, char **pathp2)
1076 if (debug > 2) {
1077 (void) printf("=============\nGETATTR2: fh ");
1078 debug_opaque_print(stdout, args, sizeof (*args));
1079 (void) printf("\n");
1081 if (pathp1 != NULL) {
1082 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(args),
1083 NULL, fhpath, "getattr2");
1084 *pathp2 = NULL;
1089 * nfslog_SETATTR2_fhargs - updates path1 but no fhtable changes
1091 /* ARGSUSED */
1092 static void
1093 nfslog_SETATTR2_fhargs(nfslog_setattrargs *args, nfsstat *res,
1094 char *fhpath, char **pathp1, char **pathp2)
1096 if (debug > 2) {
1097 (void) printf("=============\nSETATTR2: fh ");
1098 debug_opaque_print(stdout, &args->saa_fh,
1099 sizeof (args->saa_fh));
1100 (void) printf("\n");
1102 if (pathp1 != NULL) {
1103 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(&args->saa_fh),
1104 NULL, fhpath, "setattr2");
1105 *pathp2 = NULL;
1110 * nfslog_LOOKUP2_fhargs - search the table to ensure we have not added this
1111 * one already. Note that if the response status was anything but okay,
1112 * there is no fh to check...
1114 /* ARGSUSED */
1115 static void
1116 nfslog_LOOKUP2_fhargs(nfslog_diropargs *args, nfslog_diropres *res,
1117 char *fhpath, char **pathp1, char **pathp2)
1119 char *name;
1120 fhandle_t *dfh, *fh;
1122 dfh = &args->da_fhandle;
1123 name = args->da_name;
1124 if (debug > 2) {
1125 if (res->dr_status == NFS_OK)
1126 fh = &res->nfslog_diropres_u.dr_ok.drok_fhandle;
1127 else
1128 fh = NULL;
1129 PRINT_FULL_DATA(stdout, "=============\nLOOKUP2",
1130 dfh, fh, name, "")
1131 if (res->dr_status != NFS_OK)
1132 (void) printf("status %d\n", res->dr_status);
1134 dfh = NFSLOG_GET_FHANDLE2(dfh);
1135 if ((dfh == &public_fh) && (name[0] == '\x80')) {
1136 /* special mclookup */
1137 name = &name[1];
1139 if (res->dr_status != NFS_OK) {
1140 if (pathp1 != NULL) {
1141 *pathp1 = nfslog_get_path(dfh, name, fhpath, "lookup2");
1142 *pathp2 = NULL;
1144 return;
1146 fh = NFSLOG_GET_FHANDLE2(&res->nfslog_diropres_u.dr_ok.drok_fhandle);
1147 nfslog_LOOKUP_calc(dfh, name, fh, fhpath, pathp1, pathp2, "Lookup2");
1151 * nfslog_READLINK2_fhargs - updates path1 but no fhtable changes
1153 /* ARGSUSED */
1154 static void
1155 nfslog_READLINK2_fhargs(fhandle_t *args, nfslog_rdlnres *res,
1156 char *fhpath, char **pathp1, char **pathp2)
1158 if (debug > 2) {
1159 (void) printf("=============\nREADLINK2: fh ");
1160 debug_opaque_print(stdout, args, sizeof (*args));
1161 (void) printf("\n");
1163 if (pathp1 != NULL) {
1164 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(args),
1165 NULL, fhpath, "readlink2");
1166 *pathp2 = NULL;
1171 * nfslog_READ2_fhargs - updates path1 but no fhtable changes
1173 /* ARGSUSED */
1174 static void
1175 nfslog_READ2_fhargs(nfslog_nfsreadargs *args, nfslog_rdresult *res,
1176 char *fhpath, char **pathp1, char **pathp2)
1178 if (debug > 2) {
1179 (void) printf("=============\nREAD2: fh ");
1180 debug_opaque_print(stdout, &args->ra_fhandle,
1181 sizeof (args->ra_fhandle));
1182 (void) printf("\n");
1184 if (pathp1 != NULL) {
1185 *pathp1 = nfslog_get_path(
1186 NFSLOG_GET_FHANDLE2(&args->ra_fhandle),
1187 NULL, fhpath, "read2");
1188 *pathp2 = NULL;
1193 * nfslog_WRITE2_fhargs - updates path1 but no fhtable changes
1195 /* ARGSUSED */
1196 static void
1197 nfslog_WRITE2_fhargs(nfslog_writeargs *args, nfslog_writeresult *res,
1198 char *fhpath, char **pathp1, char **pathp2)
1200 if (debug > 2) {
1201 (void) printf("=============\nWRITE2: fh ");
1202 debug_opaque_print(stdout, &args->waargs_fhandle,
1203 sizeof (args->waargs_fhandle));
1204 (void) printf("\n");
1206 if (pathp1 != NULL) {
1207 *pathp1 = nfslog_get_path(
1208 NFSLOG_GET_FHANDLE2(&args->waargs_fhandle),
1209 NULL, fhpath, "write2");
1210 *pathp2 = NULL;
1215 * nfslog_CREATE2_fhargs - if the operation succeeded, we are sure there can
1216 * be no such link in the fhtable, so just add it.
1218 /* ARGSUSED */
1219 static void
1220 nfslog_CREATE2_fhargs(nfslog_createargs *args, nfslog_diropres *res,
1221 char *fhpath, char **pathp1, char **pathp2)
1223 char *name;
1224 fhandle_t *dfh, *fh;
1225 int error;
1227 name = args->ca_da.da_name;
1228 dfh = &args->ca_da.da_fhandle;
1229 if (debug > 2) {
1230 if (res->dr_status == NFS_OK)
1231 fh = &res->nfslog_diropres_u.dr_ok.drok_fhandle;
1232 else
1233 fh = NULL;
1234 PRINT_FULL_DATA(stdout, "=============\nCREATE2",
1235 dfh, fh, name, "")
1236 if (res->dr_status != NFS_OK)
1237 (void) printf("status %d\n", res->dr_status);
1239 dfh = NFSLOG_GET_FHANDLE2(dfh);
1240 if (pathp1 != NULL) {
1241 *pathp1 = nfslog_get_path(dfh, name, fhpath, "create2");
1242 *pathp2 = NULL;
1245 if (res->dr_status != NFS_OK)
1246 /* no returned fh so nothing to add */
1247 return;
1249 /* A new file handle so add it */
1250 fh = NFSLOG_GET_FHANDLE2(&res->nfslog_diropres_u.dr_ok.drok_fhandle);
1251 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1252 syslog(LOG_ERR, gettext(
1253 "Create2: Add fh for '%s' failed: %s\n"),
1254 name, ((error >= 0) ? strerror(error) : "Unknown"));
1259 * nfslog_REMOVE2_fhargs - if the operation succeeded, remove the link from
1260 * the fhtable.
1262 /* ARGSUSED */
1263 static void
1264 nfslog_REMOVE2_fhargs(nfslog_diropargs *args, nfsstat *res,
1265 char *fhpath, char **pathp1, char **pathp2)
1267 char *name;
1268 fhandle_t *dfh;
1269 int error;
1271 name = args->da_name;
1272 dfh = &args->da_fhandle;
1273 if (debug > 2) {
1274 PRINT_LINK_DATA(stdout, "=============\nREMOVE2", dfh, name, "")
1275 if (*res != NFS_OK)
1276 (void) printf("status %d\n", *res);
1278 dfh = NFSLOG_GET_FHANDLE2(dfh);
1279 if (pathp1 != NULL) {
1280 *pathp1 = nfslog_get_path(dfh, name, fhpath, "remove2");
1281 *pathp2 = NULL;
1284 if (*res != NFS_OK)
1285 /* remove failed so nothing to update */
1286 return;
1288 if (error = fh_remove(fhpath, dfh, name, pathp1)) {
1289 syslog(LOG_ERR, gettext("Remove2: '%s' failed: %s\n"),
1290 name, ((error >= 0) ? strerror(error) : "Unknown"));
1295 * nfsl_RENAME2_fhargs - updates the dfh and name fields for the given fh
1296 * to change them to the new name.
1298 /* ARGSUSED */
1299 static void
1300 nfslog_RENAME2_fhargs(nfslog_rnmargs *args, nfsstat *res,
1301 char *fhpath, char **pathp1, char **pathp2)
1303 char *from_name, *to_name;
1304 fhandle_t *from_dfh, *to_dfh;
1305 int error;
1307 from_name = args->rna_from.da_name;
1308 from_dfh = &args->rna_from.da_fhandle;
1309 to_name = args->rna_to.da_name;
1310 to_dfh = &args->rna_to.da_fhandle;
1311 if (debug > 2) {
1312 PRINT_LINK_DATA(stdout, "=============\nRENAME2: from",
1313 from_dfh, from_name, "")
1314 PRINT_LINK_DATA(stdout, "RENAME2: to ", to_dfh,
1315 to_name, "")
1316 if (*res != NFS_OK)
1317 (void) printf("status %d\n", *res);
1319 from_dfh = NFSLOG_GET_FHANDLE2(from_dfh);
1320 to_dfh = NFSLOG_GET_FHANDLE2(to_dfh);
1321 if (pathp1 != NULL) {
1322 *pathp1 = nfslog_get_path(from_dfh, from_name, fhpath,
1323 "rename2 from");
1324 *pathp2 = nfslog_get_path(to_dfh, to_name, fhpath,
1325 "rename2 to");
1328 if (*res != NFS_OK)
1329 /* rename failed so nothing to update */
1330 return;
1332 /* Rename the link in the database */
1333 if (error = fh_rename(fhpath, from_dfh, from_name, pathp1,
1334 to_dfh, to_name)) {
1335 syslog(LOG_ERR, gettext(
1336 "Rename2: Update from '%s' to '%s' failed: %s\n"),
1337 from_name, to_name,
1338 ((error >= 0) ? strerror(error) : "Unknown"));
1343 * nfslog_LINK2_fhargs - adds link name and fh to fhlist. Note that as a
1344 * result we may have more than one name for an fh.
1346 /* ARGSUSED */
1347 static void
1348 nfslog_LINK2_fhargs(nfslog_linkargs *args, nfsstat *res,
1349 char *fhpath, char **pathp1, char **pathp2)
1351 char *name;
1352 fhandle_t *dfh, *fh;
1353 int error;
1355 fh = &args->la_from;
1356 name = args->la_to.da_name;
1357 dfh = &args->la_to.da_fhandle;
1358 if (debug > 2) {
1359 PRINT_FULL_DATA(stdout, "=============\nLINK2",
1360 dfh, fh, name, "")
1361 if (*res != NFS_OK)
1362 (void) printf("status %d\n", *res);
1364 dfh = NFSLOG_GET_FHANDLE2(dfh);
1365 fh = NFSLOG_GET_FHANDLE2(fh);
1366 if (pathp1 != NULL) {
1367 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "link2 from");
1368 *pathp2 = nfslog_get_path(dfh, name, fhpath, "link2 to");
1371 if (*res != NFS_OK)
1372 /* no returned fh so nothing to add */
1373 return;
1375 /* A new link so add it, have fh_add find the link count */
1376 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1377 syslog(LOG_ERR, gettext(
1378 "Link2: Add fh for '%s' failed: %s\n"),
1379 name, ((error >= 0) ? strerror(error) : "Unknown"));
1384 * nfslog_SYMLINK2_fhargs - adds symlink name and fh to fhlist if fh returned.
1386 /* ARGSUSED */
1387 static void
1388 nfslog_SYMLINK2_fhargs(nfslog_symlinkargs *args, nfsstat *res,
1389 char *fhpath, char **pathp1, char **pathp2)
1391 char *name;
1392 fhandle_t *dfh;
1394 name = args->sla_from.da_name;
1395 dfh = &args->sla_from.da_fhandle;
1396 if (debug > 2) {
1397 PRINT_LINK_DATA(stdout, "=============\nSYMLINK2",
1398 dfh, name, "")
1400 dfh = NFSLOG_GET_FHANDLE2(dfh);
1401 if (pathp1 != NULL) {
1402 *pathp1 = nfslog_get_path(dfh, name, fhpath, "symlink2");
1403 *pathp2 = NULL;
1408 * nfslog_READDIR2_fhargs - updates path1 but no fhtable changes
1410 /* ARGSUSED */
1411 static void
1412 nfslog_READDIR2_fhargs(nfslog_rddirargs *args, nfslog_rddirres *res,
1413 char *fhpath, char **pathp1, char **pathp2)
1415 if (debug > 2) {
1416 (void) printf("=============\nREADDIR2: fh ");
1417 debug_opaque_print(stdout, &args->rda_fh,
1418 sizeof (args->rda_fh));
1419 (void) printf("\n");
1421 if (pathp1 != NULL) {
1422 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(&args->rda_fh),
1423 NULL, fhpath, "readdir2");
1424 *pathp2 = NULL;
1429 * nfslog_STATFS2_fhargs - updates path1 but no fhtable changes
1431 /* ARGSUSED */
1432 static void
1433 nfslog_STATFS2_fhargs(fhandle_t *args, nfsstat *res,
1434 char *fhpath, char **pathp1, char **pathp2)
1436 if (debug > 2) {
1437 (void) printf("=============\nSTATFS2: fh ");
1438 debug_opaque_print(stdout, args, sizeof (*args));
1439 (void) printf("\n");
1441 if (pathp1 != NULL) {
1442 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(args),
1443 NULL, fhpath, "statfs2");
1444 *pathp2 = NULL;
1449 * NFS VERSION 3
1452 /* Functions for updating the fhtable for fhtoppath */
1455 * nfslog_GETATTR3_fhargs - updates path1 but no fhtable changes
1457 /* ARGSUSED */
1458 static void
1459 nfslog_GETATTR3_fhargs(nfs_fh3 *args, nfsstat3 *res,
1460 char *fhpath, char **pathp1, char **pathp2)
1462 if (debug > 2) {
1463 (void) printf("=============\nGETATTR3: fh ");
1464 debug_opaque_print(stdout, args, sizeof (*args));
1465 (void) printf("\n");
1467 if (pathp1 != NULL) {
1468 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL,
1469 fhpath, "getattr3");
1470 *pathp2 = NULL;
1475 * nfslog_SETATTR3_fhargs - updates path1 but no fhtable changes
1477 /* ARGSUSED */
1478 static void
1479 nfslog_SETATTR3_fhargs(nfslog_SETATTR3args *args, nfsstat3 *res,
1480 char *fhpath, char **pathp1, char **pathp2)
1482 if (debug > 2) {
1483 (void) printf("=============\nSETATTR3: fh ");
1484 debug_opaque_print(stdout, &args->object,
1485 sizeof (args->object));
1486 (void) printf("\n");
1488 if (pathp1 != NULL) {
1489 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->object),
1490 NULL, fhpath, "setattr3");
1491 *pathp2 = NULL;
1496 * nfslog_LOOKUP3_fhargs - search the table to ensure we have not added this
1497 * one already. Note that if the response status was anything but okay,
1498 * there is no fh to check...
1500 /* ARGSUSED */
1501 static void
1502 nfslog_LOOKUP3_fhargs(nfslog_diropargs3 *args, nfslog_LOOKUP3res *res,
1503 char *fhpath, char **pathp1, char **pathp2)
1505 char *name;
1506 fhandle_t *dfh, *fh;
1508 name = args->name;
1509 dfh = NFSLOG_GET_FHANDLE3(&args->dir);
1511 if (debug > 2) {
1512 if (res->status == NFS3_OK)
1513 fh = NFSLOG_GET_FHANDLE3(
1514 &res->nfslog_LOOKUP3res_u.object);
1515 else
1516 fh = NULL;
1517 PRINT_FULL_DATA(stdout, "=============\nLOOKUP3",
1518 dfh, fh, name, "")
1519 if (res->status != NFS3_OK)
1520 (void) printf("status %d\n", res->status);
1522 if ((dfh == &public_fh) && (name[0] == '\x80')) {
1523 /* special mclookup */
1524 name = &name[1];
1526 if (res->status != NFS3_OK) {
1527 if (pathp1 != NULL) {
1528 *pathp1 = nfslog_get_path(dfh, name, fhpath, "lookup3");
1529 *pathp2 = NULL;
1531 return;
1533 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_LOOKUP3res_u.object);
1534 nfslog_LOOKUP_calc(dfh, name, fh, fhpath, pathp1, pathp2, "Lookup3");
1538 * nfslog_ACCESS3_fhargs - updates path1 but no fhtable changes
1540 /* ARGSUSED */
1541 static void
1542 nfslog_ACCESS3_fhargs(nfs_fh3 *args, nfsstat3 *res,
1543 char *fhpath, char **pathp1, char **pathp2)
1545 if (debug > 2) {
1546 (void) printf("=============\nACCESS3: fh ");
1547 debug_opaque_print(stdout, args,
1548 sizeof (*args));
1549 (void) printf("\n");
1551 if (pathp1 != NULL) {
1552 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args),
1553 NULL, fhpath, "access3");
1554 *pathp2 = NULL;
1559 * nfslog_READLINK3_fhargs - updates path1 but no fhtable changes
1561 /* ARGSUSED */
1562 static void
1563 nfslog_READLINK3_fhargs(nfs_fh3 *args, nfslog_READLINK3res *res,
1564 char *fhpath, char **pathp1, char **pathp2)
1566 if (debug > 2) {
1567 (void) printf("=============\nREADLINK3: fh ");
1568 debug_opaque_print(stdout, args, sizeof (*args));
1569 (void) printf("\n");
1571 if (pathp1 != NULL) {
1572 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL,
1573 fhpath, "readlink3");
1574 *pathp2 = NULL;
1579 * nfslog_READ3_fhargs - updates path1 but no fhtable changes
1581 /* ARGSUSED */
1582 static void
1583 nfslog_READ3_fhargs(nfslog_READ3args *args, nfslog_READ3res *res,
1584 char *fhpath, char **pathp1, char **pathp2)
1586 if (debug > 2) {
1587 (void) printf("=============\nREAD3: fh ");
1588 debug_opaque_print(stdout, &args->file,
1589 sizeof (args->file));
1590 (void) printf("\n");
1592 if (pathp1 != NULL) {
1593 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->file),
1594 NULL, fhpath, "read3");
1595 *pathp2 = NULL;
1600 * nfslog_WRITE3_fhargs - updates path1 but no fhtable changes
1602 /* ARGSUSED */
1603 static void
1604 nfslog_WRITE3_fhargs(nfslog_WRITE3args *args, nfslog_WRITE3res *res,
1605 char *fhpath, char **pathp1, char **pathp2)
1607 if (debug > 2) {
1608 (void) printf("=============\nWRITE3: fh ");
1609 debug_opaque_print(stdout, &args->file,
1610 sizeof (args->file));
1611 (void) printf("\n");
1613 if (pathp1 != NULL) {
1614 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->file),
1615 NULL, fhpath, "write3");
1616 *pathp2 = NULL;
1621 * nfslog_CREATE3_fhargs - if the operation succeeded, we are sure there can
1622 * be no such link in the fhtable, so just add it.
1624 /* ARGSUSED */
1625 static void
1626 nfslog_CREATE3_fhargs(nfslog_CREATE3args *args, nfslog_CREATE3res *res,
1627 char *fhpath, char **pathp1, char **pathp2)
1629 char *name;
1630 fhandle_t *dfh, *fh;
1631 int error;
1633 name = args->where.name;
1634 dfh = NFSLOG_GET_FHANDLE3(&args->where.dir);
1636 if (debug > 2) {
1637 if (res->status == NFS3_OK)
1638 fh = NFSLOG_GET_FHANDLE3(
1639 &res->nfslog_CREATE3res_u.ok.obj.handle);
1640 else
1641 fh = NULL;
1642 PRINT_FULL_DATA(stdout, "=============\nCREATE3",
1643 dfh, fh, name, "")
1644 if (res->status != NFS3_OK)
1645 (void) printf("status %d\n", res->status);
1647 if (pathp1 != NULL) {
1648 *pathp1 = nfslog_get_path(dfh, name, fhpath, "create3");
1649 *pathp2 = NULL;
1652 if ((res->status != NFS3_OK) ||
1653 !res->nfslog_CREATE3res_u.ok.obj.handle_follows)
1654 /* no returned fh so nothing to add */
1655 return;
1657 /* A new file handle so add it */
1658 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_CREATE3res_u.ok.obj.handle);
1659 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1660 syslog(LOG_ERR, gettext(
1661 "Create3: Add fh for '%s' failed: %s\n"),
1662 name, ((error >= 0) ? strerror(error) : "Unknown"));
1667 * nfslog_MKDIR3_fhargs - if the operation succeeded, we are sure there can
1668 * be no such link in the fhtable, so just add it.
1670 /* ARGSUSED */
1671 static void
1672 nfslog_MKDIR3_fhargs(nfslog_MKDIR3args *args, nfslog_MKDIR3res *res,
1673 char *fhpath, char **pathp1, char **pathp2)
1675 char *name;
1676 fhandle_t *dfh, *fh;
1677 int error;
1679 name = args->where.name;
1680 dfh = NFSLOG_GET_FHANDLE3(&args->where.dir);
1682 if (debug > 2) {
1683 if (res->status == NFS3_OK)
1684 fh = NFSLOG_GET_FHANDLE3(
1685 &res->nfslog_MKDIR3res_u.obj.handle);
1686 else
1687 fh = NULL;
1688 PRINT_FULL_DATA(stdout, "=============\nMKDIR3",
1689 dfh, fh, name, "")
1690 if (res->status != NFS3_OK)
1691 (void) printf("status %d\n", res->status);
1693 if (pathp1 != NULL) {
1694 *pathp1 = nfslog_get_path(dfh, name, fhpath, "mkdir3");
1695 *pathp2 = NULL;
1698 if ((res->status != NFS3_OK) ||
1699 !res->nfslog_MKDIR3res_u.obj.handle_follows)
1700 /* no returned fh so nothing to add */
1701 return;
1703 /* A new file handle so add it */
1704 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_MKDIR3res_u.obj.handle);
1705 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1706 syslog(LOG_ERR, gettext(
1707 "Mkdir3: Add fh for '%s' failed: %s\n"),
1708 name, ((error >= 0) ? strerror(error) : "Unknown"));
1713 * nfslog_REMOVE3_fhargs - if the operation succeeded, remove the link from
1714 * the fhtable.
1716 /* ARGSUSED */
1717 static void
1718 nfslog_REMOVE3_fhargs(nfslog_REMOVE3args *args, nfsstat3 *res,
1719 char *fhpath, char **pathp1, char **pathp2)
1721 char *name;
1722 fhandle_t *dfh;
1723 int error;
1725 name = args->object.name;
1726 dfh = NFSLOG_GET_FHANDLE3(&args->object.dir);
1728 if (debug > 2) {
1729 PRINT_LINK_DATA(stdout, "=============\nREMOVE3", dfh, name, "")
1730 if (*res != NFS3_OK)
1731 (void) printf("status %d\n", *res);
1733 if (pathp1 != NULL) {
1734 *pathp1 = nfslog_get_path(dfh, name, fhpath, "remove3");
1735 *pathp2 = NULL;
1738 if (*res != NFS3_OK)
1739 /* remove failed so nothing to update */
1740 return;
1742 if (error = fh_remove(fhpath, dfh, name, pathp1)) {
1743 syslog(LOG_ERR, gettext("Remove3: '%s' failed: %s\n"),
1744 name, ((error >= 0) ? strerror(error) : "Unknown"));
1749 * nfslog_RMDIR3_fhargs - if the operation succeeded, remove the link from
1750 * the fhtable.
1752 /* ARGSUSED */
1753 static void
1754 nfslog_RMDIR3_fhargs(nfslog_RMDIR3args *args, nfsstat3 *res,
1755 char *fhpath, char **pathp1, char **pathp2)
1757 char *name;
1758 fhandle_t *dfh;
1759 int error;
1761 name = args->object.name;
1762 dfh = NFSLOG_GET_FHANDLE3(&args->object.dir);
1764 if (debug > 2) {
1765 PRINT_LINK_DATA(stdout, "=============\nRMDIR3", dfh, name, "")
1766 if (*res != NFS3_OK)
1767 (void) printf("status %d\n", *res);
1769 if (pathp1 != NULL) {
1770 *pathp1 = nfslog_get_path(dfh, name, fhpath, "rmdir3");
1771 *pathp2 = NULL;
1774 if (*res != NFS3_OK)
1775 /* rmdir failed so nothing to update */
1776 return;
1778 if (error = fh_remove(fhpath, dfh, name, pathp1)) {
1779 syslog(LOG_ERR, gettext("Rmdir3: '%s' failed: %s\n"),
1780 name, ((error >= 0) ? strerror(error) : "Unknown"));
1785 * nfslog_RENAME3_fhargs - if the operation succeeded, update the existing
1786 * fhtable entry to point to new dir and name.
1788 /* ARGSUSED */
1789 static void
1790 nfslog_RENAME3_fhargs(nfslog_RENAME3args *args, nfsstat3 *res,
1791 char *fhpath, char **pathp1, char **pathp2)
1793 char *from_name, *to_name;
1794 fhandle_t *from_dfh, *to_dfh;
1795 int error;
1797 from_name = args->from.name;
1798 from_dfh = NFSLOG_GET_FHANDLE3(&args->from.dir);
1799 to_name = args->to.name;
1800 to_dfh = NFSLOG_GET_FHANDLE3(&args->to.dir);
1802 if (debug > 2) {
1803 PRINT_LINK_DATA(stdout, "=============\nRENAME3: from",
1804 from_dfh, from_name, "")
1805 PRINT_LINK_DATA(stdout, "=============\nRENAME3: to ",
1806 to_dfh, to_name, "")
1807 if (*res != NFS3_OK)
1808 (void) printf("status %d\n", *res);
1810 if (pathp1 != NULL) {
1811 *pathp1 = nfslog_get_path(from_dfh, from_name, fhpath,
1812 "rename3 from");
1813 *pathp2 = nfslog_get_path(to_dfh, to_name, fhpath,
1814 "rename3 to");
1816 if (*res != NFS3_OK)
1817 /* rename failed so nothing to update */
1818 return;
1820 if (error = fh_rename(fhpath, from_dfh, from_name, pathp1,
1821 to_dfh, to_name)) {
1822 syslog(LOG_ERR, gettext(
1823 "Rename3: Update from '%s' to '%s' failed: %s\n"),
1824 from_name, to_name,
1825 ((error >= 0) ? strerror(error) : "Unknown"));
1830 * nfslog_LINK3_fhargs - if the operation succeeded, we are sure there can
1831 * be no such link in the fhtable, so just add it.
1833 /* ARGSUSED */
1834 static void
1835 nfslog_LINK3_fhargs(nfslog_LINK3args *args, nfsstat3 *res,
1836 char *fhpath, char **pathp1, char **pathp2)
1838 char *name;
1839 fhandle_t *dfh, *fh;
1840 int error;
1842 fh = NFSLOG_GET_FHANDLE3(&args->file);
1843 name = args->link.name;
1844 dfh = NFSLOG_GET_FHANDLE3(&args->link.dir);
1846 if (debug > 2) {
1847 PRINT_FULL_DATA(stdout, "=============\nLINK3",
1848 dfh, fh, name, "")
1849 if (*res != NFS3_OK)
1850 (void) printf("status %d\n", *res);
1852 if (pathp1 != NULL) {
1853 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "link3 from");
1854 *pathp2 = nfslog_get_path(dfh, name, fhpath, "link3 to");
1857 if (*res != NFS3_OK)
1858 /* link failed so nothing to add */
1859 return;
1861 /* A new link so add it, have fh_add find link count */
1862 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1863 syslog(LOG_ERR, gettext(
1864 "Link3: Add fh for '%s' failed: %s\n"),
1865 name, ((error >= 0) ? strerror(error) : "Unknown"));
1870 * nfslog_MKNOD3_fhargs - if the operation succeeded, we are sure there can
1871 * be no such link in the fhtable, so just add it.
1873 /* ARGSUSED */
1874 static void
1875 nfslog_MKNOD3_fhargs(nfslog_MKNOD3args *args, nfslog_MKNOD3res *res,
1876 char *fhpath, char **pathp1, char **pathp2)
1878 char *name;
1879 fhandle_t *dfh, *fh;
1880 int error;
1882 name = args->where.name;
1883 dfh = NFSLOG_GET_FHANDLE3(&args->where.dir);
1885 if (debug > 2) {
1886 if (res->status == NFS3_OK)
1887 fh = NFSLOG_GET_FHANDLE3(
1888 &res->nfslog_MKNOD3res_u.obj.handle);
1889 else
1890 fh = NULL;
1891 PRINT_FULL_DATA(stdout, "=============\nMKNOD3",
1892 dfh, fh, name, "")
1893 if (res->status != NFS3_OK)
1894 (void) printf("status %d\n", res->status);
1896 if (pathp1 != NULL) {
1897 *pathp1 = nfslog_get_path(dfh, name, fhpath, "mknod3");
1898 *pathp2 = NULL;
1900 if ((res->status != NFS3_OK) ||
1901 !res->nfslog_MKNOD3res_u.obj.handle_follows)
1902 /* no returned fh so nothing to add */
1903 return;
1905 /* A new file handle so add it */
1906 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_MKNOD3res_u.obj.handle);
1907 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1908 syslog(LOG_ERR, gettext("Mknod3: Add fh for '%s' failed: %s\n"),
1909 name, ((error >= 0) ? strerror(error) : "Unknown"));
1914 * nfslog_SYMLINK3_fhargs - if the operation succeeded, we are sure there can
1915 * be no such link in the fhtable, so just add it.
1917 /* ARGSUSED */
1918 static void
1919 nfslog_SYMLINK3_fhargs(nfslog_SYMLINK3args *args, nfslog_SYMLINK3res *res,
1920 char *fhpath, char **pathp1, char **pathp2)
1922 char *name;
1923 fhandle_t *dfh, *fh;
1924 int error;
1926 name = args->where.name;
1927 dfh = NFSLOG_GET_FHANDLE3(&args->where.dir);
1929 if (debug > 2) {
1930 if (res->status == NFS3_OK)
1931 fh = NFSLOG_GET_FHANDLE3(
1932 &res->nfslog_SYMLINK3res_u.obj.handle);
1933 else
1934 fh = NULL;
1935 PRINT_FULL_DATA(stdout, "=============\nSYMLINK3",
1936 dfh, fh, name, "")
1937 if (res->status != NFS3_OK)
1938 (void) printf("status %d\n", res->status);
1940 if (pathp1 != NULL) {
1941 *pathp1 = nfslog_get_path(dfh, name, fhpath, "symlink3");
1942 *pathp2 = NULL;
1945 if ((res->status != NFS3_OK) ||
1946 !res->nfslog_SYMLINK3res_u.obj.handle_follows)
1947 /* no returned fh so nothing to add */
1948 return;
1950 /* A new file handle so add it */
1951 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_SYMLINK3res_u.obj.handle);
1952 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1953 syslog(LOG_ERR, gettext(
1954 "Symlink3: Add fh for '%s' failed: %s\n"),
1955 name, ((error >= 0) ? strerror(error) : "Unknown"));
1960 * nfslog_READDIR3_fhargs - updates path1 but no fhtable changes
1962 /* ARGSUSED */
1963 static void
1964 nfslog_READDIR3_fhargs(nfs_fh3 *args, nfsstat3 *res,
1965 char *fhpath, char **pathp1, char **pathp2)
1967 if (debug > 2) {
1968 (void) printf("=============\nREADDIR3: fh ");
1969 debug_opaque_print(stdout, args,
1970 sizeof (*args));
1971 (void) printf("\n");
1973 if (pathp1 != NULL) {
1974 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args),
1975 NULL, fhpath, "readdir3");
1976 *pathp2 = NULL;
1981 * nfslog_READDIRPLUS3_fhargs - updates path1 but no fhtable changes
1983 /* ARGSUSED */
1984 static void
1985 nfslog_READDIRPLUS3_fhargs(nfslog_READDIRPLUS3args *args,
1986 nfslog_READDIRPLUS3res *res,
1987 char *fhpath, char **pathp1, char **pathp2)
1989 char *name;
1990 fhandle_t *dfh, *fh;
1991 nfslog_entryplus3 *ep;
1993 if (debug > 2) {
1994 (void) printf("=============\nREADDIRPLUS3: fh ");
1995 debug_opaque_print(stdout, &args->dir,
1996 sizeof (args->dir));
1997 (void) printf("\n");
1999 if (pathp1 != NULL) {
2000 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->dir),
2001 NULL, fhpath, "readdirplus3");
2002 *pathp2 = NULL;
2005 if (res->status == NFS3_OK) {
2007 dfh = NFSLOG_GET_FHANDLE3(&args->dir);
2010 * Loop through the fh/name pair and add them
2011 * to the mappings.
2013 for (ep = res->nfslog_READDIRPLUS3res_u.ok.reply.entries;
2014 ep != NULL;
2015 ep = ep->nextentry) {
2017 name = ep->name;
2019 fh = NFSLOG_GET_FHANDLE3(&ep->name_handle.handle);
2021 nfslog_LOOKUP_calc(dfh, name, fh,
2022 fhpath, NULL, NULL,
2023 "ReaddirPlus3");
2029 * nfslog_FSSTAT3_fhargs - updates path1 but no fhtable changes
2031 /* ARGSUSED */
2032 static void
2033 nfslog_FSSTAT3_fhargs(nfs_fh3 *args, nfsstat3 *res,
2034 char *fhpath, char **pathp1, char **pathp2)
2036 if (debug > 2) {
2037 (void) printf("=============\nFSSTAT3: fh ");
2038 debug_opaque_print(stdout, args,
2039 sizeof (*args));
2040 (void) printf("\n");
2042 if (pathp1 != NULL) {
2043 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL,
2044 fhpath, "fsstat3");
2045 *pathp2 = NULL;
2050 * nfslog_FSINFO3_fhargs - updates path1 but no fhtable changes
2052 /* ARGSUSED */
2053 static void
2054 nfslog_FSINFO3_fhargs(nfs_fh3 *args, nfsstat3 *res,
2055 char *fhpath, char **pathp1, char **pathp2)
2057 if (debug > 2) {
2058 (void) printf("=============\nFSINFO3: fh ");
2059 debug_opaque_print(stdout, args,
2060 sizeof (*args));
2061 (void) printf("\n");
2063 if (pathp1 != NULL) {
2064 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL,
2065 fhpath, "fsinfo3");
2066 *pathp2 = NULL;
2071 * nfslog_PATHCONF3_fhargs - updates path1 but no fhtable changes
2073 /* ARGSUSED */
2074 static void
2075 nfslog_PATHCONF3_fhargs(nfs_fh3 *args, nfsstat3 *res,
2076 char *fhpath, char **pathp1, char **pathp2)
2078 if (debug > 2) {
2079 (void) printf("=============\nPATHCONF3: fh ");
2080 debug_opaque_print(stdout, args,
2081 sizeof (*args));
2082 (void) printf("\n");
2084 if (pathp1 != NULL) {
2085 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL,
2086 fhpath, "pathconf3");
2087 *pathp2 = NULL;
2092 * nfslog_COMMIT3_fhargs - updates path1 but no fhtable changes
2094 /* ARGSUSED */
2095 static void
2096 nfslog_COMMIT3_fhargs(nfslog_COMMIT3args *args, nfsstat3 *res,
2097 char *fhpath, char **pathp1, char **pathp2)
2099 if (debug > 2) {
2100 (void) printf("=============\nCOMMIT3: fh ");
2101 debug_opaque_print(stdout, &args->file,
2102 sizeof (args->file));
2103 (void) printf("\n");
2105 if (pathp1 != NULL) {
2106 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->file),
2107 NULL, fhpath, "commit3");
2108 *pathp2 = NULL;
2113 * NFSLOG VERSION 1
2117 * nfslog_SHARE_fhargs - adds export path and handle to fhlist
2119 /* ARGSUSED */
2120 static void
2121 nfslog_SHARE_fhargs(nfslog_sharefsargs *args, nfslog_sharefsres *res,
2122 char *fhpath, char **pathp1, char **pathp2)
2124 fhlist_ent fhrec;
2125 fhandle_t *fh;
2126 int error;
2128 if (debug > 2) {
2129 (void) printf(
2130 "=============\nSHARE: name '%s', fh ", args->sh_path);
2131 debug_opaque_print(stdout, &args->sh_fh_buf,
2132 sizeof (fhandle_t));
2133 (void) printf("\n");
2136 fh = &args->sh_fh_buf;
2139 * This bcopy is done because the fh_data for the export/share directory
2140 * is not meaningful with respect to the database keys. Therefore, we
2141 * copy the export or fh_xdata fid to the fh_data so that a reasonable
2142 * entry will be added in the data base.
2144 bcopy(fh->fh_xdata, fh->fh_data, fh->fh_xlen);
2146 /* If debug print the database */
2147 if (debug > 10) {
2148 fh_print_all_keys(fhpath, fh);
2150 if (fh_lookup_link(fhpath, fh, fh,
2151 args->sh_path, &fhrec, &error) == NULL) {
2152 if (error = FH_ADD(fhpath, fh, fh, args->sh_path)) {
2153 syslog(LOG_ERR, gettext(
2154 "Share: Add fh for '%s' failed: %s\n"),
2155 args->sh_path, ((error >= 0) ?
2156 strerror(error) : "Unknown"));
2159 if (pathp1 != NULL) {
2160 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "share");
2161 *pathp2 = NULL;
2166 * nfslog_UNSHARE_fhargs - remove export path and handle from fhlist
2168 /* ARGSUSED */
2169 static void
2170 nfslog_UNSHARE_fhargs(nfslog_sharefsargs *args, nfslog_sharefsres *res,
2171 char *fhpath, char **pathp1, char **pathp2)
2173 fhandle_t *fh;
2174 int error;
2176 if (debug > 2) {
2177 (void) printf("=============\nUNSHARE: name '%s', fh ",
2178 args->sh_path);
2179 debug_opaque_print(stdout, &args->sh_fh_buf,
2180 sizeof (fhandle_t));
2181 (void) printf("\n");
2184 fh = &args->sh_fh_buf;
2187 * This bcopy is done because the fh_data for the export/share directory
2188 * is not meaningful with respect to the database keys. Therefore, we
2189 * copy the export or fh_xdata fid to the fh_data so that a reasonable
2190 * entry will be added in the data base.
2192 bcopy(fh->fh_xdata, fh->fh_data, fh->fh_xlen);
2194 /* If debug print the database */
2195 if (debug > 10) {
2196 fh_print_all_keys(fhpath, fh);
2198 if (pathp1 != NULL) {
2199 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "share");
2200 *pathp2 = NULL;
2202 if (error = fh_remove(fhpath, fh, args->sh_path, pathp1)) {
2203 syslog(LOG_ERR, gettext("Unshare: '%s' failed: %s\n"),
2204 args->sh_path, ((error >= 0) ? strerror(error) :
2205 "Unknown"));
2209 /* ARGSUSED */
2210 static void
2211 nfslog_GETFH_fhargs(nfslog_getfhargs *args, nfsstat *res,
2212 char *fhpath, char **pathp1, char **pathp2)
2214 fhlist_ent fhrec;
2215 fhandle_t *fh;
2216 int error;
2218 if (debug > 2) {
2219 (void) printf("=============\nGETFH3: name '%s', fh ",
2220 args->gfh_path);
2221 debug_opaque_print(stdout, &args->gfh_fh_buf,
2222 sizeof (fhandle_t));
2223 (void) printf("\n");
2226 fh = &args->gfh_fh_buf;
2228 /* If debug print the database */
2229 if (debug > 10) {
2230 fh_print_all_keys(fhpath, fh);
2232 if (fh_lookup_link(fhpath, fh, fh,
2233 args->gfh_path, &fhrec, &error) == NULL) {
2234 if (error = FH_ADD(fhpath, fh, fh, args->gfh_path)) {
2235 syslog(LOG_ERR, gettext(
2236 "Getfh: Add fh for '%s' failed: %s\n"),
2237 args->gfh_path, ((error >= 0) ?
2238 strerror(error) : "Unknown"));
2241 if (pathp1 != NULL) {
2242 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "getfh");
2243 *pathp2 = NULL;
2248 * Exported function
2252 * nfslog_get_path - gets the path for this file. fh must be supplied,
2253 * name may be null. If name is supplied, fh is assumed to be a directory
2254 * filehandle, with name as its component. fhpath is the generic path for the
2255 * fhtopath table and prtstr is the name of the caller (for debug purposes).
2256 * Returns the malloc'd path. The caller must free it later.
2258 char *
2259 nfslog_get_path(fhandle_t *fh, char *name, char *fhpath, char *prtstr)
2261 char *pathp = fh_print_absolute(fhpath, fh, name);
2263 if (debug > 3) {
2264 (void) printf(" %s: path '%s', fh ", prtstr, pathp);
2265 debug_opaque_print(stdout, fh, sizeof (*fh));
2266 (void) printf("\n");
2268 return (pathp);
2272 * nfslog_process_fh_rec - updates the fh table based on the rpc req
2273 * Return 0 for success, error otherwise. If success return the path
2274 * for the input file handle(s) if so indicated.
2277 nfslog_process_fh_rec(struct nfslog_lr *lrp, char *fhpath, char **pathp1,
2278 char **pathp2, bool_t return_path)
2280 struct nfsl_fh_proc_disp *disp;
2281 nfslog_request_record *logrec = &lrp->log_record;
2282 nfslog_record_header *logrechdr = &logrec->re_header;
2284 if ((disp = nfslog_find_fh_dispatch(logrec)) != NULL) {
2286 * Allocate space for the args and results and decode
2288 logrec->re_rpc_arg = calloc(1, disp->args_size);
2290 if (!(*disp->xdr_args)(&lrp->xdrs, logrec->re_rpc_arg)) {
2291 free(logrec->re_rpc_arg);
2292 logrec->re_rpc_arg = NULL;
2293 syslog(LOG_ERR, gettext("argument decode failed"));
2294 return (FALSE);
2296 /* used later for free of data structures */
2297 lrp->xdrargs = disp->xdr_args;
2299 logrec->re_rpc_res = calloc(1, disp->res_size);
2300 if (!(*disp->xdr_res)(&lrp->xdrs, logrec->re_rpc_res)) {
2301 free(logrec->re_rpc_res);
2302 logrec->re_rpc_res = NULL;
2303 syslog(LOG_ERR, gettext("results decode failed"));
2304 return (FALSE);
2306 /* used later for free of data structures */
2307 lrp->xdrres = disp->xdr_res;
2310 * Process the operation within the context of the file handle
2311 * mapping process
2313 if (return_path) {
2314 (*disp->nfsl_dis_args)(logrec->re_rpc_arg,
2315 logrec->re_rpc_res, fhpath, pathp1, pathp2);
2316 } else {
2317 if ((logrechdr->rh_version == NFS_VERSION &&
2318 logrechdr->rh_procnum == RFS_LINK) ||
2319 (logrechdr->rh_version == NFS_V3 &&
2320 logrechdr->rh_procnum == NFSPROC3_LINK)) {
2322 (*disp->nfsl_dis_args)(logrec->re_rpc_arg,
2323 logrec->re_rpc_res,
2324 fhpath, pathp1, pathp2);
2325 } else {
2326 (*disp->nfsl_dis_args)(logrec->re_rpc_arg,
2327 logrec->re_rpc_res,
2328 fhpath, NULL, NULL);
2331 return (TRUE);
2332 } else {
2333 syslog(LOG_ERR, gettext("procedure unknown"));
2334 return (FALSE);