1 /* 2 * CDDL HEADER START 3 * 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. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1999 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 /* 28 * Code to maintain the runtime and on-disk filehandle mapping table for 29 * nfslog. 30 */ 31 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" 45 46 #define ROUNDUP32(val) (((val) + 3) & ~3) 47 48 #define IS_DOT_FILENAME(name) \ 49 ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) 50 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); 56 57 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); 67 68 /* 69 * export handle cache 70 */ 71 struct export_handle_cache { 72 fhandle_t fh; 73 char *name; 74 struct export_handle_cache *next; 75 }; 76 77 static struct export_handle_cache *exp_handle_cache = NULL; 78 79 extern bool_t nfsl_prin_fh; 80 81 static int fh_add(char *, fhandle_t *, fhandle_t *, char *); 82 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); 94 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); 107 108 /* 109 * NFS VERSION 2 110 */ 111 112 /* 113 * Functions for updating the fhtable for fhtoppath and for returning 114 * the absolute pathname 115 */ 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 **); 142 143 /* 144 * NFS VERSION 3 145 * 146 * Functions for updating the fhtable for fhtoppath 147 */ 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 **); 191 192 /* 193 * NFSLOG VERSION 1 194 * 195 * Functions for updating the fhtable for fhtoppath 196 */ 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 **); 203 204 /* 205 * Define the actions taken per prog/vers/proc: 206 * 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. 211 */ 212 213 static struct nfsl_fh_proc_disp nfsl_fh_proc_v2[] = { 214 /* 215 * NFS VERSION 2 216 */ 217 218 /* RFS_NULL = 0 */ 219 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0}, 220 221 /* RFS_GETATTR = 1 */ 222 {nfslog_GETATTR2_fhargs, xdr_fhandle, xdr_nfsstat, 223 sizeof (fhandle_t), sizeof (nfsstat)}, 224 225 /* RFS_SETATTR = 2 */ 226 {nfslog_SETATTR2_fhargs, xdr_nfslog_setattrargs, xdr_nfsstat, 227 sizeof (nfslog_setattrargs), sizeof (nfsstat)}, 228 229 /* RFS_ROOT = 3 *** NO LONGER SUPPORTED *** */ 230 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0}, 231 232 /* RFS_LOOKUP = 4 */ 233 {nfslog_LOOKUP2_fhargs, xdr_nfslog_diropargs, xdr_nfslog_diropres, 234 sizeof (nfslog_diropargs), sizeof (nfslog_diropres)}, 235 236 /* RFS_READLINK = 5 */ 237 {nfslog_READLINK2_fhargs, xdr_fhandle, xdr_nfslog_rdlnres, 238 sizeof (fhandle_t), sizeof (nfslog_rdlnres)}, 239 240 /* RFS_READ = 6 */ 241 {nfslog_READ2_fhargs, xdr_nfslog_nfsreadargs, xdr_nfslog_rdresult, 242 sizeof (nfslog_nfsreadargs), sizeof (nfslog_rdresult)}, 243 244 /* RFS_WRITECACHE = 7 *** NO LONGER SUPPORTED *** */ 245 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0}, 246 247 /* RFS_WRITE = 8 */ 248 {nfslog_WRITE2_fhargs, xdr_nfslog_writeargs, xdr_nfslog_writeresult, 249 sizeof (nfslog_writeargs), sizeof (nfslog_writeresult)}, 250 251 /* RFS_CREATE = 9 */ 252 {nfslog_CREATE2_fhargs, xdr_nfslog_createargs, xdr_nfslog_diropres, 253 sizeof (nfslog_createargs), sizeof (nfslog_diropres)}, 254 255 /* RFS_REMOVE = 10 */ 256 {nfslog_REMOVE2_fhargs, xdr_nfslog_diropargs, xdr_nfsstat, 257 sizeof (nfslog_diropargs), sizeof (nfsstat)}, 258 259 /* RFS_RENAME = 11 */ 260 {nfslog_RENAME2_fhargs, xdr_nfslog_rnmargs, xdr_nfsstat, 261 sizeof (nfslog_rnmargs), sizeof (nfsstat)}, 262 263 /* RFS_LINK = 12 */ 264 {nfslog_LINK2_fhargs, xdr_nfslog_linkargs, xdr_nfsstat, 265 sizeof (nfslog_linkargs), sizeof (nfsstat)}, 266 267 /* RFS_SYMLINK = 13 */ 268 {nfslog_SYMLINK2_fhargs, xdr_nfslog_symlinkargs, xdr_nfsstat, 269 sizeof (nfslog_symlinkargs), sizeof (nfsstat)}, 270 271 /* RFS_MKDIR = 14 */ 272 {nfslog_CREATE2_fhargs, xdr_nfslog_createargs, xdr_nfslog_diropres, 273 sizeof (nfslog_createargs), sizeof (nfslog_diropres)}, 274 275 /* RFS_RMDIR = 15 */ 276 {nfslog_REMOVE2_fhargs, xdr_nfslog_diropargs, xdr_nfsstat, 277 sizeof (nfslog_diropargs), sizeof (nfsstat)}, 278 279 /* RFS_READDIR = 16 */ 280 {nfslog_READDIR2_fhargs, xdr_nfslog_rddirargs, xdr_nfslog_rddirres, 281 sizeof (nfslog_rddirargs), sizeof (nfslog_rddirres)}, 282 283 /* RFS_STATFS = 17 */ 284 {nfslog_STATFS2_fhargs, xdr_fhandle, xdr_nfsstat, 285 sizeof (fhandle_t), sizeof (nfsstat)}, 286 }; 287 288 289 /* 290 * NFS VERSION 3 291 */ 292 293 static struct nfsl_fh_proc_disp nfsl_fh_proc_v3[] = { 294 295 /* RFS_NULL = 0 */ 296 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0}, 297 298 /* RFS3_GETATTR = 1 */ 299 {nfslog_GETATTR3_fhargs, xdr_nfs_fh3, xdr_nfsstat3, 300 sizeof (nfs_fh3), sizeof (nfsstat3)}, 301 302 /* RFS3_SETATTR = 2 */ 303 {nfslog_SETATTR3_fhargs, xdr_nfslog_SETATTR3args, xdr_nfsstat3, 304 sizeof (nfslog_SETATTR3args), sizeof (nfsstat3)}, 305 306 /* RFS3_LOOKUP = 3 */ 307 {nfslog_LOOKUP3_fhargs, xdr_nfslog_diropargs3, xdr_nfslog_LOOKUP3res, 308 sizeof (nfslog_diropargs3), sizeof (nfslog_LOOKUP3res)}, 309 310 /* RFS3_ACCESS = 4 */ 311 {nfslog_ACCESS3_fhargs, xdr_nfs_fh3, xdr_nfsstat3, 312 sizeof (nfs_fh3), sizeof (nfsstat3)}, 313 314 /* RFS3_READLINK = 5 */ 315 {nfslog_READLINK3_fhargs, xdr_nfs_fh3, xdr_nfslog_READLINK3res, 316 sizeof (nfs_fh3), sizeof (nfslog_READLINK3res)}, 317 318 /* RFS3_READ = 6 */ 319 {nfslog_READ3_fhargs, xdr_nfslog_READ3args, xdr_nfslog_READ3res, 320 sizeof (nfslog_READ3args), sizeof (nfslog_READ3res)}, 321 322 /* RFS3_WRITE = 7 */ 323 {nfslog_WRITE3_fhargs, xdr_nfslog_WRITE3args, xdr_nfslog_WRITE3res, 324 sizeof (nfslog_WRITE3args), sizeof (nfslog_WRITE3res)}, 325 326 /* RFS3_CREATE = 8 */ 327 {nfslog_CREATE3_fhargs, xdr_nfslog_CREATE3args, xdr_nfslog_CREATE3res, 328 sizeof (nfslog_CREATE3args), sizeof (nfslog_CREATE3res)}, 329 330 /* RFS3_MKDIR = 9 */ 331 {nfslog_MKDIR3_fhargs, xdr_nfslog_MKDIR3args, xdr_nfslog_MKDIR3res, 332 sizeof (nfslog_MKDIR3args), sizeof (nfslog_MKDIR3res)}, 333 334 /* RFS3_SYMLINK = 10 */ 335 {nfslog_SYMLINK3_fhargs, xdr_nfslog_SYMLINK3args, 336 xdr_nfslog_SYMLINK3res, 337 sizeof (nfslog_SYMLINK3args), sizeof (nfslog_SYMLINK3res)}, 338 339 /* RFS3_MKNOD = 11 */ 340 {nfslog_MKNOD3_fhargs, xdr_nfslog_MKNOD3args, xdr_nfslog_MKNOD3res, 341 sizeof (nfslog_MKNOD3args), sizeof (nfslog_MKNOD3res)}, 342 343 /* RFS3_REMOVE = 12 */ 344 {nfslog_REMOVE3_fhargs, xdr_nfslog_REMOVE3args, xdr_nfsstat3, 345 sizeof (nfslog_REMOVE3args), sizeof (nfsstat3)}, 346 347 /* RFS3_RMDIR = 13 */ 348 {nfslog_RMDIR3_fhargs, xdr_nfslog_RMDIR3args, xdr_nfsstat3, 349 sizeof (nfslog_RMDIR3args), sizeof (nfsstat3)}, 350 351 /* RFS3_RENAME = 14 */ 352 {nfslog_RENAME3_fhargs, xdr_nfslog_RENAME3args, xdr_nfsstat3, 353 sizeof (nfslog_RENAME3args), sizeof (nfsstat3)}, 354 355 /* RFS3_LINK = 15 */ 356 {nfslog_LINK3_fhargs, xdr_nfslog_LINK3args, xdr_nfsstat3, 357 sizeof (nfslog_LINK3args), sizeof (nfsstat3)}, 358 359 /* RFS3_READDIR = 16 */ 360 {nfslog_READDIR3_fhargs, xdr_nfs_fh3, xdr_nfsstat3, 361 sizeof (nfs_fh3), sizeof (nfsstat3)}, 362 363 /* RFS3_READDIRPLUS = 17 */ 364 {nfslog_READDIRPLUS3_fhargs, 365 xdr_nfslog_READDIRPLUS3args, xdr_nfslog_READDIRPLUS3res, 366 sizeof (nfslog_READDIRPLUS3args), 367 sizeof (nfslog_READDIRPLUS3res)}, 368 369 /* RFS3_FSSTAT = 18 */ 370 {nfslog_FSSTAT3_fhargs, xdr_nfs_fh3, xdr_nfsstat3, 371 sizeof (nfs_fh3), sizeof (nfsstat3)}, 372 373 /* RFS3_FSINFO = 19 */ 374 {nfslog_FSINFO3_fhargs, xdr_nfs_fh3, xdr_nfsstat3, 375 sizeof (nfs_fh3), sizeof (nfsstat3)}, 376 377 /* RFS3_PATHCONF = 20 */ 378 {nfslog_PATHCONF3_fhargs, xdr_nfs_fh3, xdr_nfsstat3, 379 sizeof (nfs_fh3), sizeof (nfsstat3)}, 380 381 /* RFS3_COMMIT = 21 */ 382 {nfslog_COMMIT3_fhargs, xdr_nfslog_COMMIT3args, xdr_nfsstat3, 383 sizeof (nfslog_COMMIT3args), sizeof (nfsstat3)}, 384 }; 385 386 /* 387 * NFSLOG VERSION 1 388 */ 389 390 static struct nfsl_fh_proc_disp nfsl_log_fh_proc_v1[] = { 391 392 /* NFSLOG_NULL = 0 */ 393 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0}, 394 395 /* NFSLOG_SHARE = 1 */ 396 {nfslog_SHARE_fhargs, xdr_nfslog_sharefsargs, xdr_nfslog_sharefsres, 397 sizeof (nfslog_sharefsargs), sizeof (nfslog_sharefsres)}, 398 399 /* NFSLOG_UNSHARE = 2 */ 400 {nfslog_UNSHARE_fhargs, xdr_nfslog_sharefsargs, xdr_nfslog_sharefsres, 401 sizeof (nfslog_sharefsargs), sizeof (nfslog_sharefsres)}, 402 403 /* NFSLOG_LOOKUP3 = 3 */ 404 {nfslog_LOOKUP3_fhargs, xdr_nfslog_diropargs3, xdr_nfslog_LOOKUP3res, 405 sizeof (nfslog_diropargs3), sizeof (nfslog_LOOKUP3res)}, 406 407 /* NFSLOG_GETFH = 4 */ 408 {nfslog_GETFH_fhargs, xdr_nfslog_getfhargs, xdr_nfsstat, 409 sizeof (nfslog_getfhargs), sizeof (nfsstat)}, 410 }; 411 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}, 417 }; 418 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}, 422 }; 423 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}, 435 }; 436 437 static int nfsl_fh_dispatch_table_arglen = 438 sizeof (nfsl_fh_dispatch_table) / 439 sizeof (nfsl_fh_dispatch_table[0]); 440 441 extern int debug; 442 443 /* 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. 448 */ 449 450 static void 451 sprint_fid(char *buf, uint_t buflen, const fhandle_t *fh) 452 { 453 int i; 454 uchar_t byte; 455 uint_t fhlen; 456 457 /* 458 * If the filehandle somehow got corrupted, only print the part 459 * that makes sense. 460 */ 461 if (fh->fh_len > NFS_FHMAXDATA) 462 fhlen = NFS_FHMAXDATA; 463 else 464 fhlen = fh->fh_len; 465 assert(2 * fhlen < buflen); 466 467 for (i = 0; i < fhlen; i++) { 468 byte = fh->fh_data[i]; 469 (void) sprintf(buf + 2 * i, "%02x", byte); 470 } 471 } 472 473 static void 474 fh_print_all_keys(char *fhpath, fhandle_t *fh) 475 { 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"); 481 } 482 483 #define FH_ADD(path, dfh, fh, name) \ 484 fh_add(path, dfh, fh, name) 485 486 /* 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. 491 */ 492 static int 493 fh_add(char *fhpath, fhandle_t *dfh, fhandle_t *fh, char *name) 494 { 495 uint_t flags = 0; 496 int error; 497 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") 503 } 504 return (0); 505 } 506 if (dfh && (memcmp(fh, dfh, NFS_FHSIZE) == 0)) { 507 flags |= EXPORT_POINT; 508 } 509 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, "") 519 } 520 } 521 return (error); 522 } 523 524 /* 525 * fh_compare returns 0 if the file handles match, error code otherwise 526 */ 527 static int 528 fh_compare(fhandle_t *fh1, fhandle_t *fh2) 529 { 530 if (memcmp(fh1, fh2, NFS_FHSIZE)) 531 return (errno); 532 else 533 return (0); 534 } 535 536 /* 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. 542 */ 543 544 static fhlist_ent * 545 fh_lookup(char *fhpath, fhandle_t *fh, fhlist_ent *fhrecp, int *errorp) 546 { 547 if (debug > 3) { 548 (void) printf("fh_lookup: fh "); 549 debug_opaque_print(stdout, fh, sizeof (*fh)); 550 (void) printf("\n"); 551 } 552 return (db_lookup(fhpath, fh, fhrecp, errorp)); 553 } 554 555 /* 556 * Remove the mc link if exists when removing a regular link. 557 * Return 0 for success, error code otherwise. 558 */ 559 static int 560 fh_remove_mc_link(char *fhpath, fhandle_t *dfh, char *name, char **pathp) 561 { 562 int error; 563 char *str, *str1; 564 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; 572 } 573 error = db_delete_link(fhpath, &public_fh, str); 574 if (str1 != NULL) 575 free(str1); 576 return (error); 577 } 578 579 /* 580 * Remove the link entry from the fh table. 581 * Return 0 for success, error code otherwise. 582 */ 583 static int 584 fh_remove(char *fhpath, fhandle_t *dfh, char *name, char **pathp) 585 { 586 /* 587 * disconnect element from list 588 * 589 * Remove the link entry for the file. Remove fh entry if last link. 590 */ 591 if (IS_DOT_FILENAME(name)) { 592 /* we don't insert these to the database but not an error */ 593 if (debug > 2) { 594 PRINT_LINK_DATA(stdout, "fh_remove", dfh, name, 595 " - no dot files") 596 } 597 return (0); 598 } 599 if (debug > 2) { 600 PRINT_LINK_DATA(stdout, "fh_remove", dfh, name, "") 601 } 602 /* Delete the multi-component path if exists */ 603 (void) fh_remove_mc_link(fhpath, dfh, name, pathp); 604 return (db_delete_link(fhpath, dfh, name)); 605 } 606 607 /* 608 * fh_rename - renames a link in the database (adds the new one if from link 609 * did not exist). 610 * Return 0 for success, error code otherwise. 611 */ 612 static int 613 fh_rename(char *fhpath, fhandle_t *from_dfh, char *from_name, char **from_pathp, 614 fhandle_t *to_dfh, char *to_name) 615 { 616 if (debug > 2) { 617 PRINT_LINK_DATA(stdout, "fh_rename: from:", from_dfh, 618 from_name, "") 619 PRINT_LINK_DATA(stdout, "fh_rename: to :", to_dfh, 620 to_name, "") 621 } 622 /* 623 * if any of these are dot files (should not happen), the rename 624 * becomes a "delete" or "add" operation because the dot files 625 * don't get in the database 626 */ 627 if (IS_DOT_FILENAME(to_name)) { 628 /* it is just a delete op */ 629 if (debug > 2) { 630 (void) printf("to: no dot files\nDelete from: '%s'\n", 631 from_name); 632 } 633 return (fh_remove(fhpath, from_dfh, from_name, from_pathp)); 634 } else if (IS_DOT_FILENAME(from_name)) { 635 /* we don't insert these to the database */ 636 if (debug > 2) { 637 (void) printf("rename - from: no dot files\n"); 638 } 639 /* can't insert the target, because don't have a handle */ 640 return (EINVAL); 641 } 642 /* Delete the multi-component path if exists */ 643 (void) fh_remove_mc_link(fhpath, from_dfh, from_name, from_pathp); 644 return (db_rename_link(fhpath, from_dfh, from_name, to_dfh, to_name)); 645 } 646 647 /* 648 * fh_lookup_link - search the fhtable for the link defined by (dfh,name,fh). 649 * Return 0 and set *fhrecpp to the fhlist item corresponding to it if found, 650 * or error if not found. 651 * Possible configurations: 652 * 1. dfh, fh, name are all non-null: Only exact match accepted. 653 * 2. dfh,name non-null, fh null: return first match found. 654 * 3. fh,name non-null, dfh null: return first match found. 655 * 3. fh non-null, dfh, name null: return first match found. 656 * If successfull and fhrecpp is non-null then *fhrecpp points to the 657 * returned record. If *fhrecpp was initially null, that record had 658 * been malloc'd and must be freed by caller. 659 */ 660 static fhlist_ent * 661 fh_lookup_link(char *fhpath, fhandle_t *dfh, fhandle_t *fh, char *name, 662 fhlist_ent *fhrecp, int *errorp) 663 { 664 fhlist_ent *in_fhrecp = fhrecp; 665 666 if ((name != NULL) && IS_DOT_FILENAME(name)) { 667 /* we don't insert these to the database but not an error */ 668 if (debug > 2) { 669 PRINT_FULL_DATA(stdout, "fh_lookup_link", dfh, fh, name, 670 " - no dot files\n") 671 } 672 *errorp = 0; 673 return (NULL); 674 } 675 if (debug > 3) { 676 PRINT_FULL_DATA(stdout, "fh_lookup_link", dfh, fh, name, "") 677 } 678 /* Add to database */ 679 if (fh != NULL) { 680 fhrecp = db_lookup(fhpath, fh, fhrecp, errorp); 681 if (fhrecp == NULL) { 682 if (debug > 3) 683 (void) printf("fh_lookup_link: fh not found\n"); 684 return (NULL); 685 } 686 /* Check if name and dfh match, if not search link */ 687 if (((dfh == NULL) || !fh_compare(dfh, &fhrecp->dfh)) && 688 ((name == NULL) || (strcmp(name, fhrecp->name) == 0))) { 689 /* found it */ 690 goto exit; 691 } 692 /* Found the primary record, but it's a different link */ 693 if (debug == 3) { /* Only log if >2 but already printed */ 694 PRINT_FULL_DATA(stdout, "fh_lookup_link", dfh, fh, 695 name, "") 696 } 697 if (debug > 2) { 698 PRINT_LINK_DATA(stdout, "Different primary link", 699 &fhrecp->dfh, fhrecp->name, "") 700 } 701 /* can now free the record unless it was supplied by caller */ 702 if (fhrecp != in_fhrecp) { 703 free(fhrecp); 704 fhrecp = NULL; 705 } 706 } 707 /* If here, we must search by link */ 708 if ((dfh == NULL) || (name == NULL)) { 709 if (debug > 2) 710 (void) printf("fh_lookup_link: invalid params\n"); 711 *errorp = EINVAL; 712 return (NULL); 713 } 714 fhrecp = db_lookup_link(fhpath, dfh, name, fhrecp, errorp); 715 if (fhrecp == NULL) { 716 if (debug > 3) 717 (void) printf("fh_lookup_link: link not found: %s\n", 718 ((*errorp >= 0) ? strerror(*errorp) : "Unknown")); 719 return (NULL); 720 } 721 /* If all args supplied, check if an exact match */ 722 if ((fh != NULL) && fh_compare(fh, &fhrecp->fh)) { 723 if (debug > 2) { 724 PRINT_FULL_DATA(stderr, "fh_lookup_link", dfh, fh, 725 name, "") 726 PRINT_LINK_DATA(stderr, "Different primary link", 727 &fhrecp->dfh, fhrecp->name, "") 728 } 729 if (fhrecp != in_fhrecp) 730 free(fhrecp); 731 *errorp = EINVAL; 732 return (NULL); 733 } 734 exit: 735 if (debug > 3) 736 (void) printf("lookup: found '%s' in fhtable\n", name); 737 *errorp = 0; 738 return (fhrecp); 739 } 740 741 /* 742 * Export handle cache is maintained if we see an export handle that either 743 * cannot have the path for it determined, or we failed store it. 744 * Usually the path of an export handle can be identified in the NFSLOGTAB 745 * and since every path for that filesystem will be affected, it's worth 746 * caching the ones we had problem identifying. 747 */ 748 749 /* 750 * find_fh_in_export_cache - given an export fh, find it in the cache and 751 * return the handle 752 */ 753 static struct export_handle_cache * 754 find_fh_in_export_cache(fhandle_t *fh) 755 { 756 struct export_handle_cache *p; 757 758 for (p = exp_handle_cache; p != NULL; p = p->next) { 759 if (memcmp(fh, &p->fh, sizeof (*fh)) == 0) 760 break; 761 } 762 return (p); 763 } 764 765 static void 766 add_fh_to_export_cache(fhandle_t *fh, char *path) 767 { 768 struct export_handle_cache *new; 769 770 if ((new = malloc(sizeof (*new))) == NULL) { 771 syslog(LOG_ERR, gettext( 772 "add_fh_to_export_cache: alloc new for '%s' Error %s\n"), 773 ((path != NULL) ? path : ""), strerror(errno)); 774 return; 775 } 776 if (path != NULL) { 777 if ((new->name = malloc(strlen(path) + 1)) == NULL) { 778 syslog(LOG_ERR, gettext( 779 "add_fh_to_export_cache: alloc '%s'" 780 " Error %s\n"), path, strerror(errno)); 781 free(new); 782 return; 783 } 784 (void) strcpy(new->name, path); 785 } else { 786 new->name = NULL; 787 } 788 (void) memcpy(&new->fh, fh, sizeof (*fh)); 789 new->next = exp_handle_cache; 790 exp_handle_cache = new; 791 } 792 793 /* 794 * update_export_point - called when the path for fh cannot be determined. 795 * In the past it called get_export_path() to get the name of the 796 * export point given a filehandle. This was a hack, since there's no 797 * reason why the filehandle should be lost. 798 * 799 * If a match is found, insert the path to the database. 800 * Return the inserted fhrecp is found, 801 * and NULL if not. If it is an exported fs but not in the list, log a 802 * error. 803 * If input fhrecp is non-null, it is a valid address for result, 804 * otherwise malloc it. 805 */ 806 static char * 807 update_export_point(char *fhpath, fhandle_t *fh, char *path) 808 { 809 struct export_handle_cache *p; 810 811 if ((fh == NULL) || memcmp(&fh->fh_data, &fh->fh_xdata, fh->fh_len)) { 812 /* either null fh or not the root of a shared directory */ 813 return (NULL); 814 } 815 /* Did we already see (and fail) this one? */ 816 if ((p = find_fh_in_export_cache(fh)) != NULL) { 817 /* Found it! */ 818 if (debug > 2) { 819 PRINT_LINK_DATA(stdout, "update_export_point", 820 fh, ((p->name != NULL) ? p->name : ""), ""); 821 } 822 if (p->name == NULL) 823 return (NULL); 824 /* 825 * We should not normally be here - only add to cache if 826 * fh_add failed. 827 */ 828 if ((path == NULL) && 829 ((path = malloc(strlen(p->name) + 1)) == NULL)) { 830 syslog(LOG_ERR, gettext( 831 "update_export_point: malloc '%s' Error %s"), 832 p->name, strerror(errno)); 833 return (NULL); 834 } 835 (void) strcpy(path, p->name); 836 return (path); 837 } 838 if ((path = get_export_path(fh, path)) == NULL) { 839 add_fh_to_export_cache(fh, NULL); 840 return (NULL); 841 } 842 /* Found it! */ 843 if (debug > 2) { 844 PRINT_LINK_DATA(stdout, "update_export_point", fh, path, "") 845 } 846 if (FH_ADD(fhpath, fh, fh, path)) { 847 /* cache this handle so we don't repeat the search */ 848 add_fh_to_export_cache(fh, path); 849 } 850 return (path); 851 } 852 853 /* 854 * HACK!!! To get rid of get_export_path() use 855 */ 856 /* ARGSUSED */ 857 static char * 858 get_export_path(fhandle_t *fh, char *path) 859 { 860 return (NULL); 861 } 862 863 /* 864 * Return the absolute pathname for the filehandle "fh", using the mapping 865 * table "fhlist". The caller must free the return string. 866 * name is an optional dir component name, to be appended at the end 867 * (if name is non-null, the function assumes the fh is the parent directory) 868 * 869 * Note: The original code was recursive, which was much more elegant but 870 * ran out of stack... 871 */ 872 873 static char * 874 fh_print_absolute(char *fhpath, fhandle_t *fh, char *name) 875 { 876 char *str, *rootname, parent[MAXPATHLEN]; 877 int i, j, k, len, error; 878 fhlist_ent fhrec, *fhrecp; 879 fhandle_t prevfh; 880 int namelen; 881 882 if (debug > 3) 883 (void) printf("fh_print_absolute: input name '%s'\n", 884 ((name != NULL) ? name : "")); 885 /* If name starts with '/' we are done */ 886 if ((name != NULL) && (name[0] == '/')) { 887 if ((str = strdup(name)) == NULL) { 888 syslog(LOG_ERR, gettext( 889 "fh_print_absolute: strdup '%s' error %s\n"), 890 name, strerror(errno)); 891 } 892 return (str); 893 } 894 namelen = ((name != NULL) ? strlen(name) + 2 : 0); 895 parent[0] = '\0'; 896 897 /* remember the last filehandle we've seen */ 898 (void) memcpy((void *) &prevfh, (void *) fh, sizeof (*fh)); 899 fh = &prevfh; 900 901 /* dump all names in reverse order */ 902 while ((fhrecp = fh_lookup(fhpath, fh, &fhrec, &error)) != NULL && 903 !(fhrecp->flags & (EXPORT_POINT | PUBLIC_PATH))) { 904 905 if (debug > 3) { 906 (void) printf("fh_print_absolute: name '%s'%s\n", 907 fhrecp->name, 908 ((fhrecp->flags & EXPORT_POINT) ? "root" : "")); 909 } 910 if (memcmp(&prevfh, &fhrecp->dfh, sizeof (*fh)) == 0) { 911 /* dfh == prevfh but not an export point */ 912 if (debug > 1) { 913 (void) printf( 914 "fh_print_absolute: fhrec loop:\n"); 915 debug_opaque_print(stdout, fhrecp, 916 fhrecp->reclen); 917 } 918 break; 919 } 920 (void) strcat(parent, "/"); 921 (void) strcat(parent, fhrecp->name); 922 923 /* remember the last filehandle we've seen */ 924 (void) memcpy(&prevfh, &fhrecp->dfh, sizeof (fhrecp->dfh)); 925 } 926 assert(fh == &prevfh); 927 928 if (fhrecp != NULL) { 929 rootname = fhrecp->name; 930 } else { 931 /* Check if export point, just in case... */ 932 /* There should be enough room in parent, leave the '\0' */ 933 rootname = update_export_point( 934 fhpath, fh, &parent[strlen(parent) + 1]); 935 } 936 /* Now need to reverse the order */ 937 if (rootname != NULL) { /* *fhrecp is the export point */ 938 len = strlen(rootname) + 2; 939 } else { 940 len = 2 * (NFS_FHMAXDATA + fh->fh_len); /* fid instead */ 941 } 942 len = ROUNDUP32(len + namelen + strlen(parent)); 943 if ((str = malloc(len)) == NULL) { 944 syslog(LOG_ERR, gettext( 945 "fh_print_absolute: malloc %d error %s\n"), 946 len, strerror(errno)); 947 return (NULL); 948 } 949 /* first put the export point path in */ 950 if (rootname != NULL) { /* *fhrecp is the export point */ 951 (void) strcpy(str, rootname); 952 } else { 953 sprint_fid(str, len, fh); 954 } 955 for (k = strlen(str), i = strlen(parent); (k < len) && (i >= 0); i--) { 956 for (j = i; (j >= 0) && (parent[j] != '/'); j--); 957 if (j < 0) 958 break; 959 (void) strcpy(&str[k], &parent[j]); 960 k += strlen(&str[k]); 961 parent[j] = '\0'; 962 } 963 if ((name != NULL) && ((k + namelen) <= len)) { 964 str[k] = '/'; 965 (void) strcpy(&str[k + 1], name); 966 } 967 if (debug > 3) 968 (void) printf("fh_print_absolute: path '%s'\n", str); 969 return (str); 970 } 971 972 /* 973 * nfslog_find_fh_dispatch - get the dispatch struct for this request 974 */ 975 static struct nfsl_fh_proc_disp * 976 nfslog_find_fh_dispatch(nfslog_request_record *logrec) 977 { 978 nfslog_record_header *logrechdr = &logrec->re_header; 979 struct nfsl_fh_prog_disp *progtable; /* prog struct */ 980 struct nfsl_fh_vers_disp *verstable; /* version struct */ 981 int i, vers; 982 983 /* Find prog element - search because can't use prog as array index */ 984 for (i = 0; (i < nfsl_fh_dispatch_table_arglen) && 985 (logrechdr->rh_prognum != nfsl_fh_dispatch_table[i].nfsl_dis_prog); 986 i++); 987 if (i >= nfsl_fh_dispatch_table_arglen) { /* program not logged */ 988 /* not an error */ 989 return (NULL); 990 } 991 progtable = &nfsl_fh_dispatch_table[i]; 992 /* Find vers element - no validity check - if here it's valid vers */ 993 vers = logrechdr->rh_version - progtable->nfsl_dis_versmin; 994 verstable = &progtable->nfsl_dis_vers_table[vers]; 995 /* Find proc element - no validity check - if here it's valid proc */ 996 return (&verstable->nfsl_dis_proc_table[logrechdr->rh_procnum]); 997 } 998 999 /* ARGSUSED */ 1000 static void 1001 nfslog_null_fhargs(caddr_t *nfsl_args, caddr_t *nfsl_res, 1002 char *fhpath, char **pathp1, char **pathp2) 1003 { 1004 *pathp1 = NULL; 1005 *pathp2 = NULL; 1006 } 1007 1008 /* 1009 * nfslog_LOOKUP_calc - called by both lookup3 and lookup2. Handles the 1010 * mclookup as well as normal lookups. 1011 */ 1012 /* ARGSUSED */ 1013 static void 1014 nfslog_LOOKUP_calc(fhandle_t *dfh, char *name, fhandle_t *fh, 1015 char *fhpath, char **pathp1, char **pathp2, char *str) 1016 { 1017 int error; 1018 fhlist_ent fhrec; 1019 char *name1 = NULL; 1020 1021 if (fh == &public_fh) { 1022 /* a fake lookup to inform us of the public fs path */ 1023 if (error = FH_ADD(fhpath, fh, fh, name)) { 1024 syslog(LOG_ERR, gettext( 1025 "%s: Add Public fs '%s' failed: %s\n"), 1026 str, name, 1027 ((error >= 0) ? strerror(error) : "Unknown")); 1028 } 1029 if (pathp1 != NULL) { 1030 *pathp1 = nfslog_get_path(dfh, NULL, fhpath, str); 1031 *pathp2 = NULL; 1032 } 1033 return; 1034 } 1035 if (pathp1 != NULL) { 1036 *pathp1 = nfslog_get_path(dfh, name, fhpath, str); 1037 *pathp2 = NULL; 1038 } 1039 1040 /* If public fh mclookup, then insert complete path */ 1041 if (dfh == &public_fh) { 1042 if (pathp1 != NULL) { 1043 name = *pathp1; 1044 } else { 1045 name = nfslog_get_path(dfh, name, fhpath, str); 1046 name1 = name; 1047 } 1048 } 1049 if (fh_lookup_link(fhpath, dfh, fh, name, &fhrec, &error) != NULL) { 1050 /* link already in table */ 1051 if (name1 != NULL) 1052 free(name1); 1053 return; 1054 } 1055 /* A new link so add it */ 1056 if (error = FH_ADD(fhpath, dfh, fh, name)) { 1057 syslog(LOG_ERR, gettext( 1058 "%s: Add fh for '%s' failed: %s\n"), str, 1059 name, ((error >= 0) ? strerror(error) : "Unknown")); 1060 } 1061 if (name1 != NULL) 1062 free(name1); 1063 } 1064 1065 /* 1066 * NFS VERSION 2 1067 */ 1068 1069 /* Functions for updating the fhtable for fhtoppath */ 1070 1071 /* 1072 * nfslog_GETATTR2_fhargs - updates path1 but no fhtable changes 1073 */ 1074 /* ARGSUSED */ 1075 static void 1076 nfslog_GETATTR2_fhargs(fhandle_t *args, nfsstat *res, 1077 char *fhpath, char **pathp1, char **pathp2) 1078 { 1079 if (debug > 2) { 1080 (void) printf("=============\nGETATTR2: fh "); 1081 debug_opaque_print(stdout, args, sizeof (*args)); 1082 (void) printf("\n"); 1083 } 1084 if (pathp1 != NULL) { 1085 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(args), 1086 NULL, fhpath, "getattr2"); 1087 *pathp2 = NULL; 1088 } 1089 } 1090 1091 /* 1092 * nfslog_SETATTR2_fhargs - updates path1 but no fhtable changes 1093 */ 1094 /* ARGSUSED */ 1095 static void 1096 nfslog_SETATTR2_fhargs(nfslog_setattrargs *args, nfsstat *res, 1097 char *fhpath, char **pathp1, char **pathp2) 1098 { 1099 if (debug > 2) { 1100 (void) printf("=============\nSETATTR2: fh "); 1101 debug_opaque_print(stdout, &args->saa_fh, 1102 sizeof (args->saa_fh)); 1103 (void) printf("\n"); 1104 } 1105 if (pathp1 != NULL) { 1106 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(&args->saa_fh), 1107 NULL, fhpath, "setattr2"); 1108 *pathp2 = NULL; 1109 } 1110 } 1111 1112 /* 1113 * nfslog_LOOKUP2_fhargs - search the table to ensure we have not added this 1114 * one already. Note that if the response status was anything but okay, 1115 * there is no fh to check... 1116 */ 1117 /* ARGSUSED */ 1118 static void 1119 nfslog_LOOKUP2_fhargs(nfslog_diropargs *args, nfslog_diropres *res, 1120 char *fhpath, char **pathp1, char **pathp2) 1121 { 1122 char *name; 1123 fhandle_t *dfh, *fh; 1124 1125 dfh = &args->da_fhandle; 1126 name = args->da_name; 1127 if (debug > 2) { 1128 if (res->dr_status == NFS_OK) 1129 fh = &res->nfslog_diropres_u.dr_ok.drok_fhandle; 1130 else 1131 fh = NULL; 1132 PRINT_FULL_DATA(stdout, "=============\nLOOKUP2", 1133 dfh, fh, name, "") 1134 if (res->dr_status != NFS_OK) 1135 (void) printf("status %d\n", res->dr_status); 1136 } 1137 dfh = NFSLOG_GET_FHANDLE2(dfh); 1138 if ((dfh == &public_fh) && (name[0] == '\x80')) { 1139 /* special mclookup */ 1140 name = &name[1]; 1141 } 1142 if (res->dr_status != NFS_OK) { 1143 if (pathp1 != NULL) { 1144 *pathp1 = nfslog_get_path(dfh, name, fhpath, "lookup2"); 1145 *pathp2 = NULL; 1146 } 1147 return; 1148 } 1149 fh = NFSLOG_GET_FHANDLE2(&res->nfslog_diropres_u.dr_ok.drok_fhandle); 1150 nfslog_LOOKUP_calc(dfh, name, fh, fhpath, pathp1, pathp2, "Lookup2"); 1151 } 1152 1153 /* 1154 * nfslog_READLINK2_fhargs - updates path1 but no fhtable changes 1155 */ 1156 /* ARGSUSED */ 1157 static void 1158 nfslog_READLINK2_fhargs(fhandle_t *args, nfslog_rdlnres *res, 1159 char *fhpath, char **pathp1, char **pathp2) 1160 { 1161 if (debug > 2) { 1162 (void) printf("=============\nREADLINK2: fh "); 1163 debug_opaque_print(stdout, args, sizeof (*args)); 1164 (void) printf("\n"); 1165 } 1166 if (pathp1 != NULL) { 1167 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(args), 1168 NULL, fhpath, "readlink2"); 1169 *pathp2 = NULL; 1170 } 1171 } 1172 1173 /* 1174 * nfslog_READ2_fhargs - updates path1 but no fhtable changes 1175 */ 1176 /* ARGSUSED */ 1177 static void 1178 nfslog_READ2_fhargs(nfslog_nfsreadargs *args, nfslog_rdresult *res, 1179 char *fhpath, char **pathp1, char **pathp2) 1180 { 1181 if (debug > 2) { 1182 (void) printf("=============\nREAD2: fh "); 1183 debug_opaque_print(stdout, &args->ra_fhandle, 1184 sizeof (args->ra_fhandle)); 1185 (void) printf("\n"); 1186 } 1187 if (pathp1 != NULL) { 1188 *pathp1 = nfslog_get_path( 1189 NFSLOG_GET_FHANDLE2(&args->ra_fhandle), 1190 NULL, fhpath, "read2"); 1191 *pathp2 = NULL; 1192 } 1193 } 1194 1195 /* 1196 * nfslog_WRITE2_fhargs - updates path1 but no fhtable changes 1197 */ 1198 /* ARGSUSED */ 1199 static void 1200 nfslog_WRITE2_fhargs(nfslog_writeargs *args, nfslog_writeresult *res, 1201 char *fhpath, char **pathp1, char **pathp2) 1202 { 1203 if (debug > 2) { 1204 (void) printf("=============\nWRITE2: fh "); 1205 debug_opaque_print(stdout, &args->waargs_fhandle, 1206 sizeof (args->waargs_fhandle)); 1207 (void) printf("\n"); 1208 } 1209 if (pathp1 != NULL) { 1210 *pathp1 = nfslog_get_path( 1211 NFSLOG_GET_FHANDLE2(&args->waargs_fhandle), 1212 NULL, fhpath, "write2"); 1213 *pathp2 = NULL; 1214 } 1215 } 1216 1217 /* 1218 * nfslog_CREATE2_fhargs - if the operation succeeded, we are sure there can 1219 * be no such link in the fhtable, so just add it. 1220 */ 1221 /* ARGSUSED */ 1222 static void 1223 nfslog_CREATE2_fhargs(nfslog_createargs *args, nfslog_diropres *res, 1224 char *fhpath, char **pathp1, char **pathp2) 1225 { 1226 char *name; 1227 fhandle_t *dfh, *fh; 1228 int error; 1229 1230 name = args->ca_da.da_name; 1231 dfh = &args->ca_da.da_fhandle; 1232 if (debug > 2) { 1233 if (res->dr_status == NFS_OK) 1234 fh = &res->nfslog_diropres_u.dr_ok.drok_fhandle; 1235 else 1236 fh = NULL; 1237 PRINT_FULL_DATA(stdout, "=============\nCREATE2", 1238 dfh, fh, name, "") 1239 if (res->dr_status != NFS_OK) 1240 (void) printf("status %d\n", res->dr_status); 1241 } 1242 dfh = NFSLOG_GET_FHANDLE2(dfh); 1243 if (pathp1 != NULL) { 1244 *pathp1 = nfslog_get_path(dfh, name, fhpath, "create2"); 1245 *pathp2 = NULL; 1246 } 1247 1248 if (res->dr_status != NFS_OK) 1249 /* no returned fh so nothing to add */ 1250 return; 1251 1252 /* A new file handle so add it */ 1253 fh = NFSLOG_GET_FHANDLE2(&res->nfslog_diropres_u.dr_ok.drok_fhandle); 1254 if (error = FH_ADD(fhpath, dfh, fh, name)) { 1255 syslog(LOG_ERR, gettext( 1256 "Create2: Add fh for '%s' failed: %s\n"), 1257 name, ((error >= 0) ? strerror(error) : "Unknown")); 1258 } 1259 } 1260 1261 /* 1262 * nfslog_REMOVE2_fhargs - if the operation succeeded, remove the link from 1263 * the fhtable. 1264 */ 1265 /* ARGSUSED */ 1266 static void 1267 nfslog_REMOVE2_fhargs(nfslog_diropargs *args, nfsstat *res, 1268 char *fhpath, char **pathp1, char **pathp2) 1269 { 1270 char *name; 1271 fhandle_t *dfh; 1272 int error; 1273 1274 name = args->da_name; 1275 dfh = &args->da_fhandle; 1276 if (debug > 2) { 1277 PRINT_LINK_DATA(stdout, "=============\nREMOVE2", dfh, name, "") 1278 if (*res != NFS_OK) 1279 (void) printf("status %d\n", *res); 1280 } 1281 dfh = NFSLOG_GET_FHANDLE2(dfh); 1282 if (pathp1 != NULL) { 1283 *pathp1 = nfslog_get_path(dfh, name, fhpath, "remove2"); 1284 *pathp2 = NULL; 1285 } 1286 1287 if (*res != NFS_OK) 1288 /* remove failed so nothing to update */ 1289 return; 1290 1291 if (error = fh_remove(fhpath, dfh, name, pathp1)) { 1292 syslog(LOG_ERR, gettext("Remove2: '%s' failed: %s\n"), 1293 name, ((error >= 0) ? strerror(error) : "Unknown")); 1294 } 1295 } 1296 1297 /* 1298 * nfsl_RENAME2_fhargs - updates the dfh and name fields for the given fh 1299 * to change them to the new name. 1300 */ 1301 /* ARGSUSED */ 1302 static void 1303 nfslog_RENAME2_fhargs(nfslog_rnmargs *args, nfsstat *res, 1304 char *fhpath, char **pathp1, char **pathp2) 1305 { 1306 char *from_name, *to_name; 1307 fhandle_t *from_dfh, *to_dfh; 1308 int error; 1309 1310 from_name = args->rna_from.da_name; 1311 from_dfh = &args->rna_from.da_fhandle; 1312 to_name = args->rna_to.da_name; 1313 to_dfh = &args->rna_to.da_fhandle; 1314 if (debug > 2) { 1315 PRINT_LINK_DATA(stdout, "=============\nRENAME2: from", 1316 from_dfh, from_name, "") 1317 PRINT_LINK_DATA(stdout, "RENAME2: to ", to_dfh, 1318 to_name, "") 1319 if (*res != NFS_OK) 1320 (void) printf("status %d\n", *res); 1321 } 1322 from_dfh = NFSLOG_GET_FHANDLE2(from_dfh); 1323 to_dfh = NFSLOG_GET_FHANDLE2(to_dfh); 1324 if (pathp1 != NULL) { 1325 *pathp1 = nfslog_get_path(from_dfh, from_name, fhpath, 1326 "rename2 from"); 1327 *pathp2 = nfslog_get_path(to_dfh, to_name, fhpath, 1328 "rename2 to"); 1329 } 1330 1331 if (*res != NFS_OK) 1332 /* rename failed so nothing to update */ 1333 return; 1334 1335 /* Rename the link in the database */ 1336 if (error = fh_rename(fhpath, from_dfh, from_name, pathp1, 1337 to_dfh, to_name)) { 1338 syslog(LOG_ERR, gettext( 1339 "Rename2: Update from '%s' to '%s' failed: %s\n"), 1340 from_name, to_name, 1341 ((error >= 0) ? strerror(error) : "Unknown")); 1342 } 1343 } 1344 1345 /* 1346 * nfslog_LINK2_fhargs - adds link name and fh to fhlist. Note that as a 1347 * result we may have more than one name for an fh. 1348 */ 1349 /* ARGSUSED */ 1350 static void 1351 nfslog_LINK2_fhargs(nfslog_linkargs *args, nfsstat *res, 1352 char *fhpath, char **pathp1, char **pathp2) 1353 { 1354 char *name; 1355 fhandle_t *dfh, *fh; 1356 int error; 1357 1358 fh = &args->la_from; 1359 name = args->la_to.da_name; 1360 dfh = &args->la_to.da_fhandle; 1361 if (debug > 2) { 1362 PRINT_FULL_DATA(stdout, "=============\nLINK2", 1363 dfh, fh, name, "") 1364 if (*res != NFS_OK) 1365 (void) printf("status %d\n", *res); 1366 } 1367 dfh = NFSLOG_GET_FHANDLE2(dfh); 1368 fh = NFSLOG_GET_FHANDLE2(fh); 1369 if (pathp1 != NULL) { 1370 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "link2 from"); 1371 *pathp2 = nfslog_get_path(dfh, name, fhpath, "link2 to"); 1372 } 1373 1374 if (*res != NFS_OK) 1375 /* no returned fh so nothing to add */ 1376 return; 1377 1378 /* A new link so add it, have fh_add find the link count */ 1379 if (error = FH_ADD(fhpath, dfh, fh, name)) { 1380 syslog(LOG_ERR, gettext( 1381 "Link2: Add fh for '%s' failed: %s\n"), 1382 name, ((error >= 0) ? strerror(error) : "Unknown")); 1383 } 1384 } 1385 1386 /* 1387 * nfslog_SYMLINK2_fhargs - adds symlink name and fh to fhlist if fh returned. 1388 */ 1389 /* ARGSUSED */ 1390 static void 1391 nfslog_SYMLINK2_fhargs(nfslog_symlinkargs *args, nfsstat *res, 1392 char *fhpath, char **pathp1, char **pathp2) 1393 { 1394 char *name; 1395 fhandle_t *dfh; 1396 1397 name = args->sla_from.da_name; 1398 dfh = &args->sla_from.da_fhandle; 1399 if (debug > 2) { 1400 PRINT_LINK_DATA(stdout, "=============\nSYMLINK2", 1401 dfh, name, "") 1402 } 1403 dfh = NFSLOG_GET_FHANDLE2(dfh); 1404 if (pathp1 != NULL) { 1405 *pathp1 = nfslog_get_path(dfh, name, fhpath, "symlink2"); 1406 *pathp2 = NULL; 1407 } 1408 } 1409 1410 /* 1411 * nfslog_READDIR2_fhargs - updates path1 but no fhtable changes 1412 */ 1413 /* ARGSUSED */ 1414 static void 1415 nfslog_READDIR2_fhargs(nfslog_rddirargs *args, nfslog_rddirres *res, 1416 char *fhpath, char **pathp1, char **pathp2) 1417 { 1418 if (debug > 2) { 1419 (void) printf("=============\nREADDIR2: fh "); 1420 debug_opaque_print(stdout, &args->rda_fh, 1421 sizeof (args->rda_fh)); 1422 (void) printf("\n"); 1423 } 1424 if (pathp1 != NULL) { 1425 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(&args->rda_fh), 1426 NULL, fhpath, "readdir2"); 1427 *pathp2 = NULL; 1428 } 1429 } 1430 1431 /* 1432 * nfslog_STATFS2_fhargs - updates path1 but no fhtable changes 1433 */ 1434 /* ARGSUSED */ 1435 static void 1436 nfslog_STATFS2_fhargs(fhandle_t *args, nfsstat *res, 1437 char *fhpath, char **pathp1, char **pathp2) 1438 { 1439 if (debug > 2) { 1440 (void) printf("=============\nSTATFS2: fh "); 1441 debug_opaque_print(stdout, args, sizeof (*args)); 1442 (void) printf("\n"); 1443 } 1444 if (pathp1 != NULL) { 1445 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(args), 1446 NULL, fhpath, "statfs2"); 1447 *pathp2 = NULL; 1448 } 1449 } 1450 1451 /* 1452 * NFS VERSION 3 1453 */ 1454 1455 /* Functions for updating the fhtable for fhtoppath */ 1456 1457 /* 1458 * nfslog_GETATTR3_fhargs - updates path1 but no fhtable changes 1459 */ 1460 /* ARGSUSED */ 1461 static void 1462 nfslog_GETATTR3_fhargs(nfs_fh3 *args, nfsstat3 *res, 1463 char *fhpath, char **pathp1, char **pathp2) 1464 { 1465 if (debug > 2) { 1466 (void) printf("=============\nGETATTR3: fh "); 1467 debug_opaque_print(stdout, args, sizeof (*args)); 1468 (void) printf("\n"); 1469 } 1470 if (pathp1 != NULL) { 1471 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL, 1472 fhpath, "getattr3"); 1473 *pathp2 = NULL; 1474 } 1475 } 1476 1477 /* 1478 * nfslog_SETATTR3_fhargs - updates path1 but no fhtable changes 1479 */ 1480 /* ARGSUSED */ 1481 static void 1482 nfslog_SETATTR3_fhargs(nfslog_SETATTR3args *args, nfsstat3 *res, 1483 char *fhpath, char **pathp1, char **pathp2) 1484 { 1485 if (debug > 2) { 1486 (void) printf("=============\nSETATTR3: fh "); 1487 debug_opaque_print(stdout, &args->object, 1488 sizeof (args->object)); 1489 (void) printf("\n"); 1490 } 1491 if (pathp1 != NULL) { 1492 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->object), 1493 NULL, fhpath, "setattr3"); 1494 *pathp2 = NULL; 1495 } 1496 } 1497 1498 /* 1499 * nfslog_LOOKUP3_fhargs - search the table to ensure we have not added this 1500 * one already. Note that if the response status was anything but okay, 1501 * there is no fh to check... 1502 */ 1503 /* ARGSUSED */ 1504 static void 1505 nfslog_LOOKUP3_fhargs(nfslog_diropargs3 *args, nfslog_LOOKUP3res *res, 1506 char *fhpath, char **pathp1, char **pathp2) 1507 { 1508 char *name; 1509 fhandle_t *dfh, *fh; 1510 1511 name = args->name; 1512 dfh = NFSLOG_GET_FHANDLE3(&args->dir); 1513 1514 if (debug > 2) { 1515 if (res->status == NFS3_OK) 1516 fh = NFSLOG_GET_FHANDLE3( 1517 &res->nfslog_LOOKUP3res_u.object); 1518 else 1519 fh = NULL; 1520 PRINT_FULL_DATA(stdout, "=============\nLOOKUP3", 1521 dfh, fh, name, "") 1522 if (res->status != NFS3_OK) 1523 (void) printf("status %d\n", res->status); 1524 } 1525 if ((dfh == &public_fh) && (name[0] == '\x80')) { 1526 /* special mclookup */ 1527 name = &name[1]; 1528 } 1529 if (res->status != NFS3_OK) { 1530 if (pathp1 != NULL) { 1531 *pathp1 = nfslog_get_path(dfh, name, fhpath, "lookup3"); 1532 *pathp2 = NULL; 1533 } 1534 return; 1535 } 1536 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_LOOKUP3res_u.object); 1537 nfslog_LOOKUP_calc(dfh, name, fh, fhpath, pathp1, pathp2, "Lookup3"); 1538 } 1539 1540 /* 1541 * nfslog_ACCESS3_fhargs - updates path1 but no fhtable changes 1542 */ 1543 /* ARGSUSED */ 1544 static void 1545 nfslog_ACCESS3_fhargs(nfs_fh3 *args, nfsstat3 *res, 1546 char *fhpath, char **pathp1, char **pathp2) 1547 { 1548 if (debug > 2) { 1549 (void) printf("=============\nACCESS3: fh "); 1550 debug_opaque_print(stdout, args, 1551 sizeof (*args)); 1552 (void) printf("\n"); 1553 } 1554 if (pathp1 != NULL) { 1555 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), 1556 NULL, fhpath, "access3"); 1557 *pathp2 = NULL; 1558 } 1559 } 1560 1561 /* 1562 * nfslog_READLINK3_fhargs - updates path1 but no fhtable changes 1563 */ 1564 /* ARGSUSED */ 1565 static void 1566 nfslog_READLINK3_fhargs(nfs_fh3 *args, nfslog_READLINK3res *res, 1567 char *fhpath, char **pathp1, char **pathp2) 1568 { 1569 if (debug > 2) { 1570 (void) printf("=============\nREADLINK3: fh "); 1571 debug_opaque_print(stdout, args, sizeof (*args)); 1572 (void) printf("\n"); 1573 } 1574 if (pathp1 != NULL) { 1575 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL, 1576 fhpath, "readlink3"); 1577 *pathp2 = NULL; 1578 } 1579 } 1580 1581 /* 1582 * nfslog_READ3_fhargs - updates path1 but no fhtable changes 1583 */ 1584 /* ARGSUSED */ 1585 static void 1586 nfslog_READ3_fhargs(nfslog_READ3args *args, nfslog_READ3res *res, 1587 char *fhpath, char **pathp1, char **pathp2) 1588 { 1589 if (debug > 2) { 1590 (void) printf("=============\nREAD3: fh "); 1591 debug_opaque_print(stdout, &args->file, 1592 sizeof (args->file)); 1593 (void) printf("\n"); 1594 } 1595 if (pathp1 != NULL) { 1596 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->file), 1597 NULL, fhpath, "read3"); 1598 *pathp2 = NULL; 1599 } 1600 } 1601 1602 /* 1603 * nfslog_WRITE3_fhargs - updates path1 but no fhtable changes 1604 */ 1605 /* ARGSUSED */ 1606 static void 1607 nfslog_WRITE3_fhargs(nfslog_WRITE3args *args, nfslog_WRITE3res *res, 1608 char *fhpath, char **pathp1, char **pathp2) 1609 { 1610 if (debug > 2) { 1611 (void) printf("=============\nWRITE3: fh "); 1612 debug_opaque_print(stdout, &args->file, 1613 sizeof (args->file)); 1614 (void) printf("\n"); 1615 } 1616 if (pathp1 != NULL) { 1617 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->file), 1618 NULL, fhpath, "write3"); 1619 *pathp2 = NULL; 1620 } 1621 } 1622 1623 /* 1624 * nfslog_CREATE3_fhargs - if the operation succeeded, we are sure there can 1625 * be no such link in the fhtable, so just add it. 1626 */ 1627 /* ARGSUSED */ 1628 static void 1629 nfslog_CREATE3_fhargs(nfslog_CREATE3args *args, nfslog_CREATE3res *res, 1630 char *fhpath, char **pathp1, char **pathp2) 1631 { 1632 char *name; 1633 fhandle_t *dfh, *fh; 1634 int error; 1635 1636 name = args->where.name; 1637 dfh = NFSLOG_GET_FHANDLE3(&args->where.dir); 1638 1639 if (debug > 2) { 1640 if (res->status == NFS3_OK) 1641 fh = NFSLOG_GET_FHANDLE3( 1642 &res->nfslog_CREATE3res_u.ok.obj.handle); 1643 else 1644 fh = NULL; 1645 PRINT_FULL_DATA(stdout, "=============\nCREATE3", 1646 dfh, fh, name, "") 1647 if (res->status != NFS3_OK) 1648 (void) printf("status %d\n", res->status); 1649 } 1650 if (pathp1 != NULL) { 1651 *pathp1 = nfslog_get_path(dfh, name, fhpath, "create3"); 1652 *pathp2 = NULL; 1653 } 1654 1655 if ((res->status != NFS3_OK) || 1656 !res->nfslog_CREATE3res_u.ok.obj.handle_follows) 1657 /* no returned fh so nothing to add */ 1658 return; 1659 1660 /* A new file handle so add it */ 1661 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_CREATE3res_u.ok.obj.handle); 1662 if (error = FH_ADD(fhpath, dfh, fh, name)) { 1663 syslog(LOG_ERR, gettext( 1664 "Create3: Add fh for '%s' failed: %s\n"), 1665 name, ((error >= 0) ? strerror(error) : "Unknown")); 1666 } 1667 } 1668 1669 /* 1670 * nfslog_MKDIR3_fhargs - if the operation succeeded, we are sure there can 1671 * be no such link in the fhtable, so just add it. 1672 */ 1673 /* ARGSUSED */ 1674 static void 1675 nfslog_MKDIR3_fhargs(nfslog_MKDIR3args *args, nfslog_MKDIR3res *res, 1676 char *fhpath, char **pathp1, char **pathp2) 1677 { 1678 char *name; 1679 fhandle_t *dfh, *fh; 1680 int error; 1681 1682 name = args->where.name; 1683 dfh = NFSLOG_GET_FHANDLE3(&args->where.dir); 1684 1685 if (debug > 2) { 1686 if (res->status == NFS3_OK) 1687 fh = NFSLOG_GET_FHANDLE3( 1688 &res->nfslog_MKDIR3res_u.obj.handle); 1689 else 1690 fh = NULL; 1691 PRINT_FULL_DATA(stdout, "=============\nMKDIR3", 1692 dfh, fh, name, "") 1693 if (res->status != NFS3_OK) 1694 (void) printf("status %d\n", res->status); 1695 } 1696 if (pathp1 != NULL) { 1697 *pathp1 = nfslog_get_path(dfh, name, fhpath, "mkdir3"); 1698 *pathp2 = NULL; 1699 } 1700 1701 if ((res->status != NFS3_OK) || 1702 !res->nfslog_MKDIR3res_u.obj.handle_follows) 1703 /* no returned fh so nothing to add */ 1704 return; 1705 1706 /* A new file handle so add it */ 1707 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_MKDIR3res_u.obj.handle); 1708 if (error = FH_ADD(fhpath, dfh, fh, name)) { 1709 syslog(LOG_ERR, gettext( 1710 "Mkdir3: Add fh for '%s' failed: %s\n"), 1711 name, ((error >= 0) ? strerror(error) : "Unknown")); 1712 } 1713 } 1714 1715 /* 1716 * nfslog_REMOVE3_fhargs - if the operation succeeded, remove the link from 1717 * the fhtable. 1718 */ 1719 /* ARGSUSED */ 1720 static void 1721 nfslog_REMOVE3_fhargs(nfslog_REMOVE3args *args, nfsstat3 *res, 1722 char *fhpath, char **pathp1, char **pathp2) 1723 { 1724 char *name; 1725 fhandle_t *dfh; 1726 int error; 1727 1728 name = args->object.name; 1729 dfh = NFSLOG_GET_FHANDLE3(&args->object.dir); 1730 1731 if (debug > 2) { 1732 PRINT_LINK_DATA(stdout, "=============\nREMOVE3", dfh, name, "") 1733 if (*res != NFS3_OK) 1734 (void) printf("status %d\n", *res); 1735 } 1736 if (pathp1 != NULL) { 1737 *pathp1 = nfslog_get_path(dfh, name, fhpath, "remove3"); 1738 *pathp2 = NULL; 1739 } 1740 1741 if (*res != NFS3_OK) 1742 /* remove failed so nothing to update */ 1743 return; 1744 1745 if (error = fh_remove(fhpath, dfh, name, pathp1)) { 1746 syslog(LOG_ERR, gettext("Remove3: '%s' failed: %s\n"), 1747 name, ((error >= 0) ? strerror(error) : "Unknown")); 1748 } 1749 } 1750 1751 /* 1752 * nfslog_RMDIR3_fhargs - if the operation succeeded, remove the link from 1753 * the fhtable. 1754 */ 1755 /* ARGSUSED */ 1756 static void 1757 nfslog_RMDIR3_fhargs(nfslog_RMDIR3args *args, nfsstat3 *res, 1758 char *fhpath, char **pathp1, char **pathp2) 1759 { 1760 char *name; 1761 fhandle_t *dfh; 1762 int error; 1763 1764 name = args->object.name; 1765 dfh = NFSLOG_GET_FHANDLE3(&args->object.dir); 1766 1767 if (debug > 2) { 1768 PRINT_LINK_DATA(stdout, "=============\nRMDIR3", dfh, name, "") 1769 if (*res != NFS3_OK) 1770 (void) printf("status %d\n", *res); 1771 } 1772 if (pathp1 != NULL) { 1773 *pathp1 = nfslog_get_path(dfh, name, fhpath, "rmdir3"); 1774 *pathp2 = NULL; 1775 } 1776 1777 if (*res != NFS3_OK) 1778 /* rmdir failed so nothing to update */ 1779 return; 1780 1781 if (error = fh_remove(fhpath, dfh, name, pathp1)) { 1782 syslog(LOG_ERR, gettext("Rmdir3: '%s' failed: %s\n"), 1783 name, ((error >= 0) ? strerror(error) : "Unknown")); 1784 } 1785 } 1786 1787 /* 1788 * nfslog_RENAME3_fhargs - if the operation succeeded, update the existing 1789 * fhtable entry to point to new dir and name. 1790 */ 1791 /* ARGSUSED */ 1792 static void 1793 nfslog_RENAME3_fhargs(nfslog_RENAME3args *args, nfsstat3 *res, 1794 char *fhpath, char **pathp1, char **pathp2) 1795 { 1796 char *from_name, *to_name; 1797 fhandle_t *from_dfh, *to_dfh; 1798 int error; 1799 1800 from_name = args->from.name; 1801 from_dfh = NFSLOG_GET_FHANDLE3(&args->from.dir); 1802 to_name = args->to.name; 1803 to_dfh = NFSLOG_GET_FHANDLE3(&args->to.dir); 1804 1805 if (debug > 2) { 1806 PRINT_LINK_DATA(stdout, "=============\nRENAME3: from", 1807 from_dfh, from_name, "") 1808 PRINT_LINK_DATA(stdout, "=============\nRENAME3: to ", 1809 to_dfh, to_name, "") 1810 if (*res != NFS3_OK) 1811 (void) printf("status %d\n", *res); 1812 } 1813 if (pathp1 != NULL) { 1814 *pathp1 = nfslog_get_path(from_dfh, from_name, fhpath, 1815 "rename3 from"); 1816 *pathp2 = nfslog_get_path(to_dfh, to_name, fhpath, 1817 "rename3 to"); 1818 } 1819 if (*res != NFS3_OK) 1820 /* rename failed so nothing to update */ 1821 return; 1822 1823 if (error = fh_rename(fhpath, from_dfh, from_name, pathp1, 1824 to_dfh, to_name)) { 1825 syslog(LOG_ERR, gettext( 1826 "Rename3: Update from '%s' to '%s' failed: %s\n"), 1827 from_name, to_name, 1828 ((error >= 0) ? strerror(error) : "Unknown")); 1829 } 1830 } 1831 1832 /* 1833 * nfslog_LINK3_fhargs - if the operation succeeded, we are sure there can 1834 * be no such link in the fhtable, so just add it. 1835 */ 1836 /* ARGSUSED */ 1837 static void 1838 nfslog_LINK3_fhargs(nfslog_LINK3args *args, nfsstat3 *res, 1839 char *fhpath, char **pathp1, char **pathp2) 1840 { 1841 char *name; 1842 fhandle_t *dfh, *fh; 1843 int error; 1844 1845 fh = NFSLOG_GET_FHANDLE3(&args->file); 1846 name = args->link.name; 1847 dfh = NFSLOG_GET_FHANDLE3(&args->link.dir); 1848 1849 if (debug > 2) { 1850 PRINT_FULL_DATA(stdout, "=============\nLINK3", 1851 dfh, fh, name, "") 1852 if (*res != NFS3_OK) 1853 (void) printf("status %d\n", *res); 1854 } 1855 if (pathp1 != NULL) { 1856 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "link3 from"); 1857 *pathp2 = nfslog_get_path(dfh, name, fhpath, "link3 to"); 1858 } 1859 1860 if (*res != NFS3_OK) 1861 /* link failed so nothing to add */ 1862 return; 1863 1864 /* A new link so add it, have fh_add find link count */ 1865 if (error = FH_ADD(fhpath, dfh, fh, name)) { 1866 syslog(LOG_ERR, gettext( 1867 "Link3: Add fh for '%s' failed: %s\n"), 1868 name, ((error >= 0) ? strerror(error) : "Unknown")); 1869 } 1870 } 1871 1872 /* 1873 * nfslog_MKNOD3_fhargs - if the operation succeeded, we are sure there can 1874 * be no such link in the fhtable, so just add it. 1875 */ 1876 /* ARGSUSED */ 1877 static void 1878 nfslog_MKNOD3_fhargs(nfslog_MKNOD3args *args, nfslog_MKNOD3res *res, 1879 char *fhpath, char **pathp1, char **pathp2) 1880 { 1881 char *name; 1882 fhandle_t *dfh, *fh; 1883 int error; 1884 1885 name = args->where.name; 1886 dfh = NFSLOG_GET_FHANDLE3(&args->where.dir); 1887 1888 if (debug > 2) { 1889 if (res->status == NFS3_OK) 1890 fh = NFSLOG_GET_FHANDLE3( 1891 &res->nfslog_MKNOD3res_u.obj.handle); 1892 else 1893 fh = NULL; 1894 PRINT_FULL_DATA(stdout, "=============\nMKNOD3", 1895 dfh, fh, name, "") 1896 if (res->status != NFS3_OK) 1897 (void) printf("status %d\n", res->status); 1898 } 1899 if (pathp1 != NULL) { 1900 *pathp1 = nfslog_get_path(dfh, name, fhpath, "mknod3"); 1901 *pathp2 = NULL; 1902 } 1903 if ((res->status != NFS3_OK) || 1904 !res->nfslog_MKNOD3res_u.obj.handle_follows) 1905 /* no returned fh so nothing to add */ 1906 return; 1907 1908 /* A new file handle so add it */ 1909 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_MKNOD3res_u.obj.handle); 1910 if (error = FH_ADD(fhpath, dfh, fh, name)) { 1911 syslog(LOG_ERR, gettext("Mknod3: Add fh for '%s' failed: %s\n"), 1912 name, ((error >= 0) ? strerror(error) : "Unknown")); 1913 } 1914 } 1915 1916 /* 1917 * nfslog_SYMLINK3_fhargs - if the operation succeeded, we are sure there can 1918 * be no such link in the fhtable, so just add it. 1919 */ 1920 /* ARGSUSED */ 1921 static void 1922 nfslog_SYMLINK3_fhargs(nfslog_SYMLINK3args *args, nfslog_SYMLINK3res *res, 1923 char *fhpath, char **pathp1, char **pathp2) 1924 { 1925 char *name; 1926 fhandle_t *dfh, *fh; 1927 int error; 1928 1929 name = args->where.name; 1930 dfh = NFSLOG_GET_FHANDLE3(&args->where.dir); 1931 1932 if (debug > 2) { 1933 if (res->status == NFS3_OK) 1934 fh = NFSLOG_GET_FHANDLE3( 1935 &res->nfslog_SYMLINK3res_u.obj.handle); 1936 else 1937 fh = NULL; 1938 PRINT_FULL_DATA(stdout, "=============\nSYMLINK3", 1939 dfh, fh, name, "") 1940 if (res->status != NFS3_OK) 1941 (void) printf("status %d\n", res->status); 1942 } 1943 if (pathp1 != NULL) { 1944 *pathp1 = nfslog_get_path(dfh, name, fhpath, "symlink3"); 1945 *pathp2 = NULL; 1946 } 1947 1948 if ((res->status != NFS3_OK) || 1949 !res->nfslog_SYMLINK3res_u.obj.handle_follows) 1950 /* no returned fh so nothing to add */ 1951 return; 1952 1953 /* A new file handle so add it */ 1954 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_SYMLINK3res_u.obj.handle); 1955 if (error = FH_ADD(fhpath, dfh, fh, name)) { 1956 syslog(LOG_ERR, gettext( 1957 "Symlink3: Add fh for '%s' failed: %s\n"), 1958 name, ((error >= 0) ? strerror(error) : "Unknown")); 1959 } 1960 } 1961 1962 /* 1963 * nfslog_READDIR3_fhargs - updates path1 but no fhtable changes 1964 */ 1965 /* ARGSUSED */ 1966 static void 1967 nfslog_READDIR3_fhargs(nfs_fh3 *args, nfsstat3 *res, 1968 char *fhpath, char **pathp1, char **pathp2) 1969 { 1970 if (debug > 2) { 1971 (void) printf("=============\nREADDIR3: fh "); 1972 debug_opaque_print(stdout, args, 1973 sizeof (*args)); 1974 (void) printf("\n"); 1975 } 1976 if (pathp1 != NULL) { 1977 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), 1978 NULL, fhpath, "readdir3"); 1979 *pathp2 = NULL; 1980 } 1981 } 1982 1983 /* 1984 * nfslog_READDIRPLUS3_fhargs - updates path1 but no fhtable changes 1985 */ 1986 /* ARGSUSED */ 1987 static void 1988 nfslog_READDIRPLUS3_fhargs(nfslog_READDIRPLUS3args *args, 1989 nfslog_READDIRPLUS3res *res, 1990 char *fhpath, char **pathp1, char **pathp2) 1991 { 1992 char *name; 1993 fhandle_t *dfh, *fh; 1994 nfslog_entryplus3 *ep; 1995 1996 if (debug > 2) { 1997 (void) printf("=============\nREADDIRPLUS3: fh "); 1998 debug_opaque_print(stdout, &args->dir, 1999 sizeof (args->dir)); 2000 (void) printf("\n"); 2001 } 2002 if (pathp1 != NULL) { 2003 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->dir), 2004 NULL, fhpath, "readdirplus3"); 2005 *pathp2 = NULL; 2006 } 2007 2008 if (res->status == NFS3_OK) { 2009 2010 dfh = NFSLOG_GET_FHANDLE3(&args->dir); 2011 2012 /* 2013 * Loop through the fh/name pair and add them 2014 * to the mappings. 2015 */ 2016 for (ep = res->nfslog_READDIRPLUS3res_u.ok.reply.entries; 2017 ep != NULL; 2018 ep = ep->nextentry) { 2019 2020 name = ep->name; 2021 2022 fh = NFSLOG_GET_FHANDLE3(&ep->name_handle.handle); 2023 2024 nfslog_LOOKUP_calc(dfh, name, fh, 2025 fhpath, NULL, NULL, 2026 "ReaddirPlus3"); 2027 } 2028 } 2029 } 2030 2031 /* 2032 * nfslog_FSSTAT3_fhargs - updates path1 but no fhtable changes 2033 */ 2034 /* ARGSUSED */ 2035 static void 2036 nfslog_FSSTAT3_fhargs(nfs_fh3 *args, nfsstat3 *res, 2037 char *fhpath, char **pathp1, char **pathp2) 2038 { 2039 if (debug > 2) { 2040 (void) printf("=============\nFSSTAT3: fh "); 2041 debug_opaque_print(stdout, args, 2042 sizeof (*args)); 2043 (void) printf("\n"); 2044 } 2045 if (pathp1 != NULL) { 2046 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL, 2047 fhpath, "fsstat3"); 2048 *pathp2 = NULL; 2049 } 2050 } 2051 2052 /* 2053 * nfslog_FSINFO3_fhargs - updates path1 but no fhtable changes 2054 */ 2055 /* ARGSUSED */ 2056 static void 2057 nfslog_FSINFO3_fhargs(nfs_fh3 *args, nfsstat3 *res, 2058 char *fhpath, char **pathp1, char **pathp2) 2059 { 2060 if (debug > 2) { 2061 (void) printf("=============\nFSINFO3: fh "); 2062 debug_opaque_print(stdout, args, 2063 sizeof (*args)); 2064 (void) printf("\n"); 2065 } 2066 if (pathp1 != NULL) { 2067 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL, 2068 fhpath, "fsinfo3"); 2069 *pathp2 = NULL; 2070 } 2071 } 2072 2073 /* 2074 * nfslog_PATHCONF3_fhargs - updates path1 but no fhtable changes 2075 */ 2076 /* ARGSUSED */ 2077 static void 2078 nfslog_PATHCONF3_fhargs(nfs_fh3 *args, nfsstat3 *res, 2079 char *fhpath, char **pathp1, char **pathp2) 2080 { 2081 if (debug > 2) { 2082 (void) printf("=============\nPATHCONF3: fh "); 2083 debug_opaque_print(stdout, args, 2084 sizeof (*args)); 2085 (void) printf("\n"); 2086 } 2087 if (pathp1 != NULL) { 2088 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL, 2089 fhpath, "pathconf3"); 2090 *pathp2 = NULL; 2091 } 2092 } 2093 2094 /* 2095 * nfslog_COMMIT3_fhargs - updates path1 but no fhtable changes 2096 */ 2097 /* ARGSUSED */ 2098 static void 2099 nfslog_COMMIT3_fhargs(nfslog_COMMIT3args *args, nfsstat3 *res, 2100 char *fhpath, char **pathp1, char **pathp2) 2101 { 2102 if (debug > 2) { 2103 (void) printf("=============\nCOMMIT3: fh "); 2104 debug_opaque_print(stdout, &args->file, 2105 sizeof (args->file)); 2106 (void) printf("\n"); 2107 } 2108 if (pathp1 != NULL) { 2109 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->file), 2110 NULL, fhpath, "commit3"); 2111 *pathp2 = NULL; 2112 } 2113 } 2114 2115 /* 2116 * NFSLOG VERSION 1 2117 */ 2118 2119 /* 2120 * nfslog_SHARE_fhargs - adds export path and handle to fhlist 2121 */ 2122 /* ARGSUSED */ 2123 static void 2124 nfslog_SHARE_fhargs(nfslog_sharefsargs *args, nfslog_sharefsres *res, 2125 char *fhpath, char **pathp1, char **pathp2) 2126 { 2127 fhlist_ent fhrec; 2128 fhandle_t *fh; 2129 int error; 2130 2131 if (debug > 2) { 2132 (void) printf( 2133 "=============\nSHARE: name '%s', fh ", args->sh_path); 2134 debug_opaque_print(stdout, &args->sh_fh_buf, 2135 sizeof (fhandle_t)); 2136 (void) printf("\n"); 2137 } 2138 2139 fh = &args->sh_fh_buf; 2140 2141 /* 2142 * This bcopy is done because the fh_data for the export/share directory 2143 * is not meaningful with respect to the database keys. Therefore, we 2144 * copy the export or fh_xdata fid to the fh_data so that a reasonable 2145 * entry will be added in the data base. 2146 */ 2147 bcopy(fh->fh_xdata, fh->fh_data, fh->fh_xlen); 2148 2149 /* If debug print the database */ 2150 if (debug > 10) { 2151 fh_print_all_keys(fhpath, fh); 2152 } 2153 if (fh_lookup_link(fhpath, fh, fh, 2154 args->sh_path, &fhrec, &error) == NULL) { 2155 if (error = FH_ADD(fhpath, fh, fh, args->sh_path)) { 2156 syslog(LOG_ERR, gettext( 2157 "Share: Add fh for '%s' failed: %s\n"), 2158 args->sh_path, ((error >= 0) ? 2159 strerror(error) : "Unknown")); 2160 } 2161 } 2162 if (pathp1 != NULL) { 2163 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "share"); 2164 *pathp2 = NULL; 2165 } 2166 } 2167 2168 /* 2169 * nfslog_UNSHARE_fhargs - remove export path and handle from fhlist 2170 */ 2171 /* ARGSUSED */ 2172 static void 2173 nfslog_UNSHARE_fhargs(nfslog_sharefsargs *args, nfslog_sharefsres *res, 2174 char *fhpath, char **pathp1, char **pathp2) 2175 { 2176 fhandle_t *fh; 2177 int error; 2178 2179 if (debug > 2) { 2180 (void) printf("=============\nUNSHARE: name '%s', fh ", 2181 args->sh_path); 2182 debug_opaque_print(stdout, &args->sh_fh_buf, 2183 sizeof (fhandle_t)); 2184 (void) printf("\n"); 2185 } 2186 2187 fh = &args->sh_fh_buf; 2188 2189 /* 2190 * This bcopy is done because the fh_data for the export/share directory 2191 * is not meaningful with respect to the database keys. Therefore, we 2192 * copy the export or fh_xdata fid to the fh_data so that a reasonable 2193 * entry will be added in the data base. 2194 */ 2195 bcopy(fh->fh_xdata, fh->fh_data, fh->fh_xlen); 2196 2197 /* If debug print the database */ 2198 if (debug > 10) { 2199 fh_print_all_keys(fhpath, fh); 2200 } 2201 if (pathp1 != NULL) { 2202 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "share"); 2203 *pathp2 = NULL; 2204 } 2205 if (error = fh_remove(fhpath, fh, args->sh_path, pathp1)) { 2206 syslog(LOG_ERR, gettext("Unshare: '%s' failed: %s\n"), 2207 args->sh_path, ((error >= 0) ? strerror(error) : 2208 "Unknown")); 2209 } 2210 } 2211 2212 /* ARGSUSED */ 2213 static void 2214 nfslog_GETFH_fhargs(nfslog_getfhargs *args, nfsstat *res, 2215 char *fhpath, char **pathp1, char **pathp2) 2216 { 2217 fhlist_ent fhrec; 2218 fhandle_t *fh; 2219 int error; 2220 2221 if (debug > 2) { 2222 (void) printf("=============\nGETFH3: name '%s', fh ", 2223 args->gfh_path); 2224 debug_opaque_print(stdout, &args->gfh_fh_buf, 2225 sizeof (fhandle_t)); 2226 (void) printf("\n"); 2227 } 2228 2229 fh = &args->gfh_fh_buf; 2230 2231 /* If debug print the database */ 2232 if (debug > 10) { 2233 fh_print_all_keys(fhpath, fh); 2234 } 2235 if (fh_lookup_link(fhpath, fh, fh, 2236 args->gfh_path, &fhrec, &error) == NULL) { 2237 if (error = FH_ADD(fhpath, fh, fh, args->gfh_path)) { 2238 syslog(LOG_ERR, gettext( 2239 "Getfh: Add fh for '%s' failed: %s\n"), 2240 args->gfh_path, ((error >= 0) ? 2241 strerror(error) : "Unknown")); 2242 } 2243 } 2244 if (pathp1 != NULL) { 2245 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "getfh"); 2246 *pathp2 = NULL; 2247 } 2248 } 2249 2250 /* 2251 * Exported function 2252 */ 2253 2254 /* 2255 * nfslog_get_path - gets the path for this file. fh must be supplied, 2256 * name may be null. If name is supplied, fh is assumed to be a directory 2257 * filehandle, with name as its component. fhpath is the generic path for the 2258 * fhtopath table and prtstr is the name of the caller (for debug purposes). 2259 * Returns the malloc'd path. The caller must free it later. 2260 */ 2261 char * 2262 nfslog_get_path(fhandle_t *fh, char *name, char *fhpath, char *prtstr) 2263 { 2264 char *pathp = fh_print_absolute(fhpath, fh, name); 2265 2266 if (debug > 3) { 2267 (void) printf(" %s: path '%s', fh ", prtstr, pathp); 2268 debug_opaque_print(stdout, fh, sizeof (*fh)); 2269 (void) printf("\n"); 2270 } 2271 return (pathp); 2272 } 2273 2274 /* 2275 * nfslog_process_fh_rec - updates the fh table based on the rpc req 2276 * Return 0 for success, error otherwise. If success return the path 2277 * for the input file handle(s) if so indicated. 2278 */ 2279 int 2280 nfslog_process_fh_rec(struct nfslog_lr *lrp, char *fhpath, char **pathp1, 2281 char **pathp2, bool_t return_path) 2282 { 2283 struct nfsl_fh_proc_disp *disp; 2284 nfslog_request_record *logrec = &lrp->log_record; 2285 nfslog_record_header *logrechdr = &logrec->re_header; 2286 2287 if ((disp = nfslog_find_fh_dispatch(logrec)) != NULL) { 2288 /* 2289 * Allocate space for the args and results and decode 2290 */ 2291 logrec->re_rpc_arg = calloc(1, disp->args_size); 2292 2293 if (!(*disp->xdr_args)(&lrp->xdrs, logrec->re_rpc_arg)) { 2294 free(logrec->re_rpc_arg); 2295 logrec->re_rpc_arg = NULL; 2296 syslog(LOG_ERR, gettext("argument decode failed")); 2297 return (FALSE); 2298 } 2299 /* used later for free of data structures */ 2300 lrp->xdrargs = disp->xdr_args; 2301 2302 logrec->re_rpc_res = calloc(1, disp->res_size); 2303 if (!(*disp->xdr_res)(&lrp->xdrs, logrec->re_rpc_res)) { 2304 free(logrec->re_rpc_res); 2305 logrec->re_rpc_res = NULL; 2306 syslog(LOG_ERR, gettext("results decode failed")); 2307 return (FALSE); 2308 } 2309 /* used later for free of data structures */ 2310 lrp->xdrres = disp->xdr_res; 2311 2312 /* 2313 * Process the operation within the context of the file handle 2314 * mapping process 2315 */ 2316 if (return_path) { 2317 (*disp->nfsl_dis_args)(logrec->re_rpc_arg, 2318 logrec->re_rpc_res, fhpath, pathp1, pathp2); 2319 } else { 2320 if ((logrechdr->rh_version == NFS_VERSION && 2321 logrechdr->rh_procnum == RFS_LINK) || 2322 (logrechdr->rh_version == NFS_V3 && 2323 logrechdr->rh_procnum == NFSPROC3_LINK)) { 2324 2325 (*disp->nfsl_dis_args)(logrec->re_rpc_arg, 2326 logrec->re_rpc_res, 2327 fhpath, pathp1, pathp2); 2328 } else { 2329 (*disp->nfsl_dis_args)(logrec->re_rpc_arg, 2330 logrec->re_rpc_res, 2331 fhpath, NULL, NULL); 2332 } 2333 } 2334 return (TRUE); 2335 } else { 2336 syslog(LOG_ERR, gettext("procedure unknown")); 2337 return (FALSE); 2338 } 2339 } 2340