1 /* $FreeBSD$ */ 2 /* $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $ */ 3 4 /*- 5 * SPDX-License-Identifier: BSD-4-Clause 6 * 7 * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. 8 * Copyright (C) 1994, 1995, 1997 TooLs GmbH. 9 * All rights reserved. 10 * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below). 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by TooLs GmbH. 23 * 4. The name of TooLs GmbH may not be used to endorse or promote products 24 * derived from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 32 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 */ 37 /*- 38 * Written by Paul Popelka (paulp@uts.amdahl.com) 39 * 40 * You can do anything you want with this software, just don't say you wrote 41 * it, and don't remove this notice. 42 * 43 * This software is provided "as is". 44 * 45 * The author supplies this software to be publicly redistributed on the 46 * understanding that the author is not responsible for the correct 47 * functioning of this software in any circumstances and is not liable for 48 * any damages caused by this software. 49 * 50 * October 1992 51 */ 52 53 #include <sys/param.h> 54 #include <sys/systm.h> 55 #include <sys/uio.h> 56 #include <sys/resourcevar.h> /* defines plimit structure in proc struct */ 57 #include <sys/kernel.h> 58 #include <sys/stat.h> 59 #include <sys/buf.h> 60 #include <sys/proc.h> 61 #include <sys/priv.h> 62 #include <sys/namei.h> 63 #include <sys/mount.h> 64 #include <sys/unistd.h> 65 #include <sys/vnode.h> 66 #include <sys/malloc.h> 67 #include <sys/dirent.h> 68 #include <sys/signalvar.h> 69 #include <sys/time.h> 70 71 #include <vm/vm.h> 72 #include <vm/vm_extern.h> 73 #include <vm/vm_zone.h> 74 #include <vm/vnode_pager.h> 75 #include <vm/vm_page2.h> 76 77 #include <sys/buf2.h> 78 79 #include <machine/inttypes.h> 80 81 #include <vfs/msdosfs/bpb.h> 82 #include <vfs/msdosfs/direntry.h> 83 #include <vfs/msdosfs/denode.h> 84 #include <vfs/msdosfs/fat.h> 85 #include <vfs/msdosfs/msdosfsmount.h> 86 87 /* 88 * Some general notes: 89 * 90 * In the ufs filesystem the inodes, superblocks, and indirect blocks are 91 * read/written using the vnode for the filesystem. Blocks that represent 92 * the contents of a file are read/written using the vnode for the file 93 * (including directories when they are read/written as files). This 94 * presents problems for the dos filesystem because data that should be in 95 * an inode (if dos had them) resides in the directory itself. Since we 96 * must update directory entries without the benefit of having the vnode 97 * for the directory we must use the vnode for the filesystem. This means 98 * that when a directory is actually read/written (via read, write, or 99 * readdir, or seek) we must use the vnode for the filesystem instead of 100 * the vnode for the directory as would happen in ufs. This is to insure we 101 * retrieve the correct block from the buffer cache since the hash value is 102 * based upon the vnode address and the desired block number. 103 */ 104 105 /* 106 * Create a regular file. On entry the directory to contain the file being 107 * created is locked. We must release before we return. We must also free 108 * the pathname buffer pointed at by cnp->cn_pnbuf, always on error, or 109 * only if the SAVESTART bit in cn_flags is clear on success. 110 */ 111 static int 112 msdosfs_create(struct vop_old_create_args *ap) 113 { 114 struct componentname *cnp = ap->a_cnp; 115 struct denode ndirent; 116 struct denode *dep; 117 struct denode *pdep = VTODE(ap->a_dvp); 118 struct timespec ts; 119 int error; 120 121 mprintf("msdosfs_create(cnp %p, vap %p\n", cnp, ap->a_vap); 122 123 /* 124 * If this is the root directory and there is no space left we 125 * can't do anything. This is because the root directory can not 126 * change size. 127 */ 128 if (pdep->de_StartCluster == MSDOSFSROOT 129 && pdep->de_fndoffset >= pdep->de_FileSize) { 130 error = ENOSPC; 131 goto bad; 132 } 133 134 /* 135 * Create a directory entry for the file, then call createde() to 136 * have it installed. NOTE: DOS files are always executable. We 137 * use the absence of the owner write bit to make the file 138 * readonly. 139 */ 140 memset(&ndirent, 0, sizeof(ndirent)); 141 error = uniqdosname(pdep, cnp, ndirent.de_Name); 142 if (error) 143 goto bad; 144 145 ndirent.de_Attributes = (ap->a_vap->va_mode & VWRITE) ? 146 ATTR_ARCHIVE : ATTR_ARCHIVE | ATTR_READONLY; 147 ndirent.de_LowerCase = 0; 148 ndirent.de_StartCluster = 0; 149 ndirent.de_FileSize = 0; 150 ndirent.de_dev = pdep->de_dev; 151 ndirent.de_devvp = pdep->de_devvp; 152 ndirent.de_pmp = pdep->de_pmp; 153 ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE; 154 vfs_timestamp(&ts); 155 DETIMES(&ndirent, &ts, &ts, &ts); 156 error = createde(&ndirent, pdep, &dep, cnp); 157 if (error) 158 goto bad; 159 *ap->a_vpp = DETOV(dep); 160 return (0); 161 162 bad: 163 return (error); 164 } 165 166 static int 167 msdosfs_mknod(struct vop_old_mknod_args *ap) 168 { 169 return (EINVAL); 170 } 171 172 static int 173 msdosfs_open(struct vop_open_args *ap) 174 { 175 return(vop_stdopen(ap)); 176 } 177 178 static int 179 msdosfs_close(struct vop_close_args *ap) 180 { 181 struct vnode *vp = ap->a_vp; 182 struct denode *dep = VTODE(vp); 183 struct timespec ts; 184 185 if (VREFCNT(vp) > 1) { 186 vfs_timestamp(&ts); 187 DETIMES(dep, &ts, &ts, &ts); 188 } 189 return (vop_stdclose(ap)); 190 } 191 192 static int 193 msdosfs_access(struct vop_access_args *ap) 194 { 195 struct denode *dep = VTODE(ap->a_vp); 196 struct msdosfsmount *pmp = dep->de_pmp; 197 mode_t file_mode; 198 199 file_mode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) | 200 ((dep->de_Attributes & ATTR_READONLY) ? 201 0 : (S_IWUSR|S_IWGRP|S_IWOTH)); 202 file_mode &= (ap->a_vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask); 203 204 return (vop_helper_access(ap, pmp->pm_uid, pmp->pm_gid, file_mode, 0)); 205 } 206 207 static int 208 msdosfs_getattr(struct vop_getattr_args *ap) 209 { 210 struct denode *dep = VTODE(ap->a_vp); 211 struct msdosfsmount *pmp = dep->de_pmp; 212 struct vattr *vap = ap->a_vap; 213 mode_t mode; 214 struct timespec ts; 215 u_long dirsperblk = pmp->pm_BytesPerSec / sizeof(struct direntry); 216 uint64_t fileid; 217 218 vfs_timestamp(&ts); 219 DETIMES(dep, &ts, &ts, &ts); 220 vap->va_fsid = dev2udev(dep->de_dev); 221 /* 222 * The following computation of the fileid must be the same as that 223 * used in msdosfs_readdir() to compute d_fileno. If not, pwd 224 * doesn't work. 225 */ 226 if (dep->de_Attributes & ATTR_DIRECTORY) { 227 fileid = (uint64_t)cntobn(pmp, dep->de_StartCluster) * 228 dirsperblk; 229 if (dep->de_StartCluster == MSDOSFSROOT) 230 fileid = 1; 231 } else { 232 fileid = (uint64_t)cntobn(pmp, dep->de_dirclust) * 233 dirsperblk; 234 if (dep->de_dirclust == MSDOSFSROOT) 235 fileid = (uint64_t)roottobn(pmp, 0) * dirsperblk; 236 fileid += (uoff_t)dep->de_diroffset / sizeof(struct direntry); 237 } 238 vap->va_fileid = fileid; 239 if ((dep->de_Attributes & ATTR_READONLY) == 0) 240 mode = S_IRWXU|S_IRWXG|S_IRWXO; 241 else 242 mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; 243 vap->va_mode = mode & 244 (ap->a_vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask); 245 vap->va_uid = pmp->pm_uid; 246 vap->va_gid = pmp->pm_gid; 247 vap->va_nlink = 1; 248 vap->va_rmajor = VNOVAL; 249 vap->va_rminor = VNOVAL; 250 vap->va_size = dep->de_FileSize; 251 fattime2timespec(dep->de_MDate, dep->de_MTime, 0, 0, &vap->va_mtime); 252 if (pmp->pm_flags & MSDOSFSMNT_LONGNAME) { 253 fattime2timespec(dep->de_ADate, 0, 0, 0, &vap->va_atime); 254 fattime2timespec(dep->de_CDate, dep->de_CTime, dep->de_CHun, 255 0, &vap->va_ctime); 256 } else { 257 vap->va_atime = vap->va_mtime; 258 vap->va_ctime = vap->va_mtime; 259 } 260 vap->va_flags = 0; 261 if ((dep->de_Attributes & ATTR_ARCHIVE) == 0) 262 vap->va_flags |= SF_ARCHIVED; 263 vap->va_gen = 0; 264 vap->va_blocksize = pmp->pm_bpcluster; 265 vap->va_bytes = 266 (dep->de_FileSize + pmp->pm_crbomask) & ~pmp->pm_crbomask; 267 vap->va_type = ap->a_vp->v_type; 268 vap->va_filerev = dep->de_modrev; 269 return (0); 270 } 271 272 static int 273 msdosfs_setattr(struct vop_setattr_args *ap) 274 { 275 struct vnode *vp = ap->a_vp; 276 struct denode *dep = VTODE(vp); 277 struct msdosfsmount *pmp = dep->de_pmp; 278 struct vattr *vap = ap->a_vap; 279 struct ucred *cred = ap->a_cred; 280 int error = 0; 281 282 mprintf("msdosfs_setattr(): vp %p, vap %p, cred %p\n", vp, vap, cred); 283 284 /* 285 * Check for unsettable attributes. 286 */ 287 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || 288 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || 289 (vap->va_blocksize != VNOVAL) || (vap->va_rmajor != VNOVAL) || 290 (vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { 291 mprintf("msdosfs_setattr(): returning EINVAL\n"); 292 mprintf(" va_type %d, va_nlink %llx, va_fsid %llx, va_fileid %llx\n", 293 vap->va_type, (unsigned long long)vap->va_nlink, 294 (unsigned long long)vap->va_fsid, 295 (unsigned long long)vap->va_fileid); 296 mprintf(" va_blocksize %lx, va_rdev %llx, va_bytes %llx, va_gen %lx\n", 297 vap->va_blocksize, (unsigned long long)0, 298 (unsigned long long)vap->va_bytes, vap->va_gen); 299 mprintf(" va_uid %x, va_gid %x\n", 300 vap->va_uid, vap->va_gid); 301 return (EINVAL); 302 } 303 if (vap->va_flags != VNOVAL) { 304 if (vp->v_mount->mnt_flag & MNT_RDONLY) 305 return (EROFS); 306 if (cred->cr_uid != pmp->pm_uid && 307 (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0))) 308 return (error); 309 /* 310 * We are very inconsistent about handling unsupported 311 * attributes. We ignored the access time and the 312 * read and execute bits. We were strict for the other 313 * attributes. 314 * 315 * Here we are strict, stricter than ufs in not allowing 316 * users to attempt to set SF_SETTABLE bits or anyone to 317 * set unsupported bits. However, we ignore attempts to 318 * set ATTR_ARCHIVE for directories `cp -pr' from a more 319 * sensible file system attempts it a lot. 320 */ 321 if (cred->cr_uid != 0) { 322 if (vap->va_flags & SF_SETTABLE) 323 return EPERM; 324 } 325 if (vap->va_flags & ~SF_ARCHIVED) 326 return EOPNOTSUPP; 327 if (vap->va_flags & SF_ARCHIVED) 328 dep->de_Attributes &= ~ATTR_ARCHIVE; 329 else if (!(dep->de_Attributes & ATTR_DIRECTORY)) 330 dep->de_Attributes |= ATTR_ARCHIVE; 331 dep->de_flag |= DE_MODIFIED; 332 } 333 334 if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) { 335 uid_t uid; 336 gid_t gid; 337 338 if (vp->v_mount->mnt_flag & MNT_RDONLY) 339 return (EROFS); 340 uid = vap->va_uid; 341 if (uid == (uid_t)VNOVAL) 342 uid = pmp->pm_uid; 343 gid = vap->va_gid; 344 if (gid == (gid_t)VNOVAL) 345 gid = pmp->pm_gid; 346 if ((cred->cr_uid != pmp->pm_uid || uid != pmp->pm_uid || 347 (gid != pmp->pm_gid && !groupmember(gid, cred))) && 348 (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0))) 349 return error; 350 if (uid != pmp->pm_uid || gid != pmp->pm_gid) 351 return EINVAL; 352 } 353 354 if (vap->va_size != VNOVAL) { 355 switch (vp->v_type) { 356 case VDIR: 357 return (EISDIR); 358 case VREG: 359 /* 360 * Truncation is only supported for regular files, 361 * Disallow it if the filesystem is read-only. 362 */ 363 if (vp->v_mount->mnt_flag & MNT_RDONLY) 364 return (EROFS); 365 break; 366 default: 367 /* 368 * According to POSIX, the result is unspecified 369 * for file types other than regular files, 370 * directories and shared memory objects. We 371 * don't support any file types except regular 372 * files and directories in this file system, so 373 * this (default) case is unreachable and can do 374 * anything. Keep falling through to detrunc() 375 * for now. 376 */ 377 break; 378 } 379 error = detrunc(dep, vap->va_size, 0); 380 if (error) 381 return error; 382 } 383 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { 384 if (vp->v_mount->mnt_flag & MNT_RDONLY) 385 return (EROFS); 386 if (cred->cr_uid != pmp->pm_uid && 387 (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0)) && 388 ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || 389 (error = VOP_EACCESS(vp, VWRITE, cred)))) 390 return (error); 391 if (vp->v_type != VDIR) { 392 if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 && 393 vap->va_atime.tv_sec != VNOVAL) { 394 dep->de_flag &= ~DE_ACCESS; 395 timespec2fattime(&vap->va_atime, 0, 396 &dep->de_ADate, NULL, NULL); 397 } 398 if (vap->va_mtime.tv_sec != VNOVAL) { 399 dep->de_flag &= ~DE_UPDATE; 400 timespec2fattime(&vap->va_mtime, 0, 401 &dep->de_MDate, &dep->de_MTime, NULL); 402 } 403 dep->de_Attributes |= ATTR_ARCHIVE; 404 dep->de_flag |= DE_MODIFIED; 405 } 406 } 407 /* 408 * DOS files only have the ability to have their writability 409 * attribute set, so we use the owner write bit to set the readonly 410 * attribute. 411 */ 412 if (vap->va_mode != (mode_t)VNOVAL) { 413 if (vp->v_mount->mnt_flag & MNT_RDONLY) 414 return (EROFS); 415 if (cred->cr_uid != pmp->pm_uid && 416 (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0))) 417 return (error); 418 if (vp->v_type != VDIR) { 419 /* We ignore the read and execute bits. */ 420 if (vap->va_mode & VWRITE) 421 dep->de_Attributes &= ~ATTR_READONLY; 422 else 423 dep->de_Attributes |= ATTR_READONLY; 424 dep->de_Attributes |= ATTR_ARCHIVE; 425 dep->de_flag |= DE_MODIFIED; 426 } 427 } 428 return (deupdat(dep, 0)); 429 } 430 431 static int 432 msdosfs_read(struct vop_read_args *ap) 433 { 434 int error = 0; 435 int blsize; 436 int isadir; 437 size_t orig_resid; 438 u_int n; 439 u_long diff; 440 u_long on; 441 u_long cn; 442 daddr_t lbn; 443 daddr_t rablock; 444 off_t loffset; 445 int rasize; 446 int seqcount; 447 struct buf *bp; 448 struct vnode *vp = ap->a_vp; 449 struct denode *dep = VTODE(vp); 450 struct msdosfsmount *pmp = dep->de_pmp; 451 struct uio *uio = ap->a_uio; 452 453 if (uio->uio_offset < 0) 454 return (EINVAL); 455 456 if ((uoff_t)uio->uio_offset > MSDOSFS_FILESIZE_MAX) 457 return (0); 458 /* 459 * If they didn't ask for any data, then we are done. 460 */ 461 orig_resid = uio->uio_resid; 462 if (orig_resid == 0) 463 return (0); 464 465 /* 466 * The caller is supposed to ensure that 467 * uio->uio_offset >= 0 and uio->uio_resid >= 0. 468 * We don't need to check for large offsets as in ffs because 469 * dep->de_FileSize <= MSDOSFS_FILESIZE_MAX < OFF_MAX, so large 470 * offsets cannot cause overflow even in theory. 471 */ 472 473 seqcount = ap->a_ioflag >> IO_SEQSHIFT; 474 475 isadir = dep->de_Attributes & ATTR_DIRECTORY; 476 do { 477 if (uio->uio_offset >= dep->de_FileSize) 478 break; 479 480 cn = de_cluster(pmp, uio->uio_offset); 481 loffset = de_cn2doff(pmp, cn); 482 rablock = cn + 1; 483 blsize = pmp->pm_bpcluster; 484 on = uio->uio_offset & pmp->pm_crbomask; 485 486 /* 487 * If we are operating on a directory file then be sure to 488 * do i/o with the vnode for the filesystem instead of the 489 * vnode for the directory. 490 */ 491 bp = NULL; 492 if (isadir) { 493 /* convert cluster # to block # */ 494 error = pcbmap(dep, cn, &lbn, NULL, &blsize); 495 loffset = de_bn2doff(pmp, lbn); 496 if (error == E2BIG) { 497 error = EINVAL; 498 break; 499 } else if (error) 500 break; 501 error = bread(pmp->pm_devvp, loffset, blsize, &bp); 502 } else if (de_cn2off(pmp, rablock) >= dep->de_FileSize) { 503 error = bread(vp, loffset, blsize, &bp); 504 } else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) { 505 error = cluster_readx(vp, dep->de_FileSize, loffset, 506 blsize, B_NOTMETA, on + uio->uio_resid, 507 seqcount * MAXBSIZE, &bp); 508 bp->b_flags |= B_CLUSTEROK; 509 } else if (seqcount > 1) { 510 off_t raoffset = de_cn2doff(pmp, rablock); 511 rasize = blsize; 512 error = breadn(vp, loffset, 513 blsize, &raoffset, &rasize, 1, &bp); 514 } else { 515 error = bread(vp, loffset, blsize, &bp); 516 } 517 if (error) { 518 brelse(bp); 519 break; 520 } 521 diff = pmp->pm_bpcluster - on; 522 n = szmin(uio->uio_resid, diff); 523 diff = dep->de_FileSize - uio->uio_offset; 524 if (diff < n) 525 n = diff; 526 diff = blsize - bp->b_resid; 527 if (diff < n) 528 n = diff; 529 error = uiomovebp(bp, bp->b_data + on, (size_t)n, uio); 530 bqrelse(bp); 531 } while (error == 0 && uio->uio_resid > 0 && n != 0); 532 533 if (!isadir && (error == 0 || uio->uio_resid != orig_resid) && 534 (vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0) 535 dep->de_flag |= DE_ACCESS; 536 return (error); 537 } 538 539 /* 540 * Write data to a file or directory. 541 */ 542 static int 543 msdosfs_write(struct vop_write_args *ap) 544 { 545 int n; 546 int croffset; 547 size_t resid; 548 u_long osize; 549 int error = 0; 550 u_long count; 551 int seqcount; 552 daddr_t cn, lastcn; 553 struct buf *bp = NULL; 554 int ioflag = ap->a_ioflag; 555 struct uio *uio = ap->a_uio; 556 struct thread *td = uio->uio_td; 557 struct vnode *vp = ap->a_vp; 558 struct vnode *thisvp; 559 struct denode *dep = VTODE(vp); 560 struct msdosfsmount *pmp = dep->de_pmp; 561 struct proc *p = (td ? td->td_proc : NULL); 562 struct lwp *lp = (td ? td->td_lwp : NULL); 563 564 mprintf("msdosfs_write(vp %p, uio %p, ioflag %x, cred %p\n", 565 vp, uio, ioflag, ap->a_cred); 566 mprintf("msdosfs_write(): diroff %lu, dirclust %lu, startcluster %lu\n", 567 dep->de_diroffset, dep->de_dirclust, dep->de_StartCluster); 568 569 switch (vp->v_type) { 570 case VREG: 571 if (ioflag & IO_APPEND) 572 uio->uio_offset = dep->de_FileSize; 573 thisvp = vp; 574 break; 575 case VDIR: 576 return EISDIR; 577 default: 578 panic("msdosfs_write(): bad file type"); 579 } 580 581 if (uio->uio_offset < 0) 582 return (EFBIG); 583 584 /* 585 * This is needed (unlike in ffs_write()) because we extend the 586 * file outside of the loop but we don't want to extend the file 587 * for writes of 0 bytes. 588 */ 589 if (uio->uio_resid == 0) 590 return (0); 591 592 /* 593 * The caller is supposed to ensure that 594 * uio->uio_offset >= 0 and uio->uio_resid >= 0. 595 */ 596 if ((uoff_t)uio->uio_offset + uio->uio_resid > MSDOSFS_FILESIZE_MAX) 597 return (EFBIG); 598 599 /* 600 * If they've exceeded their filesize limit, tell them about it. 601 */ 602 if (p && 603 ((uoff_t)uio->uio_offset + uio->uio_resid > 604 p->p_rlimit[RLIMIT_FSIZE].rlim_cur)) { 605 lwpsignal(p, lp, SIGXFSZ); 606 return (EFBIG); 607 } 608 609 /* 610 * If the offset we are starting the write at is beyond the end of 611 * the file, then they've done a seek. Unix filesystems allow 612 * files with holes in them, DOS doesn't so we must fill the hole 613 * with zeroed blocks. 614 */ 615 if (uio->uio_offset > dep->de_FileSize) { 616 error = deextend(dep, uio->uio_offset); 617 if (error) 618 return (error); 619 } 620 621 /* 622 * Remember some values in case the write fails. 623 */ 624 resid = uio->uio_resid; 625 osize = dep->de_FileSize; 626 627 /* 628 * If we write beyond the end of the file, extend it to its ultimate 629 * size ahead of the time to hopefully get a contiguous area. 630 */ 631 if (uio->uio_offset + resid > osize) { 632 count = de_clcount(pmp, uio->uio_offset + resid) - 633 de_clcount(pmp, osize); 634 error = extendfile(dep, count, NULL, NULL, 0); 635 if (error && (error != ENOSPC || (ioflag & IO_UNIT))) 636 goto errexit; 637 lastcn = dep->de_fc[FC_LASTFC].fc_frcn; 638 } else 639 lastcn = de_clcount(pmp, osize) - 1; 640 641 seqcount = ioflag >> IO_SEQSHIFT; 642 do { 643 if (de_cluster(pmp, uio->uio_offset) > lastcn) { 644 error = ENOSPC; 645 break; 646 } 647 648 croffset = uio->uio_offset & pmp->pm_crbomask; 649 n = (int)szmin(uio->uio_resid, pmp->pm_bpcluster - croffset); 650 if (uio->uio_offset + n > dep->de_FileSize) { 651 dep->de_FileSize = uio->uio_offset + n; 652 /* The object size needs to be set before buffer is allocated */ 653 vnode_pager_setsize(vp, dep->de_FileSize); 654 } 655 656 /* 657 * If either the whole cluster gets written, or we write 658 * the cluster from its start beyond EOF, then no need to 659 * read data from disk. 660 * 661 * If UIO_NOCOPY is set we have to do a read-before-write 662 * to fill in any missing pieces of the buffer since no 663 * actual overwrite will occur. 664 */ 665 cn = de_cluster(pmp, uio->uio_offset); 666 if ((uio->uio_offset & pmp->pm_crbomask) == 0 667 && uio->uio_segflg != UIO_NOCOPY 668 && (de_cluster(pmp, uio->uio_offset + uio->uio_resid) 669 > de_cluster(pmp, uio->uio_offset) 670 || uio->uio_offset + uio->uio_resid >= dep->de_FileSize)) { 671 bp = getblk(thisvp, de_cn2doff(pmp, cn), 672 pmp->pm_bpcluster, 0, 0); 673 clrbuf(bp); 674 /* 675 * Do the bmap now, since pcbmap needs buffers 676 * for the FAT table. (see msdosfs_strategy) 677 */ 678 if (bp->b_bio2.bio_offset == NOOFFSET) { 679 daddr_t dblkno; 680 681 error = pcbmap(dep, 682 de_cluster(pmp, bp->b_loffset), 683 &dblkno, NULL, NULL); 684 if (error || dblkno == (daddr_t)-1) { 685 bp->b_bio2.bio_offset = NOOFFSET; 686 } else { 687 bp->b_bio2.bio_offset = de_bn2doff(pmp, 688 dblkno); 689 } 690 } 691 if (bp->b_bio2.bio_offset == NOOFFSET) { 692 brelse(bp); 693 if (!error) 694 error = EIO; /* XXX */ 695 break; 696 } 697 } else { 698 /* 699 * The block we need to write into exists, so read 700 * it in. 701 */ 702 error = bread(thisvp, de_cn2doff(pmp, cn), 703 pmp->pm_bpcluster, &bp); 704 if (error) { 705 brelse(bp); 706 break; 707 } 708 } 709 710 /* 711 * Should these vnode_pager_* functions be done on dir 712 * files? 713 */ 714 715 /* 716 * Copy the data from user space into the buf header. 717 */ 718 error = uiomovebp(bp, bp->b_data + croffset, (size_t)n, uio); 719 if (error) { 720 brelse(bp); 721 break; 722 } 723 724 /* Prepare for clustered writes in some else clauses. */ 725 if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0) 726 bp->b_flags |= B_CLUSTEROK; 727 728 /* 729 * If IO_SYNC, then each buffer is written synchronously. 730 * Otherwise, if we have a severe page deficiency then 731 * write the buffer asynchronously. Otherwise, if on a 732 * cluster boundary then write the buffer asynchronously, 733 * combining it with contiguous clusters if permitted and 734 * possible, since we don't expect more writes into this 735 * buffer soon. Otherwise, do a delayed write because we 736 * expect more writes into this buffer soon. 737 */ 738 if (ioflag & IO_SYNC) 739 bwrite(bp); 740 else if (vm_page_count_severe() || buf_dirty_count_severe()) 741 bawrite(bp); 742 else if (n + croffset == pmp->pm_bpcluster) { 743 if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0) 744 cluster_write(bp, dep->de_FileSize, 745 pmp->pm_bpcluster, seqcount); 746 else 747 bawrite(bp); 748 } else 749 bdwrite(bp); 750 dep->de_flag |= DE_UPDATE; 751 } while (error == 0 && uio->uio_resid > 0); 752 753 /* 754 * If the write failed and they want us to, truncate the file back 755 * to the size it was before the write was attempted. 756 */ 757 errexit: 758 if (error) { 759 if (ioflag & IO_UNIT) { 760 detrunc(dep, osize, ioflag & IO_SYNC); 761 uio->uio_offset -= resid - uio->uio_resid; 762 uio->uio_resid = resid; 763 } else { 764 detrunc(dep, dep->de_FileSize, ioflag & IO_SYNC); 765 if (uio->uio_resid != resid) 766 error = 0; 767 } 768 } else if (ioflag & IO_SYNC) 769 error = deupdat(dep, 1); 770 return (error); 771 } 772 773 /* 774 * Flush the blocks of a file to disk. 775 */ 776 static int 777 msdosfs_fsync(struct vop_fsync_args *ap) 778 { 779 struct vnode *vp = ap->a_vp; 780 struct vnode *devvp; 781 int allerror, error; 782 783 /* 784 * Flush all dirty buffers associated with a vnode. 785 */ 786 #ifdef DIAGNOSTIC 787 loop: 788 #endif 789 vfsync(vp, ap->a_waitfor, 0, NULL, NULL); 790 #ifdef DIAGNOSTIC 791 if (ap->a_waitfor == MNT_WAIT && !RB_EMPTY(&vp->v_rbdirty_tree)) { 792 vprint("msdosfs_fsync: dirty", vp); 793 goto loop; 794 } 795 #endif 796 /* 797 * If the syncing request comes from fsync(2), sync the entire 798 * FAT and any other metadata that happens to be on devvp. We 799 * need this mainly for the FAT. We write the FAT sloppily, and 800 * syncing it all now is the best we can easily do to get all 801 * directory entries associated with the file (not just the file) 802 * fully synced. The other metadata includes critical metadata 803 * for all directory entries, but only in the MNT_ASYNC case. We 804 * will soon sync all metadata in the file's directory entry. 805 * Non-critical metadata for associated directory entries only 806 * gets synced accidentally, as in most file systems. 807 */ 808 if (ap->a_waitfor == MNT_WAIT) { 809 devvp = VTODE(ap->a_vp)->de_pmp->pm_devvp; 810 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 811 allerror = VOP_FSYNC(devvp, MNT_WAIT, 0); 812 vn_unlock(devvp); 813 } else 814 allerror = 0; 815 816 error = deupdat(VTODE(ap->a_vp), ap->a_waitfor == MNT_WAIT); 817 if (allerror == 0) 818 allerror = error; 819 return (allerror); 820 } 821 822 static int 823 msdosfs_remove(struct vop_old_remove_args *ap) 824 { 825 struct denode *dep = VTODE(ap->a_vp); 826 struct denode *ddep = VTODE(ap->a_dvp); 827 int error; 828 829 if (ap->a_vp->v_type == VDIR) 830 error = EPERM; 831 else 832 error = removede(ddep, dep); 833 mprintf("msdosfs_remove(), dep %p, v_refcnt 0x%08x\n", 834 dep, ap->a_vp->v_refcnt); 835 return (error); 836 } 837 838 /* 839 * DOS filesystems don't know what links are. 840 */ 841 static int 842 msdosfs_link(struct vop_old_link_args *ap) 843 { 844 return (EOPNOTSUPP); 845 } 846 847 /* 848 * Renames on files require moving the denode to a new hash queue since the 849 * denode's location is used to compute which hash queue to put the file 850 * in. Unless it is a rename in place. For example "mv a b". 851 * 852 * What follows is the basic algorithm: 853 * 854 * if (file move) { 855 * if (dest file exists) { 856 * remove dest file 857 * } 858 * if (dest and src in same directory) { 859 * rewrite name in existing directory slot 860 * } else { 861 * write new entry in dest directory 862 * update offset and dirclust in denode 863 * move denode to new hash chain 864 * clear old directory entry 865 * } 866 * } else { 867 * directory move 868 * if (dest directory exists) { 869 * if (dest is not empty) { 870 * return ENOTEMPTY 871 * } 872 * remove dest directory 873 * } 874 * if (dest and src in same directory) { 875 * rewrite name in existing entry 876 * } else { 877 * be sure dest is not a child of src directory 878 * write entry in dest directory 879 * update "." and ".." in moved directory 880 * clear old directory entry for moved directory 881 * } 882 * } 883 * 884 * On entry: 885 * source's parent directory is unlocked 886 * source file or directory is unlocked 887 * destination's parent directory is locked 888 * destination file or directory is locked if it exists 889 * 890 * On exit: 891 * all denodes should be released 892 */ 893 static int 894 msdosfs_rename(struct vop_old_rename_args *ap) 895 { 896 struct vnode *tdvp = ap->a_tdvp; 897 struct vnode *fvp = ap->a_fvp; 898 struct vnode *fdvp = ap->a_fdvp; 899 struct vnode *tvp = ap->a_tvp; 900 struct componentname *tcnp = ap->a_tcnp; 901 struct componentname *fcnp = ap->a_fcnp; 902 struct denode *ip, *xp, *dp, *zp; 903 u_char toname[12], oldname[11]; 904 u_long from_diroffset, to_diroffset; 905 u_char to_count; 906 int doingdirectory = 0, newparent = 0; 907 int error; 908 u_long cn, pcl; 909 daddr_t bn; 910 struct msdosfsmount *pmp; 911 struct direntry *dotdotp; 912 struct buf *bp = NULL; 913 914 pmp = VFSTOMSDOSFS(fdvp->v_mount); 915 916 /* 917 * Check for cross-device rename. 918 */ 919 if (fvp->v_mount != tdvp->v_mount || 920 (tvp && fvp->v_mount != tvp->v_mount)) { 921 error = EXDEV; 922 abortit: 923 if (tdvp == tvp) 924 vrele(tdvp); 925 else 926 vput(tdvp); 927 if (tvp) 928 vput(tvp); 929 vrele(fdvp); 930 vrele(fvp); 931 return (error); 932 } 933 934 /* 935 * If source and dest are the same, do nothing. 936 */ 937 if (tvp == fvp) { 938 error = 0; 939 goto abortit; 940 } 941 942 /* 943 * fvp, fdvp are unlocked, tvp, tdvp are locked. Lock fvp and note 944 * that we have to unlock it to use the abortit target. 945 */ 946 error = vn_lock(fvp, LK_EXCLUSIVE | LK_FAILRECLAIM); 947 if (error) 948 goto abortit; 949 dp = VTODE(fdvp); 950 ip = VTODE(fvp); 951 952 /* 953 * Be sure we are not renaming ".", "..", or an alias of ".". This 954 * leads to a crippled directory tree. It's pretty tough to do a 955 * "ls" or "pwd" with the "." directory entry missing, and "cd .." 956 * doesn't work if the ".." entry is missing. 957 */ 958 if (ip->de_Attributes & ATTR_DIRECTORY) { 959 /* 960 * Avoid ".", "..", and aliases of "." for obvious reasons. 961 */ 962 if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') || 963 dp == ip || 964 (fcnp->cn_flags & CNP_ISDOTDOT) || 965 (tcnp->cn_flags & CNP_ISDOTDOT) || 966 (ip->de_flag & DE_RENAME)) { 967 vn_unlock(fvp); 968 error = EINVAL; 969 goto abortit; 970 } 971 ip->de_flag |= DE_RENAME; 972 doingdirectory++; 973 } 974 975 /* 976 * fvp locked, fdvp unlocked, tvp, tdvp locked. DE_RENAME only 977 * set if doingdirectory. We will get fvp unlocked in fairly 978 * short order. dp and xp must be setup and fvp must be unlocked 979 * for the out and bad targets to work properly. 980 */ 981 dp = VTODE(tdvp); 982 xp = tvp ? VTODE(tvp) : NULL; 983 984 /* 985 * Remember direntry place to use for destination 986 */ 987 to_diroffset = dp->de_fndoffset; 988 to_count = dp->de_fndcnt; 989 990 /* 991 * If ".." must be changed (ie the directory gets a new 992 * parent) then the source directory must not be in the 993 * directory hierarchy above the target, as this would 994 * orphan everything below the source directory. Also 995 * the user must have write permission in the source so 996 * as to be able to change "..". We must repeat the call 997 * to namei, as the parent directory is unlocked by the 998 * call to doscheckpath(). 999 */ 1000 error = VOP_EACCESS(fvp, VWRITE, tcnp->cn_cred); 1001 vn_unlock(fvp); 1002 if (VTODE(fdvp)->de_StartCluster != VTODE(tdvp)->de_StartCluster) 1003 newparent = 1; 1004 1005 /* 1006 * ok. fvp, fdvp unlocked, tvp, tdvp locked. tvp may be NULL. 1007 * DE_RENAME only set if doingdirectory. 1008 */ 1009 if (doingdirectory && newparent) { 1010 if (error) /* write access check above */ 1011 goto bad; 1012 if (xp != NULL) { 1013 vput(tvp); 1014 xp = NULL; 1015 } 1016 /* 1017 * checkpath vput's tdvp (VTOI(dp)) on return no matter what, 1018 * get an extra ref so we wind up with just an unlocked, ref'd 1019 * tdvp. The 'out' target skips tvp and tdvp cleanups (tdvp 1020 * isn't locked so we can't use the out target). 1021 */ 1022 vref(tdvp); 1023 error = doscheckpath(ip, dp); 1024 tcnp->cn_flags |= CNP_PDIRUNLOCK; 1025 if (error) { 1026 vrele(tdvp); 1027 goto out; 1028 } 1029 /* 1030 * relookup no longer messes with the ref count. tdvp must 1031 * be unlocked on entry and on success will be locked on 1032 * return. 1033 */ 1034 error = relookup(tdvp, &tvp, tcnp); 1035 if (error) { 1036 if (tcnp->cn_flags & CNP_PDIRUNLOCK) 1037 vrele(tdvp); 1038 else 1039 vput(tdvp); 1040 goto out; 1041 } 1042 1043 /* 1044 * tvp and tdvp are now locked again. 1045 */ 1046 dp = VTODE(tdvp); 1047 xp = tvp ? VTODE(tvp) : NULL; 1048 } 1049 1050 /* 1051 * tvp and tdvp are now locked again, the 'bad' target can be used 1052 * to clean them up again. Delete an existant target and clean 1053 * up tvp. Set xp to NULL to indicate that tvp has been cleaned up. 1054 */ 1055 if (xp != NULL) { 1056 /* 1057 * Target must be empty if a directory and have no links 1058 * to it. Also, ensure source and target are compatible 1059 * (both directories, or both not directories). 1060 */ 1061 if (xp->de_Attributes & ATTR_DIRECTORY) { 1062 if (!dosdirempty(xp)) { 1063 error = ENOTEMPTY; 1064 goto bad; 1065 } 1066 if (!doingdirectory) { 1067 error = ENOTDIR; 1068 goto bad; 1069 } 1070 } else if (doingdirectory) { 1071 error = EISDIR; 1072 goto bad; 1073 } 1074 error = removede(dp, xp); 1075 if (error) 1076 goto bad; 1077 vput(tvp); 1078 xp = NULL; 1079 tvp = NULL; 1080 } 1081 1082 /* 1083 * Convert the filename in tcnp into a dos filename. We copy this 1084 * into the denode and directory entry for the destination 1085 * file/directory. 1086 */ 1087 error = uniqdosname(VTODE(tdvp), tcnp, toname); 1088 if (error) 1089 goto bad; 1090 1091 /* 1092 * Since from wasn't locked at various places above, we have to do 1093 * a relookup here. If the target and source are the same directory 1094 * we have to unlock the target directory in order to safely relookup 1095 * the source, because relookup expects its directory to be unlocked. 1096 * 1097 * Note that ap->a_fvp is still valid and ref'd. Any cleanup must 1098 * now take that into account. 1099 * 1100 * The tdvp locking issues make this a real mess. 1101 */ 1102 fcnp->cn_flags &= ~CNP_MODMASK; 1103 fcnp->cn_flags |= CNP_LOCKPARENT; 1104 if (newparent == 0) 1105 vn_unlock(tdvp); 1106 error = relookup(fdvp, &fvp, fcnp); 1107 if (error || fvp == NULL) { 1108 /* 1109 * From name has disappeared. Note: fdvp might == tdvp. 1110 * 1111 * DE_RENAME is only set if doingdirectory. 1112 */ 1113 if (doingdirectory) 1114 panic("rename: lost dir entry"); 1115 if (fcnp->cn_flags & CNP_PDIRUNLOCK) 1116 vrele(fdvp); 1117 else 1118 vput(fdvp); 1119 if (newparent == 0) 1120 vrele(tdvp); 1121 else 1122 vput(tdvp); 1123 vrele(ap->a_fvp); 1124 return(0); 1125 } 1126 1127 /* 1128 * No error occured. tdvp, fdvp and fvp are all locked. If 1129 * newparent was 0 be aware that fdvp == tdvp. tvp has been cleaned 1130 * up. ap->a_fvp is still refd. 1131 */ 1132 xp = VTODE(fvp); 1133 zp = VTODE(fdvp); 1134 from_diroffset = zp->de_fndoffset; 1135 1136 /* 1137 * Ensure that the directory entry still exists and has not 1138 * changed till now. If the source is a file the entry may 1139 * have been unlinked or renamed. In either case there is 1140 * no further work to be done. If the source is a directory 1141 * then it cannot have been rmdir'ed or renamed; this is 1142 * prohibited by the DE_RENAME flag. 1143 * 1144 * DE_RENAME is only set if doingdirectory. 1145 */ 1146 if (xp != ip) { 1147 if (doingdirectory) 1148 panic("rename: lost dir entry"); 1149 goto done; 1150 } else { 1151 u_long new_dirclust; 1152 u_long new_diroffset; 1153 1154 /* 1155 * First write a new entry in the destination 1156 * directory and mark the entry in the source directory 1157 * as deleted. Then move the denode to the correct hash 1158 * chain for its new location in the filesystem. And, if 1159 * we moved a directory, then update its .. entry to point 1160 * to the new parent directory. 1161 */ 1162 memcpy(oldname, ip->de_Name, 11); 1163 memcpy(ip->de_Name, toname, 11); /* update denode */ 1164 dp->de_fndoffset = to_diroffset; 1165 dp->de_fndcnt = to_count; 1166 error = createde(ip, dp, NULL, tcnp); 1167 if (error) { 1168 memcpy(ip->de_Name, oldname, 11); 1169 goto done; 1170 } 1171 /* 1172 * If ip is for a directory, then its name should always 1173 * be "." since it is for the directory entry in the 1174 * directory itself (msdosfs_lookup() always translates 1175 * to the "." entry so as to get a unique denode, except 1176 * for the root directory there are different 1177 * complications). However, we just corrupted its name 1178 * to pass the correct name to createde(). Undo this. 1179 */ 1180 if ((ip->de_Attributes & ATTR_DIRECTORY) != 0) 1181 memcpy(ip->de_Name, oldname, 11); 1182 ip->de_refcnt++; 1183 zp->de_fndoffset = from_diroffset; 1184 error = removede(zp, ip); 1185 if (error) { 1186 /* XXX should downgrade to ro here, fs is corrupt */ 1187 goto done; 1188 } 1189 if (!doingdirectory) { 1190 error = pcbmap(dp, de_cluster(pmp, to_diroffset), 1191 NULL, &new_dirclust, NULL); 1192 if (error) { 1193 /* XXX should downgrade to ro here, fs is corrupt */ 1194 goto done; 1195 } 1196 if (new_dirclust == MSDOSFSROOT) 1197 new_diroffset = to_diroffset; 1198 else 1199 new_diroffset = to_diroffset & pmp->pm_crbomask; 1200 msdosfs_reinsert(ip, new_dirclust, new_diroffset); 1201 } 1202 } 1203 1204 /* 1205 * If we moved a directory to a new parent directory, then we must 1206 * fixup the ".." entry in the moved directory. 1207 */ 1208 if (doingdirectory && newparent) { 1209 cn = ip->de_StartCluster; 1210 if (cn == MSDOSFSROOT) { 1211 /* this should never happen */ 1212 panic("msdosfs_rename(): updating .. in root directory?"); 1213 } else { 1214 bn = cntobn(pmp, cn); 1215 } 1216 error = bread(pmp->pm_devvp, de_bn2doff(pmp, bn), 1217 pmp->pm_bpcluster, &bp); 1218 if (error) { 1219 /* XXX should downgrade to ro here, fs is corrupt */ 1220 brelse(bp); 1221 goto done; 1222 } 1223 dotdotp = (struct direntry *)bp->b_data + 1; 1224 pcl = dp->de_StartCluster; 1225 if (FAT32(pmp) && pcl == pmp->pm_rootdirblk) 1226 pcl = MSDOSFSROOT; 1227 putushort(dotdotp->deStartCluster, pcl); 1228 if (FAT32(pmp)) 1229 putushort(dotdotp->deHighClust, pcl >> 16); 1230 if (DOINGASYNC(fvp)) 1231 bdwrite(bp); 1232 else if ((error = bwrite(bp)) != 0) { 1233 /* XXX should downgrade to ro here, fs is corrupt */ 1234 goto done; 1235 } 1236 } 1237 1238 /* 1239 * done case fvp, fdvp, tdvp are locked. ap->a_fvp is refd 1240 */ 1241 done: 1242 if (doingdirectory) 1243 ip->de_flag &= ~DE_RENAME; /* XXX fvp not locked */ 1244 vput(fvp); 1245 if (newparent) 1246 vput(fdvp); 1247 else 1248 vrele(fdvp); 1249 vput(tdvp); 1250 vrele(ap->a_fvp); 1251 return (error); 1252 1253 /* 1254 * 'bad' target: xp governs tvp. tvp and tdvp are locked, fdvp and fvp 1255 * are not locked. ip points to fvp's inode which may have DE_RENAME 1256 * set. 1257 */ 1258 bad: 1259 if (xp) 1260 vput(tvp); 1261 vput(tdvp); 1262 out: 1263 /* 1264 * 'out' target: tvp and tdvp have already been cleaned up. 1265 */ 1266 if (doingdirectory) 1267 ip->de_flag &= ~DE_RENAME; 1268 vrele(fdvp); 1269 vrele(fvp); 1270 return (error); 1271 1272 } 1273 1274 static struct { 1275 struct direntry dot; 1276 struct direntry dotdot; 1277 } dosdirtemplate = { 1278 { ". ", /* the . entry */ 1279 ATTR_DIRECTORY, /* file attribute */ 1280 0, /* reserved */ 1281 0, { 0, 0 }, { 0, 0 }, /* create time & date */ 1282 { 0, 0 }, /* access date */ 1283 { 0, 0 }, /* high bits of start cluster */ 1284 { 210, 4 }, { 210, 4 }, /* modify time & date */ 1285 { 0, 0 }, /* startcluster */ 1286 { 0, 0, 0, 0 } /* filesize */ 1287 }, 1288 { ".. ", /* the .. entry */ 1289 ATTR_DIRECTORY, /* file attribute */ 1290 0, /* reserved */ 1291 0, { 0, 0 }, { 0, 0 }, /* create time & date */ 1292 { 0, 0 }, /* access date */ 1293 { 0, 0 }, /* high bits of start cluster */ 1294 { 210, 4 }, { 210, 4 }, /* modify time & date */ 1295 { 0, 0 }, /* startcluster */ 1296 { 0, 0, 0, 0 } /* filesize */ 1297 } 1298 }; 1299 1300 static int 1301 msdosfs_mkdir(struct vop_old_mkdir_args *ap) 1302 { 1303 struct componentname *cnp = ap->a_cnp; 1304 struct denode *dep; 1305 struct denode *pdep = VTODE(ap->a_dvp); 1306 struct direntry *denp; 1307 struct msdosfsmount *pmp = pdep->de_pmp; 1308 struct buf *bp; 1309 u_long newcluster, pcl; 1310 int bn; 1311 int error; 1312 struct denode ndirent; 1313 struct timespec ts; 1314 1315 /* 1316 * If this is the root directory and there is no space left we 1317 * can't do anything. This is because the root directory can not 1318 * change size. 1319 */ 1320 if (pdep->de_StartCluster == MSDOSFSROOT 1321 && pdep->de_fndoffset >= pdep->de_FileSize) { 1322 error = ENOSPC; 1323 goto bad2; 1324 } 1325 1326 /* 1327 * Allocate a cluster to hold the about to be created directory. 1328 */ 1329 error = clusteralloc(pmp, 0, 1, CLUST_EOFE, &newcluster, NULL); 1330 if (error) 1331 goto bad2; 1332 1333 memset(&ndirent, 0, sizeof(ndirent)); 1334 ndirent.de_pmp = pmp; 1335 ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE; 1336 vfs_timestamp(&ts); 1337 DETIMES(&ndirent, &ts, &ts, &ts); 1338 1339 /* 1340 * Now fill the cluster with the "." and ".." entries. And write 1341 * the cluster to disk. This way it is there for the parent 1342 * directory to be pointing at if there were a crash. 1343 */ 1344 bn = cntobn(pmp, newcluster); 1345 /* always succeeds */ 1346 bp = getblk(pmp->pm_devvp, de_bn2doff(pmp, bn), 1347 pmp->pm_bpcluster, 0, 0); 1348 memset(bp->b_data, 0, pmp->pm_bpcluster); 1349 memcpy(bp->b_data, &dosdirtemplate, sizeof(dosdirtemplate)); 1350 denp = (struct direntry *)bp->b_data; 1351 putushort(denp[0].deStartCluster, newcluster); 1352 putushort(denp[0].deCDate, ndirent.de_CDate); 1353 putushort(denp[0].deCTime, ndirent.de_CTime); 1354 denp[0].deCHundredth = ndirent.de_CHun; 1355 putushort(denp[0].deADate, ndirent.de_ADate); 1356 putushort(denp[0].deMDate, ndirent.de_MDate); 1357 putushort(denp[0].deMTime, ndirent.de_MTime); 1358 pcl = pdep->de_StartCluster; 1359 /* 1360 * Although the root directory has a non-magic starting cluster 1361 * number for FAT32, chkdsk and fsck_msdosfs still require 1362 * references to it in dotdot entries to be magic. 1363 */ 1364 if (FAT32(pmp) && pcl == pmp->pm_rootdirblk) 1365 pcl = MSDOSFSROOT; 1366 putushort(denp[1].deStartCluster, pcl); 1367 putushort(denp[1].deCDate, ndirent.de_CDate); 1368 putushort(denp[1].deCTime, ndirent.de_CTime); 1369 denp[1].deCHundredth = ndirent.de_CHun; 1370 putushort(denp[1].deADate, ndirent.de_ADate); 1371 putushort(denp[1].deMDate, ndirent.de_MDate); 1372 putushort(denp[1].deMTime, ndirent.de_MTime); 1373 if (FAT32(pmp)) { 1374 putushort(denp[0].deHighClust, newcluster >> 16); 1375 putushort(denp[1].deHighClust, pcl >> 16); 1376 } 1377 1378 if (DOINGASYNC(ap->a_dvp)) 1379 bdwrite(bp); 1380 else if ((error = bwrite(bp)) != 0) 1381 goto bad; 1382 1383 /* 1384 * Now build up a directory entry pointing to the newly allocated 1385 * cluster. This will be written to an empty slot in the parent 1386 * directory. 1387 */ 1388 error = uniqdosname(pdep, cnp, ndirent.de_Name); 1389 if (error) 1390 goto bad; 1391 1392 ndirent.de_Attributes = ATTR_DIRECTORY; 1393 ndirent.de_LowerCase = 0; 1394 ndirent.de_StartCluster = newcluster; 1395 ndirent.de_FileSize = 0; 1396 ndirent.de_dev = pdep->de_dev; 1397 ndirent.de_devvp = pdep->de_devvp; 1398 error = createde(&ndirent, pdep, &dep, cnp); 1399 if (error) 1400 goto bad; 1401 *ap->a_vpp = DETOV(dep); 1402 return (0); 1403 1404 bad: 1405 clusterfree(pmp, newcluster, NULL); 1406 bad2: 1407 return (error); 1408 } 1409 1410 static int 1411 msdosfs_rmdir(struct vop_old_rmdir_args *ap) 1412 { 1413 struct vnode *vp = ap->a_vp; 1414 struct vnode *dvp = ap->a_dvp; 1415 struct denode *ip, *dp; 1416 int error; 1417 1418 ip = VTODE(vp); 1419 dp = VTODE(dvp); 1420 1421 /* 1422 * Verify the directory is empty (and valid). 1423 * (Rmdir ".." won't be valid since 1424 * ".." will contain a reference to 1425 * the current directory and thus be 1426 * non-empty.) 1427 */ 1428 error = 0; 1429 if (!dosdirempty(ip) || ip->de_flag & DE_RENAME) { 1430 error = ENOTEMPTY; 1431 goto out; 1432 } 1433 /* 1434 * Delete the entry from the directory. For dos filesystems this 1435 * gets rid of the directory entry on disk, the in memory copy 1436 * still exists but the de_refcnt is <= 0. This prevents it from 1437 * being found by deget(). When the vput() on dep is done we give 1438 * up access and eventually msdosfs_reclaim() will be called which 1439 * will remove it from the denode cache. 1440 */ 1441 error = removede(dp, ip); 1442 if (error) 1443 goto out; 1444 /* 1445 * Truncate the directory that is being deleted. 1446 */ 1447 error = detrunc(ip, (u_long)0, IO_SYNC); 1448 out: 1449 return (error); 1450 } 1451 1452 /* 1453 * DOS filesystems don't know what symlinks are. 1454 */ 1455 static int 1456 msdosfs_symlink(struct vop_old_symlink_args *ap) 1457 { 1458 return (EOPNOTSUPP); 1459 } 1460 1461 static int 1462 msdosfs_readdir(struct vop_readdir_args *ap) 1463 { 1464 struct mbnambuf nb; 1465 int error = 0; 1466 int diff; 1467 long n; 1468 int blsize; 1469 long on; 1470 u_long cn; 1471 u_long dirsperblk; 1472 long bias = 0; 1473 daddr_t bn, lbn; 1474 struct buf *bp = NULL; 1475 struct denode *dep; 1476 struct msdosfsmount *pmp; 1477 struct direntry *dentp; 1478 struct dirent dirbuf; 1479 struct uio *uio = ap->a_uio; 1480 off_t *cookies = NULL; 1481 int ncookies = 0; 1482 off_t offset, off; 1483 int chksum = -1; 1484 1485 error = vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY | LK_FAILRECLAIM); 1486 if (error) 1487 return (error); 1488 1489 dep = VTODE(ap->a_vp); 1490 pmp = dep->de_pmp; 1491 1492 mprintf("msdosfs_readdir(): vp %p, uio %p, cred %p, eofflagp %p\n", 1493 ap->a_vp, uio, ap->a_cred, ap->a_eofflag); 1494 1495 /* 1496 * msdosfs_readdir() won't operate properly on regular files since 1497 * it does i/o only with the filesystem vnode, and hence can 1498 * retrieve the wrong block from the buffer cache for a plain file. 1499 * So, fail attempts to readdir() on a plain file. 1500 */ 1501 if ((dep->de_Attributes & ATTR_DIRECTORY) == 0) { 1502 error = ENOTDIR; 1503 goto done; 1504 } 1505 1506 /* 1507 * To be safe, initialize dirbuf 1508 */ 1509 memset(dirbuf.d_name, 0, sizeof(dirbuf.d_name)); 1510 1511 /* 1512 * If the user buffer is smaller than the size of one dos directory 1513 * entry or the file offset is not a multiple of the size of a 1514 * directory entry, then we fail the read. 1515 */ 1516 off = offset = uio->uio_offset; 1517 if (uio->uio_resid < sizeof(struct direntry) || 1518 (offset & (sizeof(struct direntry) - 1))) { 1519 error = EINVAL; 1520 goto done; 1521 } 1522 1523 if (ap->a_ncookies) { 1524 ncookies = uio->uio_resid / 16 + 1; 1525 if (ncookies > 1024) 1526 ncookies = 1024; 1527 cookies = kmalloc(ncookies * sizeof(off_t), M_TEMP, M_WAITOK); 1528 *ap->a_cookies = cookies; 1529 *ap->a_ncookies = ncookies; 1530 } 1531 1532 dirsperblk = pmp->pm_BytesPerSec / sizeof(struct direntry); 1533 1534 #define d_fileno d_ino 1535 /* 1536 * If they are reading from the root directory then, we simulate 1537 * the . and .. entries since these don't exist in the root 1538 * directory. We also set the offset bias to make up for having to 1539 * simulate these entries. By this I mean that at file offset 64 we 1540 * read the first entry in the root directory that lives on disk. 1541 */ 1542 if (dep->de_StartCluster == MSDOSFSROOT 1543 || (FAT32(pmp) && dep->de_StartCluster == pmp->pm_rootdirblk)) { 1544 #if 0 1545 printf("msdosfs_readdir(): going after . or .. in root dir, offset %d\n", 1546 offset); 1547 #endif 1548 bias = 2 * sizeof(struct direntry); 1549 if (offset < bias) { 1550 for (n = (int)offset / sizeof(struct direntry); 1551 n < 2; n++) { 1552 dirbuf.d_fileno = FAT32(pmp) ? 1553 (uint64_t)cntobn(pmp, pmp->pm_rootdirblk) * 1554 dirsperblk : 1; 1555 dirbuf.d_type = DT_DIR; 1556 switch (n) { 1557 case 0: 1558 dirbuf.d_namlen = 1; 1559 strcpy(dirbuf.d_name, "."); 1560 break; 1561 case 1: 1562 dirbuf.d_namlen = 2; 1563 strcpy(dirbuf.d_name, ".."); 1564 break; 1565 } 1566 if (vop_write_dirent(&error, uio, 1567 dirbuf.d_fileno, dirbuf.d_type, 1568 dirbuf.d_namlen, dirbuf.d_name)) 1569 goto out; 1570 if (error) 1571 goto out; 1572 offset += sizeof(struct direntry); 1573 off = offset; 1574 if (cookies) { 1575 *cookies++ = offset; 1576 if (--ncookies <= 0) 1577 goto out; 1578 } 1579 } 1580 } 1581 } 1582 1583 mbnambuf_init(&nb); 1584 off = offset; 1585 1586 while (uio->uio_resid > 0) { 1587 lbn = de_cluster(pmp, offset - bias); 1588 on = (offset - bias) & pmp->pm_crbomask; 1589 n = szmin(pmp->pm_bpcluster - on, uio->uio_resid); 1590 diff = dep->de_FileSize - (offset - bias); 1591 if (diff <= 0) 1592 break; 1593 n = min(n, diff); 1594 error = pcbmap(dep, lbn, &bn, &cn, &blsize); 1595 if (error) 1596 break; 1597 error = bread(pmp->pm_devvp, de_bn2doff(pmp, bn), blsize, &bp); 1598 if (error) { 1599 brelse(bp); 1600 goto done; 1601 } 1602 n = min(n, blsize - bp->b_resid); 1603 if (n == 0) { 1604 brelse(bp); 1605 error = EIO; 1606 goto done; 1607 } 1608 1609 /* 1610 * Convert from dos directory entries to fs-independent 1611 * directory entries. 1612 */ 1613 for (dentp = (struct direntry *)(bp->b_data + on); 1614 (char *)dentp < bp->b_data + on + n; 1615 dentp++, offset += sizeof(struct direntry)) { 1616 #if 0 1617 printf("rd: dentp %08x prev %08x crnt %08x deName %02x attr %02x\n", 1618 dentp, prev, crnt, dentp->deName[0], dentp->deAttributes); 1619 #endif 1620 /* 1621 * If this is an unused entry, we can stop. 1622 */ 1623 if (dentp->deName[0] == SLOT_EMPTY) { 1624 brelse(bp); 1625 goto out; 1626 } 1627 /* 1628 * Skip deleted entries. 1629 */ 1630 if (dentp->deName[0] == SLOT_DELETED) { 1631 chksum = -1; 1632 mbnambuf_init(&nb); 1633 continue; 1634 } 1635 1636 /* 1637 * Handle Win95 long directory entries 1638 */ 1639 if (dentp->deAttributes == ATTR_WIN95) { 1640 if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME) 1641 continue; 1642 chksum = win2unixfn(&nb, 1643 (struct winentry *)dentp, chksum, pmp); 1644 continue; 1645 } 1646 1647 /* 1648 * Skip volume labels 1649 */ 1650 if (dentp->deAttributes & ATTR_VOLUME) { 1651 chksum = -1; 1652 mbnambuf_init(&nb); 1653 continue; 1654 } 1655 /* 1656 * This computation of d_fileno must match 1657 * the computation of va_fileid in 1658 * msdosfs_getattr. 1659 */ 1660 if (dentp->deAttributes & ATTR_DIRECTORY) { 1661 cn = getushort(dentp->deStartCluster); 1662 if (FAT32(pmp)) { 1663 cn |= getushort(dentp->deHighClust) << 1664 16; 1665 if (cn == MSDOSFSROOT) 1666 cn = pmp->pm_rootdirblk; 1667 } 1668 if (cn == MSDOSFSROOT && !FAT32(pmp)) 1669 dirbuf.d_fileno = 1; 1670 else 1671 dirbuf.d_fileno = cntobn(pmp, cn) * 1672 dirsperblk; 1673 dirbuf.d_type = DT_DIR; 1674 } else { 1675 dirbuf.d_fileno = (uoff_t)offset / 1676 sizeof(struct direntry); 1677 dirbuf.d_type = DT_REG; 1678 } 1679 1680 if (chksum != winChksum(dentp->deName)) { 1681 dirbuf.d_namlen = dos2unixfn(dentp->deName, 1682 (u_char *)dirbuf.d_name, 1683 dentp->deLowerCase | 1684 ((pmp->pm_flags & MSDOSFSMNT_SHORTNAME) ? 1685 (LCASE_BASE | LCASE_EXT) : 0), 1686 pmp); 1687 mbnambuf_init(&nb); 1688 } else 1689 mbnambuf_flush(&nb, &dirbuf); 1690 chksum = -1; 1691 if (vop_write_dirent(&error, uio, dirbuf.d_fileno, 1692 dirbuf.d_type, dirbuf.d_namlen, dirbuf.d_name)) { 1693 brelse(bp); 1694 goto out; 1695 } 1696 if (error) { 1697 brelse(bp); 1698 goto out; 1699 } 1700 1701 if (cookies) { 1702 *cookies++ = offset + sizeof(struct direntry); 1703 if (--ncookies <= 0) { 1704 brelse(bp); 1705 goto out; 1706 } 1707 } 1708 off = offset + sizeof(struct direntry); 1709 } 1710 brelse(bp); 1711 } 1712 out: 1713 /* Subtract unused cookies */ 1714 if (ap->a_ncookies) 1715 *ap->a_ncookies -= ncookies; 1716 1717 uio->uio_offset = off; 1718 1719 /* 1720 * Set the eofflag (NFS uses it) 1721 */ 1722 if (ap->a_eofflag) { 1723 if (dep->de_FileSize - (offset - bias) <= 0) 1724 *ap->a_eofflag = 1; 1725 else 1726 *ap->a_eofflag = 0; 1727 } 1728 done: 1729 vn_unlock(ap->a_vp); 1730 return (error); 1731 } 1732 1733 /*- 1734 * a_vp - pointer to the file's vnode 1735 * a_runp - where to return the "run past" a_bn. This is the count of logical 1736 * blocks whose physical blocks (together with a_bn's physical block) 1737 * are contiguous. 1738 * a_runb - where to return the "run before" a_bn. 1739 */ 1740 static int 1741 msdosfs_bmap(struct vop_bmap_args *ap) 1742 { 1743 struct fatcache savefc; 1744 struct denode *dep; 1745 struct mount *mp; 1746 struct msdosfsmount *pmp; 1747 struct vnode *vp; 1748 daddr_t dbn, runbn; 1749 u_long cn; 1750 int bnpercn, error, maxio, maxrun, run; 1751 1752 vp = ap->a_vp; 1753 dep = VTODE(vp); 1754 pmp = dep->de_pmp; 1755 1756 if (ap->a_doffsetp == NULL) 1757 return (0); 1758 if (ap->a_runp != NULL) 1759 *ap->a_runp = 0; 1760 if (ap->a_runb != NULL) 1761 *ap->a_runb = 0; 1762 1763 KKASSERT(((int)ap->a_loffset & ((1 << pmp->pm_cnshift) - 1)) == 0); 1764 error = pcbmap(dep, de_cluster(pmp, ap->a_loffset), &dbn, NULL, NULL); 1765 if (error || dbn == (daddr_t)-1) 1766 *ap->a_doffsetp = NOOFFSET; 1767 else 1768 *ap->a_doffsetp = de_bn2doff(pmp, dbn); 1769 if (error != 0 || dbn == (daddr_t)-1 || 1770 (ap->a_runp == NULL && ap->a_runb == NULL)) 1771 return (error); 1772 1773 /* 1774 * Prepare to back out updates of the fatchain cache after the one 1775 * for the first block done by pcbmap() above. Without the backout, 1776 * then whenever the caller doesn't do i/o to all of the blocks that 1777 * we find, the single useful cache entry would be too far in advance 1778 * of the actual i/o to work for the next sequential i/o. Then the 1779 * FAT would be searched from the beginning. With the backout, the 1780 * FAT is searched starting at most a few blocks early. This wastes 1781 * much less time. Time is also wasted finding more blocks than the 1782 * caller will do i/o to. This is necessary because the runlength 1783 * parameters are output-only. 1784 */ 1785 savefc = dep->de_fc[FC_LASTMAP]; 1786 1787 cn = de_cluster(pmp, ap->a_loffset); 1788 mp = vp->v_mount; 1789 maxio = mp->mnt_iosize_max / mp->mnt_stat.f_iosize; 1790 bnpercn = de_cn2bn(pmp, 1); 1791 if (ap->a_runp != NULL) { 1792 maxrun = ulmin(maxio - 1, pmp->pm_maxcluster - cn); 1793 for (run = 1; run <= maxrun; run++) { 1794 if (pcbmap(dep, cn + run, &runbn, NULL, NULL) != 0 || 1795 runbn != dbn + run * bnpercn) 1796 break; 1797 } 1798 *ap->a_runp = run - 1; 1799 } 1800 if (ap->a_runb != NULL) { 1801 maxrun = ulmin(maxio - 1, cn); 1802 for (run = 1; run < maxrun; run++) { 1803 if (pcbmap(dep, cn - run, &runbn, NULL, NULL) != 0 || 1804 runbn != dbn - run * bnpercn) 1805 break; 1806 } 1807 *ap->a_runb = run - 1; 1808 } 1809 dep->de_fc[FC_LASTMAP] = savefc; 1810 1811 return (0); 1812 } 1813 1814 static int 1815 msdosfs_strategy(struct vop_strategy_args *ap) 1816 { 1817 struct bio *bio = ap->a_bio; 1818 struct bio *nbio; 1819 struct buf *bp = bio->bio_buf; 1820 struct vnode *vp = ap->a_vp; 1821 struct denode *dep = VTODE(vp); 1822 struct msdosfsmount *pmp = dep->de_pmp; 1823 int error = 0; 1824 daddr_t dblkno; 1825 1826 if (vp->v_type == VBLK || vp->v_type == VCHR) 1827 panic("msdosfs_strategy: spec"); 1828 /* 1829 * If we don't already know the filesystem relative block number 1830 * then get it using pcbmap(). If pcbmap() returns the block 1831 * number as -1 then we've got a hole in the file. DOS filesystems 1832 * don't allow files with holes, so we shouldn't ever see this. 1833 */ 1834 nbio = push_bio(bio); 1835 if (nbio->bio_offset == NOOFFSET) { 1836 error = pcbmap(dep, de_cluster(pmp, bio->bio_offset), 1837 &dblkno, NULL, NULL); 1838 if (error) { 1839 bp->b_error = error; 1840 bp->b_flags |= B_ERROR; 1841 /* I/O was never started on nbio, must biodone(bio) */ 1842 biodone(bio); 1843 return (error); 1844 } 1845 if (dblkno == (daddr_t)-1) { 1846 nbio->bio_offset = NOOFFSET; 1847 vfs_bio_clrbuf(bp); 1848 } else { 1849 nbio->bio_offset = de_bn2doff(pmp, dblkno); 1850 } 1851 } 1852 if (nbio->bio_offset == NOOFFSET) { 1853 /* I/O was never started on nbio, must biodone(bio) */ 1854 biodone(bio); 1855 return (0); 1856 } 1857 /* 1858 * Read/write the block from/to the disk that contains the desired 1859 * file block. 1860 */ 1861 vn_strategy(dep->de_devvp, nbio); 1862 return (0); 1863 } 1864 1865 static int 1866 msdosfs_print(struct vop_print_args *ap) 1867 { 1868 struct denode *dep = VTODE(ap->a_vp); 1869 1870 kprintf("tag VT_MSDOSFS, startcluster %lu, dircluster %lu, " 1871 "diroffset %lu, dev %d, %d", 1872 dep->de_StartCluster, dep->de_dirclust, dep->de_diroffset, 1873 major(dep->de_dev), minor(dep->de_dev)); 1874 lockmgr_printinfo(&ap->a_vp->v_lock); 1875 return (0); 1876 } 1877 1878 static int 1879 msdosfs_pathconf(struct vop_pathconf_args *ap) 1880 { 1881 struct msdosfsmount *pmp = VTODE(ap->a_vp)->de_pmp; 1882 1883 switch (ap->a_name) { 1884 case _PC_FILESIZEBITS: 1885 *ap->a_retval = FAT12(pmp) ? 32 : 33; 1886 return (0); 1887 case _PC_LINK_MAX: 1888 *ap->a_retval = 1; 1889 return (0); 1890 case _PC_NAME_MAX: 1891 *ap->a_retval = 1892 pmp->pm_flags & MSDOSFSMNT_LONGNAME ? WIN_MAXLEN : 12; 1893 return (0); 1894 case _PC_CHOWN_RESTRICTED: 1895 *ap->a_retval = 1; 1896 return (0); 1897 case _PC_NO_TRUNC: 1898 *ap->a_retval = 0; 1899 return (0); 1900 default: 1901 return (vop_stdpathconf(ap)); 1902 } 1903 /* NOTREACHED */ 1904 } 1905 1906 /* Global vfs data structures for msdosfs */ 1907 struct vop_ops msdosfs_vnode_vops = { 1908 .vop_default = vop_defaultop, 1909 .vop_access = msdosfs_access, 1910 .vop_bmap = msdosfs_bmap, 1911 .vop_getpages = vop_stdgetpages, 1912 .vop_putpages = vop_stdputpages, 1913 .vop_open = msdosfs_open, 1914 .vop_close = msdosfs_close, 1915 .vop_old_create = msdosfs_create, 1916 .vop_fsync = msdosfs_fsync, 1917 .vop_getattr = msdosfs_getattr, 1918 .vop_inactive = msdosfs_inactive, 1919 .vop_old_link = msdosfs_link, 1920 .vop_old_lookup = msdosfs_lookup, 1921 .vop_old_mkdir = msdosfs_mkdir, 1922 .vop_old_mknod = msdosfs_mknod, 1923 .vop_pathconf = msdosfs_pathconf, 1924 .vop_print = msdosfs_print, 1925 .vop_read = msdosfs_read, 1926 .vop_readdir = msdosfs_readdir, 1927 .vop_reclaim = msdosfs_reclaim, 1928 .vop_old_remove = msdosfs_remove, 1929 .vop_old_rename = msdosfs_rename, 1930 .vop_old_rmdir = msdosfs_rmdir, 1931 .vop_setattr = msdosfs_setattr, 1932 .vop_strategy = msdosfs_strategy, 1933 .vop_old_symlink = msdosfs_symlink, 1934 .vop_write = msdosfs_write, 1935 }; 1936