1/* 2 * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved 25 */ 26/* 27 * Copyright (c) 1992, 1993 28 * The Regents of the University of California. All rights reserved. 29 * 30 * The NEXTSTEP Software License Agreement specifies the terms 31 * and conditions for redistribution. 32 * 33 * @(#)webdav.h 8.4 (Berkeley) 1/21/94 34 */ 35 36#ifndef _WEBDAV_H_INCLUDE 37#define _WEBDAV_H_INCLUDE 38 39#include <sys/types.h> 40#include <sys/stat.h> 41#include <sys/ucred.h> 42#include <sys/vnode.h> 43#include <sys/mount.h> 44#include <sys/ioccom.h> 45 46#ifdef KERNEL 47#include <libkern/locks.h> 48 #define DEBUG 0 49#else 50 #define DEBUG 0 51#endif 52/* Webdav file operation constants */ 53#define WEBDAV_LOOKUP 1 54#define WEBDAV_CREATE 2 55#define WEBDAV_OPEN 3 56#define WEBDAV_CLOSE 4 57#define WEBDAV_GETATTR 5 58#define WEBDAV_SETATTR 6 59#define WEBDAV_READ 7 60#define WEBDAV_WRITE 8 61#define WEBDAV_FSYNC 9 62#define WEBDAV_REMOVE 10 63#define WEBDAV_RENAME 11 64#define WEBDAV_MKDIR 12 65#define WEBDAV_RMDIR 13 66#define WEBDAV_READDIR 14 67#define WEBDAV_STATFS 15 68#define WEBDAV_UNMOUNT 16 69#define WEBDAV_INVALCACHES 17 70/* for the future */ 71#define WEBDAV_LINK 18 72#define WEBDAV_SYMLINK 19 73#define WEBDAV_READLINK 20 74#define WEBDAV_MKNOD 21 75#define WEBDAV_GETATTRLIST 22 76#define WEBDAV_SETATTRLIST 23 77#define WEBDAV_EXCHANGE 24 78#define WEBDAV_READDIRATTR 25 79#define WEBDAV_SEARCHFS 26 80#define WEBDAV_COPYFILE 27 81#define WEBDAV_WRITESEQ 28 82#define WEBDAV_DUMP_COOKIES 29 83#define WEBDAV_CLEAR_COOKIES 30 84 85/* Webdav file type constants */ 86#define WEBDAV_FILE_TYPE 1 87#define WEBDAV_DIR_TYPE 2 88 89/* The WEBDAV_MAX_IO_BUFFER_SIZE gates how many bytes we 90 * will try to read with a byte range request to the server. 91 * Because sockets are only so big we can't transfer 8192 bytes. 92 * That many bytes won't fit in a buffer so rather than having 93 * webdav_sendmsg wait for all data, it would have to loop. Limiting 94 * at 8000 works (based on emprical study on Darwin). If you are porting 95 * this code to another platform or if the default socket buffer size 96 * changes you may need to change this constan to implement the looping. 97 * None of this would be necessary if Darwin's soreserve actually did reserve 98 * space rather than just enforcing limits 99 */ 100 101#define WEBDAV_MAX_IO_BUFFER_SIZE 8000 /* Gates byte read optimization */ 102 103/* Shared (kernel & processs) WebDAV structures */ 104 105typedef int webdav_filetype_t; 106 107// XXX Dependency on __DARWIN_64_BIT_INO_T 108// We cannot pass ino_t back and forth between the kext and 109// webdavfs_agent, because ino_t is in flux right now. 110// In user space ino_t is 64-bits, but 32 bits in kernel space. 111// So we have to define our own type for now (webdav_ino_t). 112// 113// This was the root cause of: 114// <rdar://problem/6491194> 10A245+10A246: WebDAV FS complains about file names being too long. 115// 116// Once ino_t is identical in length for kernel and user space, then 117// we can get rid of webdav_ino_t and just use ino_t exclusively. 118// 119typedef uint32_t webdav_ino_t; 120 121/* Shared (kernel & process) WebDAV defninitions */ 122 123/* 124 * An opaque_id is used to find a file system object in userland. 125 * Lookup returns it. The rest of the operations which act upon a file system 126 * object use it. If the file system object in userland goes away, the opaque_id 127 * will be invalidated and messages to userland will fail with ESTALE. 128 * The opaque_id 0 (kInvalidOpaqueID) is never valid. 129 */ 130#define kInvalidOpaqueID 0 131typedef uint32_t opaque_id; 132 133/* 134 * IMPORTANT: struct user_webdav_args, struct webdav_args, and webdav_mount() 135 * must all be changed if the structure changes. 136 */ 137 138/* 139 * kCurrentWebdavArgsVersion MUST be incremented anytime changes are made in 140 * either the WebDAV file system's kernel or user-land code which require both 141 * executables to be released as a set. 142 */ 143#define kCurrentWebdavArgsVersion 5 144 145#pragma options align=packed 146 147struct webdav_vfsstatfs 148{ 149 uint32_t f_bsize; /* fundamental file system block size */ 150 uint32_t f_iosize; /* optimal transfer block size */ 151 uint64_t f_blocks; /* total data blocks in file system */ 152 uint64_t f_bfree; /* free blocks in fs */ 153 uint64_t f_bavail; /* free blocks avail to non-superuser */ 154 uint64_t f_files; /* total file nodes in file system */ 155 uint64_t f_ffree; /* free file nodes in fs */ 156}; 157 158struct user_webdav_args 159{ 160 user_addr_t pa_mntfromname; /* mntfromname */ 161 int pa_version; /* argument struct version */ 162 int pa_socket_namelen; /* Socket to server name length */ 163 user_addr_t pa_socket_name; /* Socket to server name */ 164 user_addr_t pa_vol_name; /* volume name */ 165 u_int32_t pa_flags; /* flag bits for mount */ 166 u_int32_t pa_server_ident; /* identifies some (not all) types of servers we are connected to */ 167 opaque_id pa_root_id; /* root opaque_id */ 168 webdav_ino_t pa_root_fileid; /* root fileid */ 169 uid_t pa_uid; /* effective uid of the mounting user */ 170 gid_t pa_gid; /* effective gid of the mounting user */ 171 off_t pa_dir_size; /* size of directories */ 172 /* pathconf values: >=0 to return value; -1 if not supported */ 173 int pa_link_max; /* maximum value of a file's link count */ 174 int pa_name_max; /* The maximum number of bytes in a file name (does not include null at end) */ 175 int pa_path_max; /* The maximum number of bytes in a relative pathname (does not include null at end) */ 176 int pa_pipe_buf; /* The maximum number of bytes that can be written atomically to a pipe (usually PIPE_BUF if supported) */ 177 int pa_chown_restricted; /* Return _POSIX_CHOWN_RESTRICTED if appropriate privileges are required for the chown(2) */ 178 int pa_no_trunc; /* Return _POSIX_NO_TRUNC if file names longer than KERN_NAME_MAX are truncated */ 179 /* end of webdav_args version 1 */ 180 struct webdav_vfsstatfs pa_vfsstatfs; /* need this to fill out the statfs struct during the mount */ 181}; 182 183struct webdav_args 184{ 185 char *pa_mntfromname; /* mntfromname */ 186 int pa_version; /* argument struct version */ 187 int pa_socket_namelen; /* Socket to server name length */ 188 struct sockaddr *pa_socket_name; /* Socket to server name */ 189 char *pa_vol_name; /* volume name */ 190 u_int32_t pa_flags; /* flag bits for mount */ 191 u_int32_t pa_server_ident; /* identifies some (not all) types of servers we are connected to */ 192 opaque_id pa_root_id; /* root opaque_id */ 193 webdav_ino_t pa_root_fileid; /* root fileid */ 194 uid_t pa_uid; /* effective uid of the mounting user */ 195 gid_t pa_gid; /* effective gid of the mounting user */ 196 off_t pa_dir_size; /* size of directories */ 197 /* pathconf values: >=0 to return value; -1 if not supported */ 198 int pa_link_max; /* maximum value of a file's link count */ 199 int pa_name_max; /* The maximum number of bytes in a file name (does not include null at end) */ 200 int pa_path_max; /* The maximum number of bytes in a relative pathname (does not include null at end) */ 201 int pa_pipe_buf; /* The maximum number of bytes that can be written atomically to a pipe (usually PIPE_BUF if supported) */ 202 int pa_chown_restricted; /* Return _POSIX_CHOWN_RESTRICTED if appropriate privileges are required for the chown(2) */ 203 int pa_no_trunc; /* Return _POSIX_NO_TRUNC if file names longer than KERN_NAME_MAX are truncated */ 204 /* end of webdav_args version 1 */ 205 struct webdav_vfsstatfs pa_vfsstatfs; /* need this to fill out the statfs struct during the mount */ 206}; 207 208 209/* Defines for webdav_args pa_flags field */ 210#define WEBDAV_SUPPRESSALLUI 0x00000001 /* SuppressAllUI flag */ 211#define WEBDAV_SECURECONNECTION 0x00000002 /* Secure connection flag (the connection to the server is secure) */ 212 213/* Defines for webdav_args pa_server_ident field */ 214#define WEBDAV_IDISK_SERVER 0x00000001 215#define WEBDAV_MICROSOFT_IIS_SERVER 0x00000002 216 217struct webdav_cred 218{ 219 uid_t pcr_uid; /* From ucred */ 220}; 221 222/* WEBDAV_LOOKUP */ 223struct webdav_request_lookup 224{ 225 struct webdav_cred pcr; /* user and groups */ 226 opaque_id dir_id; /* directory to search */ 227 int force_lookup; /* if TRUE, don't use a cached lookup */ 228 uint32_t name_length; /* length of name */ 229 char name[]; /* filename to find */ 230}; 231 232struct webdav_timespec64 233{ 234 uint64_t tv_sec; 235 uint64_t tv_nsec; 236}; 237 238struct webdav_reply_lookup 239{ 240 opaque_id obj_id; /* opaque_id of object corresponding to name */ 241 webdav_ino_t obj_fileid; /* object's file ID number */ 242 webdav_filetype_t obj_type; /* WEBDAV_FILE_TYPE or WEBDAV_DIR_TYPE */ 243 struct webdav_timespec64 obj_atime; /* time of last access */ 244 struct webdav_timespec64 obj_mtime; /* time of last data modification */ 245 struct webdav_timespec64 obj_ctime; /* time of last file status change */ 246 struct webdav_timespec64 obj_createtime; /* file creation time */ 247 off_t obj_filesize; /* filesize of object */ 248}; 249 250/* WEBDAV_CREATE */ 251struct webdav_request_create 252{ 253 struct webdav_cred pcr; /* user and groups */ 254 opaque_id dir_id; /* The opaque_id for the directory in which the file is to be created */ 255 mode_t mode; /* file type and initial file access permissions for the file */ 256 uint32_t name_length; /* length of name */ 257 char name[]; /* The name that is to be associated with the created file */ 258}; 259 260struct webdav_reply_create 261{ 262 opaque_id obj_id; /* opaque_id of file corresponding to name */ 263 webdav_ino_t obj_fileid; /* file's file ID number */ 264}; 265 266/* WEBDAV_MKDIR */ 267struct webdav_request_mkdir 268{ 269 struct webdav_cred pcr; /* user and groups */ 270 opaque_id dir_id; /* The opaque_id for the directory in which the file is to be created */ 271 mode_t mode; /* file type and initial file access permissions for the file */ 272 uint32_t name_length; /* length of name */ 273 char name[]; /* The name that is to be associated with the created directory */ 274}; 275 276struct webdav_reply_mkdir 277{ 278 opaque_id obj_id; /* opaque_id of directory corresponding to name */ 279 webdav_ino_t obj_fileid; /* directory's file ID number */ 280}; 281 282/* WEBDAV_OPEN */ 283struct webdav_request_open 284{ 285 struct webdav_cred pcr; /* user and groups */ 286 opaque_id obj_id; /* opaque_id of object */ 287 int flags; /* file access flags (O_RDONLY, O_WRONLY, etc.) */ 288 int ref; /* the reference to the webdav object that the cache object should be associated with */ 289}; 290 291struct webdav_reply_open 292{ 293 pid_t pid; /* process ID of file system daemon (for matching to ref's pid) */ 294}; 295 296/* WEBDAV_CLOSE */ 297struct webdav_request_close 298{ 299 struct webdav_cred pcr; /* user and groups */ 300 opaque_id obj_id; /* opaque_id of object */ 301}; 302 303struct webdav_reply_close 304{ 305}; 306 307struct webdav_stat { 308 dev_t st_dev; /* [XSI] ID of device containing file */ 309 webdav_ino_t st_ino; /* [XSI] File serial number */ 310 mode_t st_mode; /* [XSI] Mode of file (see below) */ 311 nlink_t st_nlink; /* [XSI] Number of hard links */ 312 uid_t st_uid; /* [XSI] User ID of the file */ 313 gid_t st_gid; /* [XSI] Group ID of the file */ 314 dev_t st_rdev; /* [XSI] Device ID */ 315 struct webdav_timespec64 st_atimespec; /* time of last access */ 316 struct webdav_timespec64 st_mtimespec; /* time of last data modification */ 317 struct webdav_timespec64 st_ctimespec; /* time of last status change */ 318 struct webdav_timespec64 st_createtimespec; /* time file was created */ 319 off_t st_size; /* [XSI] file size, in bytes */ 320 blkcnt_t st_blocks; /* [XSI] blocks allocated for file */ 321 blksize_t st_blksize; /* [XSI] optimal blocksize for I/O */ 322 uint32_t st_flags; /* user defined flags for file */ 323 uint32_t st_gen; /* file generation number */ 324}; 325 326/* WEBDAV_GETATTR */ 327struct webdav_request_getattr 328{ 329 struct webdav_cred pcr; /* user and groups */ 330 opaque_id obj_id; /* opaque_id of object */ 331}; 332 333struct webdav_reply_getattr 334{ 335 struct webdav_stat obj_attr; /* attributes for the object */ 336}; 337 338/* WEBDAV_SETATTR XXX not needed at this time */ 339struct webdav_request_setattr 340{ 341 struct webdav_cred pcr; /* user and groups */ 342 opaque_id obj_id; /* opaque_id of object */ 343 struct stat new_obj_attr; /* new attributes of the object */ 344}; 345 346struct webdav_reply_setattr 347{ 348}; 349 350/* WEBDAV_READ */ 351struct webdav_request_read 352{ 353 struct webdav_cred pcr; /* user and groups */ 354 opaque_id obj_id; /* opaque_id of file object */ 355 off_t offset; /* position within the file object at which the read is to begin */ 356 uint64_t count; /* number of bytes of data to be read (limited to WEBDAV_MAX_IO_BUFFER_SIZE (8000-bytes)) */ 357}; 358 359struct webdav_reply_read 360{ 361}; 362 363/* WEBDAV_WRITE XXX not needed at this time */ 364struct webdav_request_write 365{ 366 struct webdav_cred pcr; /* user and groups */ 367 opaque_id obj_id; /* opaque_id of file object */ 368 off_t offset; /* position within the file object at which the write is to begin */ 369 uint64_t count; /* number of bytes of data to be written (limited to WEBDAV_MAX_IO_BUFFER_SIZE (8000-bytes)) */ 370 char data[]; /* data to be written to the file object */ 371}; 372 373struct webdav_reply_write 374{ 375 uint64_t count; /* number of bytes of data written to the file */ 376}; 377 378/* WEBDAV_FSYNC */ 379struct webdav_request_fsync 380{ 381 struct webdav_cred pcr; /* user and groups */ 382 opaque_id obj_id; /* opaque_id of object */ 383}; 384 385struct webdav_reply_fsync 386{ 387}; 388 389/* WEBDAV_REMOVE */ 390struct webdav_request_remove 391{ 392 struct webdav_cred pcr; /* user and groups */ 393 opaque_id obj_id; /* opaque_id of entry to remove */ 394}; 395 396struct webdav_reply_remove 397{ 398}; 399 400/* WEBDAV_RMDIR */ 401struct webdav_request_rmdir 402{ 403 struct webdav_cred pcr; /* user and groups */ 404 opaque_id obj_id; /* opaque_id of directory object to remove */ 405}; 406 407struct webdav_reply_rmdir 408{ 409}; 410 411/* WEBDAV_RENAME */ 412struct webdav_request_rename 413{ 414 struct webdav_cred pcr; /* user and groups */ 415 opaque_id from_dir_id; /* opaque_id for the directory from which the entry is to be renamed */ 416 opaque_id from_obj_id; /* opaque_id for the object to be renamed */ 417 opaque_id to_dir_id; /* opaque_id for the directory to which the object is to be renamed */ 418 opaque_id to_obj_id; /* opaque_id for the object's new location if it exists (may be NULL) */ 419 uint32_t to_name_length; /* length of to_name */ 420 char to_name[]; /* new name for the object */ 421}; 422 423struct webdav_reply_rename 424{ 425}; 426 427/* WEBDAV_READDIR */ 428struct webdav_request_readdir 429{ 430 struct webdav_cred pcr; /* user and groups */ 431 opaque_id obj_id; /* opaque_id of directory to read */ 432 int cache; /* if TRUE, perform additional caching */ 433}; 434 435struct webdav_reply_readdir 436{ 437}; 438 439/* WEBDAV_STATFS */ 440 441struct webdav_statfs { 442 uint64_t f_bsize; /* fundamental file system block size */ 443 uint64_t f_iosize; /* optimal transfer block size */ 444 uint64_t f_blocks; /* total data blocks in file system */ 445 uint64_t f_bfree; /* free blocks in fs */ 446 uint64_t f_bavail; /* free blocks avail to non-superuser */ 447 uint64_t f_files; /* total file nodes in file system */ 448 uint64_t f_ffree; /* free file nodes in fs */ 449}; 450 451struct webdav_request_statfs 452{ 453 struct webdav_cred pcr; /* user and groups */ 454 opaque_id root_obj_id; /* opaque_id of the root directory */ 455}; 456 457struct webdav_reply_statfs 458{ 459 struct webdav_statfs fs_attr; /* file system information */ 460 /* 461 * (required: f_bsize, f_iosize, f_blocks, f_bfree, 462 * f_bavail, f_files, f_ffree. The kext will either copy 463 * the remaining info from the mount struct, or the cached 464 * statfs struct in the mount struct IS the destination. 465 */ 466}; 467 468/* WEBDAV_UNMOUNT */ 469struct webdav_request_unmount 470{ 471 struct webdav_cred pcr; /* user and groups */ 472}; 473 474struct webdav_reply_unmount 475{ 476}; 477 478/* WEBDAV_INVALCACHES */ 479struct webdav_request_invalcaches 480{ 481 struct webdav_cred pcr; /* user and groups */ 482}; 483 484struct webdav_reply_invalcaches 485{ 486}; 487 488/* WEBDAV_SHOW_COOKIES */ 489/* WEBDAV_RESET_COOKIES */ 490struct webdav_request_cookies { 491 struct webdav_cred pcr; /* user and groups */ 492}; 493 494struct webdav_reply_cookies { 495 496}; 497 498struct webdav_request_writeseq 499{ 500 struct webdav_cred pcr; /* user and groups */ 501 opaque_id obj_id; /* opaque_id of file object */ 502 off_t offset; /* position within the file object at which the write is to begin */ 503 off_t count; /* number of bytes of data to be written (limited to WEBDAV_MAX_IO_BUFFER_SIZE (8000-bytes)) */ 504 uint64_t file_len; /* length of the file after all sequential writes are done */ 505 uint32_t is_retry; /* non-zero indicates this request is a retry due to an EPIPE */ 506}; 507 508struct webdav_reply_writeseq 509{ 510 uint64_t count; /* number of bytes of data written to the file */ 511}; 512 513union webdav_request 514{ 515 struct webdav_request_lookup lookup; 516 struct webdav_request_create create; 517 struct webdav_request_open open; 518 struct webdav_request_close close; 519 struct webdav_request_getattr getattr; 520 struct webdav_request_setattr setattr; 521 struct webdav_request_read read; 522 struct webdav_request_write write; 523 struct webdav_request_fsync fsync; 524 struct webdav_request_remove remove; 525 struct webdav_request_rmdir rmdir; 526 struct webdav_request_rename rename; 527 struct webdav_request_readdir readdir; 528 struct webdav_request_statfs statfs; 529 struct webdav_request_invalcaches invalcaches; 530 struct webdav_request_writeseq writeseq; 531}; 532 533union webdav_reply 534{ 535 struct webdav_reply_lookup lookup; 536 struct webdav_reply_create create; 537 struct webdav_reply_open open; 538 struct webdav_reply_close close; 539 struct webdav_reply_getattr getattr; 540 struct webdav_reply_setattr setattr; 541 struct webdav_reply_read read; 542 struct webdav_reply_write write; 543 struct webdav_reply_fsync fsync; 544 struct webdav_reply_remove remove; 545 struct webdav_reply_rmdir rmdir; 546 struct webdav_reply_rename rename; 547 struct webdav_reply_readdir readdir; 548 struct webdav_reply_statfs statfs; 549 struct webdav_reply_invalcaches invalcaches; 550 struct webdav_reply_writeseq writeseq; 551}; 552 553#define UNKNOWNUID ((uid_t)99) 554 555/* 556 * The WEBDAV_CONNECTION_DOWN_MASK bit is set by the code in send_reply() in 557 * activate.c in the int result when the mount_webdav daemon determines it cannot 558 * communicate with the remote WebDAV server. webdav_sendmsg() and webdav_open() in 559 * webdav_vnops.c check that bit to determine if the connection is up or down. 560 */ 561#define WEBDAV_CONNECTION_DOWN_MASK 0x80000000 562 563/* 564 * fsctl(2) values for WebDAV FS 565 */ 566 567/* 568 * WEBDAVIOC_INVALIDATECACHES commmand passed to fsctl(2) causes WebDAV FS to 569 * revalidate cached files with the WebDAV server and to invalidate all 570 * all cached stat data. 571 * example: 572 * result = fsctl(path, WEBDAVIOC_INVALIDATECACHES, NULL, 0); 573 */ 574#define WEBDAVIOC_INVALIDATECACHES _IO('w', 1) 575#define WEBDAV_INVALIDATECACHES IOCBASECMD(WEBDAVIOC_INVALIDATECACHES) 576 577/* 578 * The WEBDAVIOC_WRITE_SEQUENTIAL command passed to fsctl(2) causes WebDAV FS to 579 * enable Write Sequential mode on a vnode that is opened for writing. 580 * The only parameter is a struct WebdavWriteSequential, that has a single field 581 * to indicate the total length in bytes that will be written. 582 * 583 * Example: 584 * 585 * struct WebdavWriteSequential { 586 * uint64_t file_len; 587 * }; 588 * 589 * struct WebdavWriteSequential req; 590 * req->file_len = 8192; // Will write 8k 591 * result = fsctl(path, WEBDAVIOC_WRITE_SEQUENTIAL, &req, 0); 592 * 593 * Return values: 594 * 0 - Success 595 * EBUSY - File is already in Write Sequential mode. 596 */ 597struct WebdavWriteSequential { 598 uint64_t file_len; 599}; 600 601#pragma options align=reset 602 603#define WEBDAVIOC_WRITE_SEQUENTIAL _IOW('z', 19, struct WebdavWriteSequential) 604#define WEBDAV_WRITE_SEQUENTIAL IOCBASECMD(WEBDAVIOC_WRITE_SEQUENTIAL) 605 606#define WEBDAVIOC_SHOW_COOKIES _IOW('x', 29, int) 607#define WEBDAV_SHOW_COOKIES IOCBASECMD(WEBDAVIOC_SHOW_COOKIES) 608 609#define WEBDAVIOC_RESET_COOKIES _IOW('x', 28, int) 610#define WEBDAV_RESET_COOKIES IOCBASECMD(WEBDAVIOC_RESET_COOKIES) 611 612/* 613 * Sysctl values for WebDAV FS 614 */ 615 616/* 617 * If name[0] is WEBDAV_ASSOCIATECACHEFILE_SYSCTL, then 618 * name[1] = a pointer to a struct open_associatecachefile 619 * name[2] = fd of cache file 620 */ 621#define WEBDAV_ASSOCIATECACHEFILE_SYSCTL 1 622/* 623 * If name[0] is WEBDAV_NOTIFY_RECONNECTED_SYSCTL, then 624 * name[1] = fsid.value[0] // fsid byte 0 of reconnected file system 625 * name[2] = fsid.value[1] // fsid byte 1 of reconnected file system 626 */ 627#define WEBDAV_NOTIFY_RECONNECTED_SYSCTL 2 628 629#define WEBDAV_MAX_KEXT_CONNECTIONS 128 /* maximum number of open connections to user-land server */ 630 631#ifdef KERNEL 632 633struct webdavmount 634{ 635 vnode_t pm_root; /* Root node */ 636 u_int32_t pm_status; /* status bits for this mounted structure */ 637 struct mount *pm_mountp; /* vfs structure for this filesystem */ 638 char *pm_vol_name; /* volume name */ 639 struct sockaddr *pm_socket_name; /* Socket to server name */ 640 u_int32_t pm_open_connections; /* number of connections opened to user-land server */ 641 u_int32_t pm_server_ident; /* identifies some (not all) types of servers we are connected to */ 642 off_t pm_dir_size; /* size of directories */ 643 /* pathconf values: >=0 to return value; -1 if not supported */ 644 int pm_link_max; /* maximum value of a file's link count (1 for file systems that do not support link counts) */ 645 int pm_name_max; /* The maximum number of bytes in a file name (does not include null at end) */ 646 int pm_path_max; /* The maximum number of bytes in a relative pathname (does not include null at end) */ 647 int pm_pipe_buf; /* The maximum number of bytes that can be written atomically to a pipe (usually PIPE_BUF if supported) */ 648 int pm_chown_restricted; /* Return _POSIX_CHOWN_RESTRICTED if appropriate privileges are required for the chown(2); otherwise 0 */ 649 int pm_no_trunc; /* Return _POSIX_NO_TRUNC if file names longer than KERN_NAME_MAX are truncated; otherwise 0 */ 650 size_t pm_iosize; /* saved iosize to use */ 651 uid_t pm_uid; /* effective uid of the mounting user */ 652 gid_t pm_gid; /* effective gid of the mounting user */ 653 lck_mtx_t pm_mutex; /* Protects pm_status adn pm_open_connections fields */ 654 lck_mtx_t pm_renamelock; /* Mount rename lock */ 655}; 656 657struct webdavnode 658{ 659 lck_rw_t pt_rwlock; /* this webdavnode's lock */ 660 LIST_ENTRY(webdavnode) pt_hash; /* Hash chain. */ 661 struct mount *pt_mountp; /* vfs structure for this filesystem */ 662 vnode_t pt_parent; /* Pointer to parent vnode */ 663 vnode_t pt_vnode; /* Pointer to vnode */ 664 vnode_t pt_cache_vnode; /* Pointer to cached file vnode */ 665 opaque_id pt_obj_id; /* opaque_id from lookup */ 666 webdav_ino_t pt_fileid; /* file id */ 667 668 /* timestamp cache */ 669 struct webdav_timespec64 pt_atime; /* time of last access */ 670 struct webdav_timespec64 pt_mtime; /* time of last data modification */ 671 struct webdav_timespec64 pt_ctime; /* time of last file status change */ 672 struct webdav_timespec64 pt_createtime; /* file creation time */ 673 struct webdav_timespec64 pt_mtime_old; /* previous pt_mtime value (directory nodes only, used for negative name cache) */ 674 struct webdav_timespec64 pt_timestamp_refresh; /* time of last timestamp refresh */ 675 676 off_t pt_filesize; /* what we think the filesize is */ 677 u_int32_t pt_status; /* WEBDAV_DIRTY, etc */ 678 u_int32_t pt_opencount; /* reference count of opens */ 679 680 /* for Write Sequential mode */ 681 u_int32_t pt_opencount_write; /* count of opens for writing */ 682 u_int32_t pt_writeseq_enabled; /* TRUE if node Write Sequential mode is enabled */ 683 off_t pt_writeseq_offset; /* offset we're expecting for the next write */ 684 uint64_t pt_writeseq_len; /* total length in bytes that will be written in Write Sequential mode */ 685 686 /* SMP debug variables */ 687 void *pt_lastvop; /* tracks last operation that locked this webdavnode */ 688 void *pt_activation; /* tracks last thread that locked this webdavnode */ 689 u_int32_t pt_lockState; /* current lock state */ 690}; 691 692struct open_associatecachefile 693{ 694 vnode_t cachevp; 695 pid_t pid; 696}; 697 698/* Defines for webdavnode pt_status field */ 699 700#define WEBDAV_DIRTY 0x00000001 /* Indicates webdavnode has data which has not been flushed to cache file */ 701#define WEBDAV_ACCESSED 0x00000002 /* Indicates file has been accessed - used by webdav_gettr to determine dates */ 702#define WEBDAV_ONHASHLIST 0x00000004 /* Indicates webdavnode is on the hash chain */ 703#define WEBDAV_DELETED 0x00000008 /* Indicates that webdav file (which is still referenced) has been deleted */ 704#define WEBDAV_DIR_NOT_LOADED 0x00000010 /* Indicates that an open directory is empty and needs to be populated from the server */ 705#define WEBDAV_INIT 0x00000020 /* Indicates that the webdavnode is in the process of being initialized */ 706#define WEBDAV_WAITINIT 0x00000040 /* Indicates that someone is sleeping (on webdavnode) waiting for initialization to finish */ 707#define WEBDAV_ISMAPPED 0x00000080 /* Indicates that the file is mapped */ 708#define WEBDAV_WASMAPPED 0x00000100 /* Indicates that the file is or was mapped */ 709#define WEBDAV_NEGNCENTRIES 0x00000200 /* Indicates one or more negative name cache entries exist (directory nodes only) */ 710 711/* Defines for webdavmount pm_status field */ 712 713#define WEBDAV_MOUNT_SUPPORTS_STATFS 0x00000001 /* Indicates that the server supports quata and quota used properties */ 714#define WEBDAV_MOUNT_STATFS 0x00000002 /* statfs is in progress */ 715#define WEBDAV_MOUNT_STATFS_WANTED 0x00000004 /* statfs wakeup is wanted */ 716#define WEBDAV_MOUNT_TIMEO 0x00000008 /* connection to webdav server was lost */ 717#define WEBDAV_MOUNT_DEAD 0x00000010 /* file system is dead. */ 718#define WEBDAV_MOUNT_SUPPRESS_ALL_UI 0x00000020 /* suppress UI when connection is lost */ 719#define WEBDAV_MOUNT_CONNECTION_WANTED 0x000000040 /* wakeup is wanted to start another connection with user-land server */ 720#define WEBDAV_MOUNT_SECURECONNECTION 0x000000080 /* the connection to the server is secure */ 721 722/* Webdav sizes for statfs */ 723 724#define WEBDAV_NUM_BLOCKS -1 /* not supported */ 725#define WEBDAV_FREE_BLOCKS -1 /* not supported */ 726#define WEBDAV_NUM_FILES 65535 /* Like HFS */ 727#define WEBDAV_FREE_FILES (WEBDAV_NUM_FILES - 2) /* Used a couple */ 728 729/* Webdav status macros */ 730 731#define VFSTOWEBDAV(mp) ((struct webdavmount *)(vfs_fsprivate(mp))) 732#define VTOWEBDAV(vp) ((struct webdavnode *)(vnode_fsnode(vp))) 733#define WEBDAVTOV(pt) ((pt)->pt_vnode) 734#define WEBDAVTOMP(pt) (vnode_mount(WEBDAVTOV(pt))) 735 736/* Other defines */ 737 738 739 740/* 741 * In webdav_read and webdav_pagein, webdav_read_bytes is called if the part of 742 * file we need hasn't been downloaded from the server yet. However, since we're 743 * already downloading the file, there's already data in the stream so reading 744 * a range is counterproductive if we'll have downloaded the part we need (in the 745 * stream) by the time webdav_read_bytes returns the data out of band. 746 * Apache's mod_dav buffers 32K in the stream, so that's we'll use. 747 */ 748#define WEBDAV_WAIT_IF_WITHIN 32768 749 750/* 751 * There are several loops where the code waits for a cache file to be downloaded, 752 * or for a specific part of the cache file to be downloaded. This constant controls 753 * how often the cache vnode is polled (with VNOP_GETATTR). The less often we poll, 754 * the higher the latency between getting data and using it. 755 * 756 * A network connection with 35mbps (maximum cable) can give us a page every millisecond. 757 * A network connection with 3mbps (typical capped cable or high speed DSL) can give us a page every 10 milliseconds. 758 * For typical home networks over cable or DSL, 10 ms should be OK. Thus... (10 * 1000 * 1000) nanoseconds. 759 */ 760#define WEBDAV_WAIT_FOR_PAGE_TIME (10 * 1000 * 1000) 761 762/* the number of seconds soreceive() should block 763 * before rechecking the server process state 764 */ 765#define WEBDAV_SO_RCVTIMEO_SECONDS 10 766 767/* How many times webdav_sendmsg() will block in soreceive() 768 * before timing out the request. The total 769 * amount of seconds is WEBDAV_SO_RCVTIMEO_SECONDS * WEBDAV_MAX_SOCK_RCV_TIMEOUTS 770 */ 771#define WEBDAV_MAX_SOCK_RCV_TIMEOUTS 9 772 773/* 774 * Used only for negative name caching, TIMESTAMP_NEGNCACHE_TIMEOUT is used by the webdav_vnop_lookup routine 775 * to determine how often to fetch attributes from the server to check if a directory has been modified (va_mod_time timestamp). 776 * We purge all negative name cache entries when the modification time of a directory has changed. 777 * 778 */ 779#define TIMESTAMP_CACHE_TIMEOUT 10 780 781#if 0 782 #define START_MARKER(str) \ 783 { \ 784 log_vnop_start(str); \ 785 } 786 #define RET_ERR(str, error) \ 787 { \ 788 /*if (error)*/ \ 789 log_vnop_error(str, error); \ 790 return(error); \ 791 } 792extern void log_vnop_start(char *str); 793extern void log_vnop_error(char *str, int error); 794#else 795 #define START_MARKER(str) 796 #define RET_ERR(str, error) return(error) 797#endif 798 799 800extern int( **webdav_vnodeop_p)(); 801extern void webdav_hashinit(void); 802extern void webdav_hashdestroy(void); 803extern void webdav_hashrem(struct webdavnode *); 804extern void webdav_hashins(struct webdavnode *); 805extern struct webdavnode *webdav_hashget(struct mount *mp, webdav_ino_t fileid, struct webdavnode *pt_new, uint32_t *inserted); 806 807extern void webdav_copy_creds(vfs_context_t context, struct webdav_cred *dest); 808extern int webdav_sendmsg(int vnop, struct webdavmount *fmp, 809 void *request, size_t requestsize, 810 void *vardata, size_t vardatasize, 811 int *result, void *reply, size_t replysize); 812extern int webdav_get( 813 struct mount *mp, /* mount point */ 814 vnode_t dvp, /* parent vnode */ 815 int markroot, /* if 1, mark as root vnode */ 816 struct componentname *cnp, /* componentname */ 817 opaque_id obj_id, /* object's opaque_id */ 818 webdav_ino_t obj_fileid, /* object's file ID number */ 819 enum vtype obj_vtype, /* VREG or VDIR */ 820 struct webdav_timespec64 obj_atime, /* time of last access */ 821 struct webdav_timespec64 obj_mtime, /* time of last data modification */ 822 struct webdav_timespec64 obj_ctime, /* time of last file status change */ 823 struct webdav_timespec64 obj_createtime, /* file creation time */ 824 off_t obj_filesize, /* object's filesize */ 825 vnode_t *vpp); /* vnode returned here */ 826 827extern int webdav_assign_ref(struct open_associatecachefile *associatecachefile, int *ref); 828extern void webdav_release_ref(int ref); 829extern char webdav_name[MFSNAMELEN]; 830 831#endif /* KERNEL */ 832 833#endif /*ifndef _WEBDAV_H_INCLUDE */ 834 835